【问题标题】:Right mouse functionality in QPushButtonQPushButton 中的鼠标右键功能
【发布时间】:2016-08-30 06:24:41
【问题描述】:

我想在QPushButton上实现鼠标左键的所有功能(如clicked()、pressed()、released()、setAutoRepeat())保留所有左键功能完好。这是重新实现 eventFilter 的代码,它没有给出理想的结果。

bool PreciseControl::eventFilter(QObject *, QEvent *event) 
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);


if(event->type() == QEvent::MouseButtonPress &&
                    mouseEvent->button()==Qt::RightButton )
 {


        emit rightMousePressed();
        return true;
 }
else if(event->type() == QEvent::MouseButtonRelease &&
        mouseEvent->button()==Qt::RightButton )
{
        emit rightMouseReleased();
        return true;
}


if(event->type() == QEvent::MouseButtonPress &&
                    mouseEvent->button()==Qt::LeftButton )
 {


        emit leftMousePressed();
        return true;
 }
else if(event->type() == QEvent::MouseButtonRelease &&
        mouseEvent->button()==Qt::LeftButton )
{
        emit leftMouseReleased();
        return true;
}

 return false;}

有人可以帮忙吗?提前致谢。

【问题讨论】:

  • 根据你的例子检查link的事件过滤器,这里指定我们需要在对象上安装事件过滤器。在您的情况下,按钮对象名称。其他方式,您可以从 QPushbutton 创建驱动类并编写自己的 QPushbotton 的 MouseEvent
  • 请出示minimal reproducible example 并准确解释什么不起作用,“没有给出理想的结果”不够具体。
  • @Mailerdaimon 我想我已经提供了最小、完整和可验证的示例代码。至于“没有给出理想的结果”,让我说得更具体一些。在右键 press() 上,我没有获得自动重复功能,在左键上按下 leftMousePressed() 信号没有发出。希望这能稍微澄清一下。
  • @rugi 很高兴您得到的答案在某种程度上对您有所帮助。这表明这个问题并非不可用。但我的立场是,您的代码和描述既不完整也不可验证。再次阅读这篇文章,它将帮助您在下次提问时获得更多更好的答案。

标签: qt


【解决方案1】:

您不应为此使用事件过滤器。子类QPushButton 并实现您自己的右键单击处理。这是一个工作示例(我没有彻底测试它,所以可能存在一些问题):

#include <QApplication>
#include <QPushButton>
#include <QMouseEvent>
#include <QLayout>
#include <QDebug>

class CustomButton : public QPushButton
{
    Q_OBJECT
public:
    explicit CustomButton(QWidget *parent = 0) : QPushButton(parent){}

protected:
    void mousePressEvent(QMouseEvent *e)
    {
        if(e->button() == Qt::RightButton && hitButton(e->pos()))
        {
            setDown(true);
            emit pressed();
        }
        QPushButton::mousePressEvent(e);
    }

    void mouseMoveEvent(QMouseEvent *e)
    {
        if(e->buttons() & Qt::RightButton)
        {
            if(hitButton(e->pos()) != isDown())
                setDown(!isDown());
        }
        QPushButton::mouseMoveEvent(e);
    }

    void mouseReleaseEvent(QMouseEvent *e)
    {
        if(e->button() == Qt::RightButton)
        {
            setDown(false);
            if(hitButton(e->pos()))
                click();
        }
        QPushButton::mouseReleaseEvent(e);
    }
};

void buttonClicked()
{
    qDebug() << "CLICKED";
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QWidget w;
    w.resize(500,500);
    w.setLayout(new QVBoxLayout);
    CustomButton button;
    button.setAutoRepeat(true);
    QObject::connect(&button, &CustomButton::clicked, &buttonClicked);
    w.layout()->addWidget(&button);
    w.show();

    return a.exec();
}

#include "main.moc"

如果您想区分右键单击和左键单击,请查看source code for QAbstractButton::click,并为右键单击实现自己的。

【讨论】:

  • 实际上,使用事件过滤器是向QWidget 添加行为的一种惯用方法:)
  • 谢谢。它在一定程度上解决了我的问题。但是我还没有从右键按下事件中获得 AutoRpeat 功能。你能指点我怎么做吗?提前致谢。
  • @KubaOber 当然。我只是觉得这种方式更漂亮:)
  • @rugi 在我提供的示例中,自动重复正在工作。当我按住鼠标右键时,"CLICKED" 消息不断打印出来。
  • @thuga 是的,它的工作原理。我这边有一个错误。感谢您的帮助。
【解决方案2】:

您可以在事件过滤器中实现该功能,并将其安装在您希望可右键单击的按钮上。

// https://github.com/KubaO/stackoverflown/tree/master/questions/right-to-left-event-39220180
#include <QtWidgets>

class RightToLeftClick : public QObject {
    bool eventFilter(QObject *watched, QEvent *event) {
        if (event->type() == QEvent::MouseButtonDblClick ||
                event->type() == QEvent::MouseButtonPress ||
                event->type() == QEvent::MouseButtonRelease) {
            auto ev = static_cast<QMouseEvent*>(event);
            if (ev->button() == Qt::RightButton) {
                auto buttons = ev->buttons();
                if (buttons & Qt::RightButton) {
                    buttons ^= Qt::RightButton;
                    buttons |= Qt::LeftButton;
                }
                QMouseEvent lev{ev->type(),
                            ev->localPos(),
                            ev->windowPos(),
                            ev->screenPos(),
                            Qt::LeftButton,
                            buttons,
                            ev->modifiers(),
                            ev->source()};
                Q_ASSERT(! (lev.buttons() & Qt::RightButton));
                QCoreApplication::sendEvent(watched, &lev);
                return true;
            }
        }
        return QObject::eventFilter(watched, event);
    }
public:
    explicit RightToLeftClick(QObject * parent = nullptr) : QObject{parent} {
        addTo(parent);
    }
    void addTo(QObject * obj) {
        if (obj) obj->installEventFilter(this);
    }
};

使用方法如下:

int main(int argc, char ** argv) {
    QApplication app{argc, argv};
    QWidget ui;
    QVBoxLayout layout{&ui};
    QPushButton button1{"Left Click Me"};
    QPushButton button2{"Right Click Me"};
    layout.addWidget(&button1);
    layout.addWidget(&button2);
    ui.show();
    RightToLeftClick rtl{&button2};
    return app.exec();
}

【讨论】:

  • 谢谢。但是我还没有从右键按下事件中获得 AutoRpeat 功能。你能指点我怎么做吗?提前致谢。
  • 我猜你还没有尝试过这段代码。自动重复在 Qt 5.7 下工作正常。当然你需要在按钮上setAutoRepeat
猜你喜欢
  • 1970-01-01
  • 2021-09-29
  • 1970-01-01
  • 2014-05-06
  • 2012-10-17
  • 2021-02-26
  • 2014-01-26
  • 2017-03-14
  • 1970-01-01
相关资源
最近更新 更多