gpt4 book ai didi

c++ - 如何完全清除 QTreeWidget 选择?

转载 作者:行者123 更新时间:2023-11-30 05:00:59 26 4
gpt4 key购买 nike

我正在尝试制作一个包含多个 QTreeWidget 的程序。但是,我的目标是一次只允许选择 1 个 QTreeWidget 行。

我已经设法使用 currentItemChanged 信号实现了这一点,但它出错了。

要重现问题...

  1. 在一个 QTreeWidget 上选择一行。
  2. 在 OTHER QTreeWidget 上选择另一行。此时所有 QTreeWidget 选择都被删除(太棒了,这正是我想要的)。
  3. 在与第 1 步相同的 QTreeWidget 上选择同一行。此时它已经出现错误,因为您之前的选择仍然被选中...

我是否不正确地清除了选择,如果是,我应该如何清除它?

这是问题的图片。

https://i.imgur.com/e4Uj5tb.png

这是我的来源...

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTreeWidget>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

private slots:
void OnSelectedTreeValueChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);

private:
Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDebug>
#include <QTreeWidget>
#include <QTreeWidgetItem>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

ui->treeWidget->expandAll();
ui->treeWidget->setItemsExpandable(false);

ui->treeWidget_2->expandAll();
ui->treeWidget_2->setItemsExpandable(false);

connect(ui->treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(OnSelectedTreeValueChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
connect(ui->treeWidget_2, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(OnSelectedTreeValueChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::OnSelectedTreeValueChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
if(current->childCount() == 0)
{
// Get OUR parrent item.
QTreeWidgetItem* parent_item = current->parent();

// Go through each tree & deselect selections.
QObject* sender_object = sender();
QTreeView* sender_tree = static_cast<QTreeView*>(sender_object);
const QList<QTreeWidget*> children = ui->TreeScrollAreaContents->findChildren<QTreeWidget*>(QRegularExpression(), Qt::FindDirectChildrenOnly);
for(QList<QTreeWidget*>::const_iterator it = children.begin(); it != children.end(); it++)
{
QTreeWidget* child_tree = *it;
if(sender_tree != child_tree)
{
child_tree->clearSelection();
child_tree->clearFocus();
}
}
}
}

主窗口.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>176</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QScrollArea" name="TreeScrollArea">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>401</width>
<height>171</height>
</rect>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="TreeScrollAreaContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>399</width>
<height>169</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">#TreeScrollAreaContents {
background-color: #000000;
}</string>
</property>
<layout class="QGridLayout" name="TreeScrollAreaGridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QTreeWidget" name="treeWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<column>
<property name="text">
<string>1</string>
</property>
</column>
<item>
<property name="text">
<string>Item 1</string>
</property>
<item>
<property name="text">
<string>Sub Item 1</string>
</property>
</item>
<item>
<property name="text">
<string>Sub Item 2</string>
</property>
</item>
<item>
<property name="text">
<string>Sub Item 3</string>
</property>
</item>
<item>
<property name="text">
<string>Sub Item 4</string>
</property>
</item>
</item>
</widget>
</item>
<item row="0" column="1">
<widget class="QTreeWidget" name="treeWidget_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<column>
<property name="text">
<string>1</string>
</property>
</column>
<item>
<property name="text">
<string>Item 1</string>
</property>
<item>
<property name="text">
<string>Sub Item 1</string>
</property>
</item>
<item>
<property name="text">
<string>Sub Item 2</string>
</property>
</item>
<item>
<property name="text">
<string>Sub Item 3</string>
</property>
</item>
<item>
<property name="text">
<string>Sub Item 4</string>
</property>
</item>
</item>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();

return a.exec();
}

最佳答案

一件事是 currentItem,另一件事是选择的项目,而不是使用 currentItemChanged 信号,您必须使用信号 itemSelectionChanged。当使用 clearSelection() 时,相应的 QTreeWidget 也会发出信号 itemSelectionChanged 并且这可能会产生一个无限循环,解决方案是使用 block 信号()

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTreeWidgetItem>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
private slots:
void OnSelectedTreeValueChanged(); // remove arguments
};

#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QTreeWidget>
#include <QTreeWidgetItem>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

const QList<QTreeWidget*> childrens = ui->TreeScrollAreaContents->findChildren<QTreeWidget*>(QRegularExpression(), Qt::FindDirectChildrenOnly);
for(QTreeWidget* child_tree: childrens)
{
child_tree->expandAll();
child_tree->setItemsExpandable(false);
connect(child_tree, &QTreeWidget::itemSelectionChanged, this, &MainWindow::OnSelectedTreeValueChanged);
}
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::OnSelectedTreeValueChanged()
{
QTreeWidget *sender_tree = qobject_cast<QTreeWidget *>(sender());

if(sender_tree->currentItem()->childCount() == 0)
{
const QList<QTreeWidget*> childrens = ui->TreeScrollAreaContents->findChildren<QTreeWidget*>(QRegularExpression(), Qt::FindDirectChildrenOnly);
for(QTreeWidget* child_tree: childrens)
{
if(sender_tree != child_tree)
{
child_tree->blockSignals(true);
child_tree->clearSelection();
child_tree->blockSignals(false);
}
}
}
}

注意:

我将解释为什么您的方法不起作用,您正在使用 currentItem 作为算法的基本元素,但是可能选择或不选择 currentItemclearSelection 不影响 currentItem

关于c++ - 如何完全清除 QTreeWidget 选择?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50477775/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com