2011-11-25 9 views
5

Moja QTreeWidget ma pojedynczą kolumnę. Jego elementy mają pole wyboru, ikonę i tekst. Jeśli użytkownik kliknie w element, chcę się dowiedzieć, czy kliknięto ikonę. Jak mogę znaleźć położenie i rozmiar ikony w QTreeWidgetItem?Pozycja ikony w QTreeWidgetItem

Zaktualizowano, aby dodać: Oto kod dla mojego ewentualnego rozwiązania, zgodnie z żądaniem użytkownika webclectic.

Po pierwsze, podklasyfikowałem QItemDelegate, aby uzyskać dostęp do współrzędnych każdej części QTreeWidgetItem (pole wyboru, ikona i tekst). Oto nagłówek pliku:

#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 ; 
    } ; 

I tu jest plik źródłowy:

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()) ; 
    } 

Potem dodał członek MyItemDelegate* do MyTreeWidget i ustawić go jako delegata widoku elementu. W nagłówku:

class MyTreeWidget : public QTreeWidget 
    { 
    ... 
    MyItemDelegate* Delegate ; 
    ... 
    } ; 

w źródle:

MyTreeWidget::MyTreeWidget (QObject* parent) 
    { 
    ... 
    Delegate = new MyItemDelegate (this) ; 
    setItemDelegate (ItemDelegate) ; 
    } 

Teraz, aby uzyskać współrzędne każdej części QTreeWidgetItem:

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

Odpowiedz

2

Niestety nie istnieje prosty sposób na osiągnięcie czego chcesz. Problem polega na tym, że QTreeWidget jest odpowiedzialny za malowanie swoich przedmiotów, więc sam przedmiot nie ma informacji o położeniu jego elementów w widoku.

Przede wszystkim należy podklasę QTreeWidget i ponownie wprowadzić mousePressEvent (lub mouseReleaseEvent, jeśli wolisz). Wewnątrz wydarzenia należy obliczyć położenie ikony i odpowiednio ją obsłużyć.

Przykładowy kod (ale niesprawdzone) następująco:

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; 
    } 
} 

powtarzam, że kod jest niesprawdzone ale masz pojęcia o tym, jak osiągnąć to, co chcesz.

+0

Próbowałem tego, a to z 'PM_IndicatorWidth' działa dobrze. Dziękuję za to! Ponadto, 'iconSize()' zwraca (-1, -1), ale jeśli zadzwonię 'setIconSize()' najpierw działa. Wygląda to koliście, ale w rzeczywistości rozwiązał mój problem z ikonami, które są mniejsze niż chciałem. – TonyK

+0

Dobrze wiedzieć .. :) – pnezis

+0

Po kilku testach odkryłem, że to rozwiązanie również nie działa - ignoruje marginesy wokół pola wyboru i ikony. Aby zrobić to poprawnie, musiałem podklasy QItemDelegate i dostarczyć wersję sizeHint, która zwraca trzy części (pole wyboru, ikona, tekst) oddzielnie. Ale postawiłeś mnie na właściwej drodze. – TonyK