单击+拖动时禁用 QListWidget 中的自动选择项目

Disable auto-selecting items in QListWidget on click+drag

我今天花了大半时间试图解决看似微不足道的 QListWidget 行为定制:当使用按下鼠标左键并移动鼠标光标时,ListWidget 的内容滚动并且 selection 移动到另一个恰好出现在鼠标光标下的项目。我可以滚动,但我想避免 selecting 所有后续项目,因为这会导致我的程序及时运行。最后,我想让列表内容在鼠标按下和移动时滚动,但 select 项只能通过直接单击它们来滚动。 此列表禁用了拖放功能(这是默认行为),它应该是;我已尝试明确禁用它:没有任何变化。

我已经阅读了所有与 Qt 相关的可用文档 类,例如 QListWidget、QListWidgetItem、QListView,应有尽有!试图理解这些小部件的源代码;挖出 Whosebug 和 Google...但遗憾的是没有结果:(

这是我的 QListWidget 的所有相关代码:单个 selection,没什么特别的:

QListWidget* categoryListWidget;
...
categoryListWidget = new QListWidget();
categoryListWidget->move(offsetX, offsetY);
categoryListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
categoryListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
categoryListWidget->setFocusPolicy(Qt::NoFocus);
categoryListWidget->setStyleSheet(listQSS);
...
categoryListWidget->clear();
new QListWidgetItem(tr("1 - Sample Category 1"), categoryListWidget);
new QListWidgetItem(tr("2 - Sample Category 2"), categoryListWidget);
new QListWidgetItem(tr("3 - Sample Category 3 with a very long name"), categoryListWidget);
new QListWidgetItem(tr("4 - Sample Category 4"), categoryListWidget);

C++/Qt 5.5 如果这在某种程度上相关,则 Win 和 Mac 平台具有相似的行为。

看在遇到同样问题的人的份上,这是我的解决方案:subclass QListWidget 和 make child class 在按下 leftButton 时忽略 mouseMove 事件。

Header:

class QtListWidget: public QListWidget
{ // QListWidget clone that suppresses item selection on mouse click+drag
private:
    bool    mousePressed;
public:
     QtListWidget():QListWidget(), mousePressed(false) {}
protected:
    virtual void mousePressEvent(QMouseEvent *event);
    virtual void mouseMoveEvent(QMouseEvent *event);
    virtual void mouseReleaseEvent(QMouseEvent *event);
};

来源:

//////////////////////////////////////////////////////////////////////////
void QtListWidget::mousePressEvent(QMouseEvent *event){
//    qDebug() << "QtListWidget::mousePressEvent";
    if(event->button() == Qt::LeftButton)
        mousePressed = true;
    QListWidget::mousePressEvent(event);
}

void QtListWidget::mouseMoveEvent(QMouseEvent *event){
//    qDebug() << "QtListWidget::mouseMoveEvent";
    if(!mousePressed)   // disable click+drag
        QListWidget::mouseMoveEvent(event);
}

void QtListWidget::mouseReleaseEvent(QMouseEvent *event){
//    qDebug() << "QtListWidget::mouseReleaseEvent";
    if(event->button() == Qt::LeftButton)
        mousePressed = false;
    QListWidget::mouseReleaseEvent(event);
}
//////////////////////////////////////////////////////////////////////////

使用很简单,您需要多少列表小部件:

QtListWidget* categoryListWidget;
// all original code above would still work as expected
...

想做对吗?那就自己动手吧! :)

你的解决方案让我无法滚动。我正在使用 QListView。这是另一种方式:

在 QListView 父级的构造函数中:

ui->listView->setSelectionMode(QAbstractItemView::NoSelection);
connect(ui->listView, SIGNAL(clicked(QModelIndex)), this, SLOT(on_listview_clicked(QModelIndex)));

在连接的插槽中:

on_listview_clicked(const QModelIndex &index)
{
    if (index.isValid())
    {
        ui->listView->selectionModel->select(index, QItemSelectionModel::Toggle | QItemSelectionModel::Rows);

    }
}

因此,它只会在单击时选择。