Qt 关于Qtreewidget 项选择的问题

在使用Qtreewidget并创建几个项之后,如果单击项后按住鼠标,项的选择会滑动,如何设置不滑动,在第一次单击后就确定选择

可以在QTreeWidget的构造函数中使用setSelectionMode()函数设置选择模式。 例如:
treeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
这样就可以设置为只能单选了。

以下根据题主的反馈重新修改答案:
思路一:可以使用setSelectionMode(QAbstractItemView::NoSelection)禁止选择,然后自定义单击事件来确定选择。

#include <QtWidgets>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QTreeWidget treeWidget;
    treeWidget.setSelectionMode(QAbstractItemView::NoSelection);
    treeWidget.header()->setVisible(false);
    treeWidget.setRootIsDecorated(false);
    for (int i = 0; i < 5; ++i) {
        QTreeWidgetItem *item = new QTreeWidgetItem(&treeWidget);
        item->setText(0, QString("Item %1").arg(i + 1));
    }
    treeWidget.connect(&treeWidget, &QTreeWidget::itemClicked, [&treeWidget](QTreeWidgetItem *item, int column) {
        treeWidget.clearSelection();
        item->setSelected(true);
    });
    treeWidget.show();
    return a.exec();
}

思路二:可以使用信号/槽机制,在项单击时连接信号,设置选择,然后在信号处理函数中禁止选择。

#include <QApplication>
#include <QTreeWidget>
#include <QTreeWidgetItem>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTreeWidget treeWidget;
    treeWidget.setSelectionMode(QAbstractItemView::NoSelection);
    treeWidget.setWindowTitle("QTreeWidget Example");

    // 创建项
    QTreeWidgetItem *item1 = new QTreeWidgetItem(&treeWidget);
    item1->setText(0, "Item 1");
    QTreeWidgetItem *item2 = new QTreeWidgetItem(&treeWidget);
    item2->setText(0, "Item 2");
    QTreeWidgetItem *item3 = new QTreeWidgetItem(&treeWidget);
    item3->setText(0, "Item 3");

    // 信号/槽连接
    QObject::connect(&treeWidget, &QTreeWidget::itemClicked, &treeWidget, [&treeWidget](QTreeWidgetItem *item) {
        treeWidget.setCurrentItem(item);
        treeWidget.setSelectionMode(QAbstractItemView::NoSelection);
    });

    treeWidget.show();

    return a.exec();
}

也可以

#include <QtWidgets>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QTreeWidget treeWidget;
    treeWidget.setSelectionMode(QAbstractItemView::SingleSelection);
    treeWidget.setSelectionBehavior(QAbstractItemView::SelectItems);

    QObject::connect(&treeWidget, &QTreeWidget::itemClicked, [&treeWidget](QTreeWidgetItem *item, int column){
        treeWidget.setCurrentItem(item, column, QItemSelectionModel::Select);
        treeWidget.setSelectionMode(QAbstractItemView::NoSelection);
    });

    treeWidget.show();

    return a.exec();
}

这个代码设置了QTreeWidget的选择模式为单选,选择行为为选择项,并在项单击时连接信号,设置选择,然后在信号处理函数中禁止选择。

补充:可以使用自定义事件处理来实现,在鼠标按下时记录选择的项,在鼠标释放时判断是否与记录的项相同,如果不同则不选择。

#include <QListWidget>
#include <QMouseEvent>

class CustomListWidget : public QListWidget
{
    Q_OBJECT

public:
    CustomListWidget(QWidget *parent = nullptr) : QListWidget(parent)
    {
        setSelectionMode(QAbstractItemView::SingleSelection);
    }

protected:
    void mousePressEvent(QMouseEvent *event)
    {
        m_selectedItem = itemAt(event->pos());
        QListWidget::mousePressEvent(event);
    }

    void mouseReleaseEvent(QMouseEvent *event)
    {
        if (itemAt(event->pos()) != m_selectedItem)
            clearSelection();
        QListWidget::mouseReleaseEvent(event);
    }

private:
    QListWidgetItem *m_selectedItem;
};