单击+拖动时禁用 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);
}
}
因此,它只会在单击时选择。
我今天花了大半时间试图解决看似微不足道的 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);
}
}
因此,它只会在单击时选择。