QApplication::mouseButtons是线程安全和延迟安全的

How thread-safe and latency-safe is QApplication::mouseButtons?

本文关键字:安全 延迟 线程 mouseButtons QApplication      更新时间:2023-10-16

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

QModelIndex没有告诉您按下了哪个按钮。因此,我们可以求助于QApplication::mouseButtons。但是QApplication::mouseButtons是当前按下的按钮,而不是模型经历的点击。

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

当您查看Qt甚至QML时,在接收到QModelIndex时,需要大量的代码技巧来实现适当的鼠标按钮信息。诺基亚正在努力推动鼠标按钮不可知论,这是一项政策吗?

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

一个"简单"的方法来确定哪个按钮被点击是子类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信号并发出一个新信号,该信号除了模型索引外还将包含按钮。
// 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做类似的事情。