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

C++ 单击并拖动时禁用QListWidget中的自动选择项,c++,qt,qwidget,qgraphicsview,C++,Qt,Qwidget,Qgraphicsview,今天我花了大半时间试图解决看似琐碎的QListWidget行为定制问题:当使用时,按下鼠标左键并移动鼠标光标,ListWidget的内容将滚动,所选内容将移动到恰好出现在鼠标光标下的另一项。我可以滚动,但我想避免选择所有consequential项,因为这会导致程序中的及时操作。最后,我想保持列表内容在鼠标按下和移动时滚动,但只能通过直接单击来选择项目。 此列表禁用拖放,这是默认行为,应该是;我试图明确地禁用它:没有任何更改 我已经阅读了QistWidget、QListWidgetItem、QL

今天我花了大半时间试图解决看似琐碎的QListWidget行为定制问题:当使用时,按下鼠标左键并移动鼠标光标,ListWidget的内容将滚动,所选内容将移动到恰好出现在鼠标光标下的另一项。我可以滚动,但我想避免选择所有consequential项,因为这会导致程序中的及时操作。最后,我想保持列表内容在鼠标按下和移动时滚动,但只能通过直接单击来选择项目。 此列表禁用拖放,这是默认行为,应该是;我试图明确地禁用它:没有任何更改

我已经阅读了QistWidget、QListWidgetItem、QListView等Qt相关类的所有可用文档!试图理解这些小部件的源代码;挖了StackOverflow和Google。。。但遗憾的是,没有结果:

以下是我的QListWidget的所有相关代码:单一选择,没有什么特别之处:

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平台都有类似的行为。

为了那些偶然发现相同问题的人,我的解决方案是:将QListWidget子类化,并在按下leftButton时使子类忽略mouseMove事件

标题:

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);
}
//////////////////////////////////////////////////////////////////////////

想把它做好吗?那就自己动手吧!:

你的解决方案为我扼杀了滚动。我正在使用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);

    }
}

因此,它只需单击即可进行选择。

您是否尝试使用eventFilter功能过滤掉导致问题的事件?您指的是什么事件?有鼠标按下,鼠标移动和鼠标释放,经典的组合。如果有一种简单的方法来定制ListWidget的行为,但我没有找到,那么我不会编写我自己的自定义版本的ListWidget。在此之前,我对同一个ListWidget进行了4次其他定制,所有这些定制都花费了2小时来完成文档、样本等,并产生了一行代码:设置此标志或更改该设置。我真的希望能找到类似的东西。对不起,我不知道有什么标志可以实现这种行为,但我对ListWidgets没有太多经验,所以可能有一个我不知道的标志。
on_listview_clicked(const QModelIndex &index)
{
    if (index.isValid())
    {
        ui->listView->selectionModel->select(index, QItemSelectionModel::Toggle | QItemSelectionModel::Rows);

    }
}