PDA

View Full Version : Position of widgets within QTreeWidget items



dagvegar
29th October 2012, 08:06
Hi folks,

I have uploaded a minimal example (TreeItemTest.zip) to point at my specific issue.

The example program has two items, where one is child of the other. A QPushButton is shown on every QTreeWidgetItem. In addition, when having children, a QPushButton for expanding the tree is shown at the right.

The two items are shown running the same code (using delegate), but they look different because the expand button is hidden when not having children.

When clicking the "Left" button, it turns red (just to illustrate that its hit). To check if it is hit, the mouse click is calculated to check if the cursor is at the target.

And here is the problem, try clicking the "Left" buttons, on the one above at the left side of the "Left" button and then click at the below button at the right side of it. (Thus when clicking the buttons, the clicks are not aligned vertically.) As seen, you will sometimes not get a hit (the button does not change color).
It seems like the geometry of the button clicked is the geometry of the other button (and visa versa).

The calculation of the button positions is done in the editorEvent. I have also tried to put this code in the mousePressEvent at the QTreeWidget level without success.

Could anyone point at what is wrong and show a way to do this correctly. A link to the exact same issue would do, thus I haven't found one yet.

Big thanks!

norobro
31st October 2012, 14:16
Try the following change:
bool TestTreeWidgetItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
. . .
. . .
if(rectPushLeft.contains(mouse_event->pos()))
{
qDebug() << item->m_strDescription << "rectPushLeft is clicked" << rectPushLeft;
item->UpdatePushLeft();
//return true; move this statement
}
return true; // to here
}
else
{
return false;
}
return false;
}

dagvegar
2nd November 2012, 06:37
Thank you for your answer and that you have looked into my issue, norobro.

I see that your suggestion is to change the return value when leaving the editorEvent. true means that the editorEvent has handled the event, false means it has not. Your suggestion may be correct, but unfortunately it does not help on this issue.

Please compile&run the test program and click the mouse several times switching between clicking the positions a) then b) (see attached WhereToClick.png 8387) and notice that the buttons not always change color (it is supposed to change on the first click). On the other hand, if clicked on positions where the "Left" buttons are aligned vertically, they will always change color because the calculation of the clicked position in respect of the position of the pushbutton matches.

Thanks again :)

norobro
3rd November 2012, 18:30
The problem is, with regard to m_pPushExpand being visible or not, that the geometry of m_pPushLeft is not updated until the editor widget is shown. So in your delegate's editorEvent() function, item->GetPushLeftGeometry() returns the previous position of the button.

I hope that makes sense.

As a test, try the following:
void TestTreeWidgetItem::RefreshWidget(TestTreeWidgetIt emEditor *itemeditor, TestTreeWidget::ItemType type)
{
if(type == TestTreeWidget::ITTypeA)
{
itemeditor->m_plabelDescription->setText(m_strDescription);
itemeditor->m_pPushExpand->setVisible((childCount() > 0));

QRect rect = itemeditor->m_pPushLeft->geometry();
if(childCount()>0) rect.setX(338);
else rect.setX(380);
itemeditor->m_pPushLeft->setGeometry(rect);

itemeditor->m_pPushLeft->setStyleSheet("background: "+ m_strColor +";");
}
}


Hard coding the position of the button won't work unless you set your main widget to a fixed size.