QApplication::mouseButtons 的线程安全性和延迟安全性如何?

Posted

技术标签:

【中文标题】QApplication::mouseButtons 的线程安全性和延迟安全性如何?【英文标题】:How thread-safe and latency-safe is QApplication::mouseButtons? 【发布时间】:2011-11-20 05:39:04 【问题描述】:

当您从模型中获得鼠标信号到您的插槽时,传递的参数是 QModelIndex。

QModelIndex 不会告诉你按下了什么按钮。所以,我们可以求助于 QApplication::mouseButtons。但 QApplication::mouseButtons 是当前按钮按下,而不是模型经历点击时。

我的思想实验是说,在按下右键后,底层视图将信号发送到我的小部件,但就在我的小部件插槽接收到信号之前,发生了虚假的左键单击。因此,在收到 QModelIndex 时调用 QApplication::mouseButtons 会错误地将正在单击的行与鼠标左键而不是右键相关联。这种情况怎么可能?

当您查看 Qt 甚至 QML 时,需要大量代码杂技才能在收到 QModelIndex 时获得正确的鼠标按钮信息。诺基亚力求推广鼠标按钮不可知论是一项政策吗?

【问题讨论】:

【参考方案1】:

我不认为这是一个非常可能的情况,但它可能会发生。

确定单击了哪个按钮的“简单”方法是继承QTableView(或您正在使用的视图并重新实现mouseReleaseEvent

void mouseReleaseEvent(QMouseEvent * event)

    // store the button that was clicked
    mButton = event->button();
    // Now call the parent's event
    QTableView::mouseReleaseEvent(event);

默认情况下,mouseReleaseEvent 会在视图的某个项目被按下时发出 clicked 信号

如果用户在您的小部件内按下鼠标,然后拖动 在释放鼠标按钮之前将鼠标移动到另一个位置,您的 小部件接收发布事件。该函数将发出 如果一个项目被按下,clicked() 信号。

诀窍是在派生类中捕获clicked 信号并发出一个新信号,该信号除了模型索引之外还将包含按钮。

// Define your new signal in the header
signals:
    void clicked(QModelIndex, Qt::MouseButton);

// and a slot that will emit it
private slots:
    void clickedSlot(QModelIndex); 

// In the constructor of your derived class connect the default clicked with a slot 
connect(this, SIGNAL(clicked(QModelIndex), this, SLOT(clickedSlot(QModelIndex)));

// Now the slot just emits the new clicked signal with the button that was pressed
void clickedSlot(QModelIndex i)

    emit clicked(i, mButton);

如果您还需要pressed 信号,您可以使用mousePressEvent 执行类似的操作。

【讨论】:

谢谢你——这真是太棒了。我现在可以使用 QApplication::mouseButtons 丢弃。

以上是关于QApplication::mouseButtons 的线程安全性和延迟安全性如何?的主要内容,如果未能解决你的问题,请参考以下文章