Как мне полностью очистить выбор QTreeWidget? - PullRequest
0 голосов
/ 23 мая 2018

Я пытаюсь создать программу, которая имеет несколько QTreeWidget.Тем не менее, моя цель состоит в том, чтобы разрешить ТОЛЬКО для выбора 1 строки QTreeWidget за один раз.

Мне удалось сделать это, используя сигнал currentItemChanged, но он выдает ошибку.

Чтобы воспроизвести проблему ...

  1. Выберите строку в одном QTreeWidget.
  2. Выберите другую строку в ДРУГОМ QTreeWidget.В этот момент все выделения QTreeWidget удаляются (отлично, это именно то, что я и хотел).
  3. Выберите ту же строку в том же QTreeWidget, что и в шаге 1. На данный момент она вышла из строя, потому что ваш предыдущий выбор все еще выбран...

Неправильно ли я очищаю выделение, и если да, то как мне его очистить?

Вот изображение проблемы.

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 голосов
/ 23 мая 2018

Одна вещь - это 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 может быть выбран или нет, clearSelection не влияет на currentItem.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...