在单击+拖动时禁用 QListWidget 中的自动选择项目
Posted
技术标签:
【中文标题】在单击+拖动时禁用 QListWidget 中的自动选择项目【英文标题】:Disable auto-selecting items in QListWidget on click+drag 【发布时间】:2016-03-25 20:38:38 【问题描述】:我今天花了大半的时间试图解决看似微不足道的 QListWidget 行为定制:当使用时按下鼠标左键并移动鼠标光标,ListWidget 的内容会滚动,并且选择会移动到恰好出现在鼠标下的另一个项目光标。我可以滚动,但我想避免选择所有后续项目,因为这会导致我的程序及时操作。最后,我想保持列表内容在鼠标按下和移动时滚动,但只能通过直接单击它们来选择项目。 此列表禁用拖放(这是默认行为),它应该是;我试图明确禁用它:没有任何变化。
我已经阅读了所有关于 Qt 相关类的可用文档,例如 QListWidget、QListWidgetItem、QListView,应有尽有!试图理解这些小部件的源代码;挖了 *** 和 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 平台都有相似的行为。
【问题讨论】:
您是否尝试过使用 eventFilter 函数来过滤掉导致问题的事件? 你是什么意思?有鼠标Press、mouseMove和mouseRelease,经典组合。如果有一种简单的方法可以自定义其行为(我没有找到),我会避免编写我自己的自定义版本的 ListWidget。在此之前,我对同一个 ListWidget 进行了 4 次其他自定义,所有这些都花费了大约 2 小时来完成文档、示例等,并产生了一行代码:设置此标志或更改该设置。我真的希望能找到类似的东西。 抱歉,我不知道会实现这种行为的标志,但我对 ListWidgets 没有太多经验,所以可能有一个我不知道的标志。跨度> 【参考方案1】:为了遇到同样问题的人,这里是我的解决方案:子类 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);
//////////////////////////////////////////////////////////////////////////
使用很简单,您可以根据需要使用尽可能多的列表小部件:
QtListWidget* categoryListWidget;
// all original code above would still work as expected
...
想要正确完成吗?然后自己做! :)
【讨论】:
【参考方案2】:您的解决方案让我无法滚动。我正在使用 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);
所以,它只会在点击时选择。
【讨论】:
以上是关于在单击+拖动时禁用 QListWidget 中的自动选择项目的主要内容,如果未能解决你的问题,请参考以下文章
在 QHeaderView 和 QListWidget 之间拖放列