图标在QTreeWidgetItem中的位置

Ton*_*nyK 6 qt

QTreeWidget有一个专栏.它的项目有一个复选框,一个图标和文本.如果用户在项目中单击,我想知道是否单击了该图标.如何找到图标的位置和大小QTreeWidgetItem

更新以添加:这是我的最终解决方案的代码,如webclectic所要求的.

首先,我进行了分类,QItemDelegate以便我可以访问每个部分的坐标QTreeWidgetItem(复选框,图标和文本).这是头文件:

#include <QItemDelegate>

class MyItemDelegate : public QItemDelegate
  {
  Q_OBJECT

public:
  explicit MyItemDelegate (MyTreeWidget *parent)
    : QItemDelegate (parent), ParentView (parent) { }
  ~MyItemDelegate() { }

  void GetRects (const QModelIndex &index, QRect& CheckBox, QRect& Icon, QRect& Text) const ;

private:
  MyTreeWidget* ParentView ;
  } ;
Run Code Online (Sandbox Code Playgroud)

这是源文件:

void MyItemDelegate::GetRects (const QModelIndex &index, QRect& CheckBox, QRect& Icon, QRect& Text) const
  {
  QStyleOptionViewItem option = ParentView -> viewOptions() ;
  CheckBox = rect (option, index, Qt::CheckStateRole) ;
  Icon = rect (option, index, Qt::DecorationRole) ;
  Text = rect (option, index, Qt::DisplayRole) ;

  doLayout (option, &CheckBox, &Icon, &Text, true) ;

  QRect VisualRect = ParentView -> visualRect (index) ;
  CheckBox.translate (VisualRect.topLeft()) ;
  Icon.translate (VisualRect.topLeft()) ;
  Text.translate (VisualRect.topLeft()) ;
  }
Run Code Online (Sandbox Code Playgroud)

然后我添加了一个MyItemDelegate*成员MyTreeWidget,并将其设置为项目视图的委托.在标题中:

class MyTreeWidget : public QTreeWidget
  {
  ...
  MyItemDelegate* Delegate ;
  ...
  } ;
Run Code Online (Sandbox Code Playgroud)

在来源:

MyTreeWidget::MyTreeWidget (QObject* parent)
  {
  ...
  Delegate = new MyItemDelegate (this) ;
  setItemDelegate (ItemDelegate) ;
  }
Run Code Online (Sandbox Code Playgroud)

现在,获取a的每个部分的坐标QTreeWidgetItem:

  QTreeWidgetItem* item ;
  ...
  QModelIndex ModelIndex = indexFromItem (item) ;
  QRect CheckBoxRect, IconRect, TextRect ;
  ItemDelegate -> GetRects (ModelIndex, &CheckBoxRect, &IconRect, &TextRect) ;
Run Code Online (Sandbox Code Playgroud)

pne*_*zis 4

不幸的是,没有简单的方法可以实现您想要的。问题是QTreeWidget负责绘制其项目,因此项目本身没有有关其元素在视图中的位置的信息。

首先,您必须子类化QTreeWidget并重新实现mousePressEvent(或者mouseReleaseEvent如果您愿意的话)。在事件内部,您应该计算图标的位置并进行相应的处理。

示例代码(但未经测试)如下:

void mousePressEvent(QMouseEvent *event)
{
   QModelIndex clickedIndex = indexAt(event->pos());
   // make sure the event was on a valid item
   if (clickedIndex.isValid() == false)
      return;

   // Get the tree widget's x position
   int treeX = header()->sectionViewportPosition(0);

   // Get the x coordinate of the root item. It is required in order to calculate
   // the identation of the item
   int rootX = visualRect(rootIndex()).x();

   // Get the rectangle of the viewport occupied by the pressed item
   QRect vrect = visualRect(clickedIndex);

   // Now we can easily calculate the x coordinate of the item
   int itemX = treeX + vrect.x() - rootX; 

   // The item is a checkbox, then an icon and finally the text. 

   // 1. Get the rect surrounding the checkbox
   QRect checkboxRect = QRect(itemX, 
                              vrect.y(), 
                              style()->pixelMetric(QStyle::PM_IndicatorWidth),
                              vrect.height()); 

   // 2. Get the rect surrounding the icon
   QRect iconRect = QRect(itemX + checkboxRect.width(),
                          vrect.y(),
                          iconSize().width(),
                          vrect.height());

   // 3. Finally get the rect surrounding the text
   QRect textRect = QRect(itemX + checkboxRect.width() + iconRect.width(),
                          vrect.y(),
                          vrect.width() - checkboxRect.width() - iconRect.width(),
                          vrect.height());       

   // Now check where the press event took place and handle it correspondingly

   if(checkboxRect.contains(event->pos())) 
   {
       qDebug() << "Checkbox pressed";
       QTreeWidget::mousePressEvent(event);
       return;
   } 
   else if (iconRect.contains(event->pos()))
   {
       qDebug() << "Icon pressed";
       QTreeWidget::mousePressEvent(event);
       return;
   }
   else
   {
       qDebug() << "Text pressed";
       QTreeWidget::mousePressEvent(event);
       return; 
   }
}
Run Code Online (Sandbox Code Playgroud)

我再说一遍,代码未经测试,但您知道如何实现您想要的。