QTreeWidget not expanding/collapsing when clicking twice on the arrow
-
Hello!
I'm running into a strange issue with a QTreeWidget.
Here's what's happening:
- First, I click on the chevron icon to expand the group. This works fine.
- I wait just a moment without moving the mouse, then click on it again. It does not close the group.
- I click on it a third time. This closes the group.
And here are a few clues that might help:
Waiting longer helps:
- First, I click on the chevron icon to expand the group. This works fine.
- I wait a few seconds without moving the mouse, then click on it again. The group closes as expected.
Moving the mouse away and back also helps:
- First, I click on the chevron icon to expand the group. This works fine.
- I quickly move the mouse away from the chevron icon, then back over it.
- I click on the chevron icon, and the group closes as expected.
I tried turning off the QTreeView's expandsOnDoubleClick property, but this made no difference.
Here's the code that populates the QTreeWidget:
MainWindow::MainWindow(QWidget *parent, ModuleTypesManager *module_types_manager) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); // Add the module to the QGraphicsScene scene = new QGraphicsScene(this); // Store the module_types_manager for later use this->module_types_manager = module_types_manager; // Get the module type groups QVector<QString> groups = module_types_manager->getGroups(); // // Populate the module selector // // First, iterate over the groups for (int i = 0; i < groups.size(); i++) { // Create a new QTreeWidgetItem for the group QTreeWidgetItem *group_item = new QTreeWidgetItem(); group_item->setText(0, groups[i]); // Group items should not highlight when you click on them. // Instead, they should expand or collapse. group_item->setFlags(group_item->flags() & ~Qt::ItemIsSelectable); // Add the group to the module selector ui->ModuleSelector->addTopLevelItem(group_item); // Get the module types for the group QVector<ModuleTypes *> types = module_types_manager->getTypes(groups[i]); // Iterate over the module types for (int j = 0; j < types.size(); j++) { // Create a new QTreeWidgetItem for the module type QTreeWidgetItem *type_item = new QTreeWidgetItem(); type_item->setText(0, types[j]->getName()); type_item->setData(0, Qt::UserRole, types[j]->getType()); type_item->setFlags(type_item->flags() | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled); // Add the module type to the group group_item->addChild(type_item); } } ui->ModuleSelector->setDragEnabled(true); ui->ModuleSelector->setDropIndicatorShown(false); // Disable dropping // This allows users to click on the group items to expand or contract the groups. // If expandsOnDoubleClick is disabled, this starts to ignore second clicks similar // to how the chevron icons do. connect(ui->ModuleSelector, &QTreeWidget::itemClicked, [=](QTreeWidgetItem *item, int /*column*/) { if (item->childCount() > 0) // check if the item is a group { if (item->isExpanded()) item->setExpanded(false); else item->setExpanded(true); } } ); // Set the QGraphicsScene as the scene for the graphics view ui->node_canvas->setScene(scene); ui->node_canvas->setModuleTypesManager(module_types_manager); ui->ModuleSelector->setDragEnabled(true); // Connect the selectionChanged signal to the NodeCanvas slot connect(scene, SIGNAL(selectionChanged()), ui->node_canvas, SLOT(onSelectionChanged())); // Connect the moduleSelectionChanged signal to the MainWindow slot connect(ui->node_canvas, &NodeCanvas::moduleSelectionChanged, this, &MainWindow::on_ModuleSelectionChanged); // Connect the text editors connect(ui->defaults_json_editor, &QTextEdit::textChanged, this, &MainWindow::on_DefaultsContentChanged); connect(ui->data_json_editor, &QTextEdit::textChanged, this, &MainWindow::on_DataContentChanged); // Connect the resize signal to the MainWindow slot connect(&resizeTimer, &QTimer::timeout, this, &MainWindow::on_ResizeTimerTimeout); resizeTimer.setSingleShot(true); loadConfig(); }
Thanks for any help you can provide!
-
Hello!
I'm running into a strange issue with a QTreeWidget.
Here's what's happening:
- First, I click on the chevron icon to expand the group. This works fine.
- I wait just a moment without moving the mouse, then click on it again. It does not close the group.
- I click on it a third time. This closes the group.
And here are a few clues that might help:
Waiting longer helps:
- First, I click on the chevron icon to expand the group. This works fine.
- I wait a few seconds without moving the mouse, then click on it again. The group closes as expected.
Moving the mouse away and back also helps:
- First, I click on the chevron icon to expand the group. This works fine.
- I quickly move the mouse away from the chevron icon, then back over it.
- I click on the chevron icon, and the group closes as expected.
I tried turning off the QTreeView's expandsOnDoubleClick property, but this made no difference.
Here's the code that populates the QTreeWidget:
MainWindow::MainWindow(QWidget *parent, ModuleTypesManager *module_types_manager) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); // Add the module to the QGraphicsScene scene = new QGraphicsScene(this); // Store the module_types_manager for later use this->module_types_manager = module_types_manager; // Get the module type groups QVector<QString> groups = module_types_manager->getGroups(); // // Populate the module selector // // First, iterate over the groups for (int i = 0; i < groups.size(); i++) { // Create a new QTreeWidgetItem for the group QTreeWidgetItem *group_item = new QTreeWidgetItem(); group_item->setText(0, groups[i]); // Group items should not highlight when you click on them. // Instead, they should expand or collapse. group_item->setFlags(group_item->flags() & ~Qt::ItemIsSelectable); // Add the group to the module selector ui->ModuleSelector->addTopLevelItem(group_item); // Get the module types for the group QVector<ModuleTypes *> types = module_types_manager->getTypes(groups[i]); // Iterate over the module types for (int j = 0; j < types.size(); j++) { // Create a new QTreeWidgetItem for the module type QTreeWidgetItem *type_item = new QTreeWidgetItem(); type_item->setText(0, types[j]->getName()); type_item->setData(0, Qt::UserRole, types[j]->getType()); type_item->setFlags(type_item->flags() | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled); // Add the module type to the group group_item->addChild(type_item); } } ui->ModuleSelector->setDragEnabled(true); ui->ModuleSelector->setDropIndicatorShown(false); // Disable dropping // This allows users to click on the group items to expand or contract the groups. // If expandsOnDoubleClick is disabled, this starts to ignore second clicks similar // to how the chevron icons do. connect(ui->ModuleSelector, &QTreeWidget::itemClicked, [=](QTreeWidgetItem *item, int /*column*/) { if (item->childCount() > 0) // check if the item is a group { if (item->isExpanded()) item->setExpanded(false); else item->setExpanded(true); } } ); // Set the QGraphicsScene as the scene for the graphics view ui->node_canvas->setScene(scene); ui->node_canvas->setModuleTypesManager(module_types_manager); ui->ModuleSelector->setDragEnabled(true); // Connect the selectionChanged signal to the NodeCanvas slot connect(scene, SIGNAL(selectionChanged()), ui->node_canvas, SLOT(onSelectionChanged())); // Connect the moduleSelectionChanged signal to the MainWindow slot connect(ui->node_canvas, &NodeCanvas::moduleSelectionChanged, this, &MainWindow::on_ModuleSelectionChanged); // Connect the text editors connect(ui->defaults_json_editor, &QTextEdit::textChanged, this, &MainWindow::on_DefaultsContentChanged); connect(ui->data_json_editor, &QTextEdit::textChanged, this, &MainWindow::on_DataContentChanged); // Connect the resize signal to the MainWindow slot connect(&resizeTimer, &QTimer::timeout, this, &MainWindow::on_ResizeTimerTimeout); resizeTimer.setSingleShot(true); loadConfig(); }
Thanks for any help you can provide!
@Clone45
If I get you [edit]right, the goal is to toggle node expansion/collapse when the user clicks on the item - in addition toQTreeWidget
's out-of-the-box expansion options, right?The Lambda in charge of this operation is a bit clumsy, but in principle doing the right thing.
You could replace the whole inner if'ery with the one lineritem->setExpanded(!item->isExpanded());
Furthermore, the compiler will rightfully find 3rd argument Lambdas risky business - it prefers athis
argument before.
But that doesn't prevent anything from working.Without seeing the entire code, it's a bit of guessing in the dark.
Waiting longer helps:
Assuming no code is blocking the event loop:
QTreeView
(whichQTreeWidget
inherits from) overridesQWidget::mouseDobleClickEvent()
andQWidget::mousePressEvent()
. In the latter, it checks if an expansion or collapse is could be the reason for the (first) click. That will swallow the mouse click you are waiting for. At some point, it will just time out, that's why waiting helps.
To prevent that from happening, I don't see other save options than subclassingQTreeWidget
and overriding the click-stealing event handlers. -
@Clone45
If I get you [edit]right, the goal is to toggle node expansion/collapse when the user clicks on the item - in addition toQTreeWidget
's out-of-the-box expansion options, right?The Lambda in charge of this operation is a bit clumsy, but in principle doing the right thing.
You could replace the whole inner if'ery with the one lineritem->setExpanded(!item->isExpanded());
Furthermore, the compiler will rightfully find 3rd argument Lambdas risky business - it prefers athis
argument before.
But that doesn't prevent anything from working.Without seeing the entire code, it's a bit of guessing in the dark.
Waiting longer helps:
Assuming no code is blocking the event loop:
QTreeView
(whichQTreeWidget
inherits from) overridesQWidget::mouseDobleClickEvent()
andQWidget::mousePressEvent()
. In the latter, it checks if an expansion or collapse is could be the reason for the (first) click. That will swallow the mouse click you are waiting for. At some point, it will just time out, that's why waiting helps.
To prevent that from happening, I don't see other save options than subclassingQTreeWidget
and overriding the click-stealing event handlers.@Axel-Spoerl said in QTreeWidget not expanding/collapsing when clicking twice on the arrow:
To prevent that from happening, I don't see other save options than subclassing QTreeWidgetand overriding the click-stealing event handlers.
Thank you so much for this insight!
-
C Clone45 has marked this topic as solved on