代码之家  ›  专栏  ›  技术社区  ›  Rick

如何完全清除qtreeWidget选择?

  •  1
  • Rick  · 技术社区  · 6 年前

    我正在尝试制作一个具有多个qtreeWidget的程序。但是,我的目标是一次只允许选择一个qtreeWidget行。

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

    为了重现这个问题…

    1. 在一个qtreeWidget上选择一行。
    2. 在其他qtreewidget上选择另一行。此时,所有qtreeWidget选择都被删除(这正是我想要的)。
    3. 在同一qtreeWidget上选择与步骤1相同的行。现在它已经被监听了,因为您以前的选择仍然被选中…

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

    这是这个问题的图片。

    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>
    

    主.cpp

    #include "mainwindow.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   eyllanesc RAHUL KUMAR    6 年前

    一件事是 currentItem 另一个是所选项目,而不是使用 currentItemChanged 信号你必须使用信号 itemSelectionChanged . 使用时 clearSelection() 各自的 QTreeWidget 也会发出信号 项选择已更改 这会产生一个无限循环,解决方法是 blockSignals() .

    主窗口.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);
                }
            }
        }
    }
    

    注:

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