如何完全清除QTreeWidget选择?

时间:2018-05-22 23:24:04

标签: c++ qt

我试图创建一个包含多个QTreeWidget的程序。但是,我的目标是只允许一次选择1个QTreeWidget行。

我已经设法使用currentItemChanged信号实现了这一点,但是它有问题。

重现问题...

  1. 在一个QTreeWidget上选择一行。
  2. 在OTHER QTreeWidget上选择另一行。此时,所有QTreeWidget选择都被删除了(很棒,这正是我想要的)。
  3. 在与步骤1相同的QTreeWidget上选择相同的行。此时它已经被淘汰,因为您之前的选择仍然被选中...
  4. 我是否不正确地清除选择,如果是,我应该如何清除它?

    这是问题的图片。

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

    这是我的来源......

    mainwindow.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
    

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

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

1 个答案:

答案 0 :(得分:1)

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

<强> mainwindow.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

<强> mainwindow.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作为算法的基本元素,但可以选择currentItem或不选择clearSelectioncurrentItem不会影响cgi/app.js (compiled typescript file) node_modules/@types node_modules/three/build/three.module.js src/app.ts index.html tsconfig.json package.json