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

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

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

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

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

【问题讨论】:

    标签: c++ qt qt4 mouse qml


    【解决方案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 丢弃。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多