选定鼠标事件的 Qt 透明

Qt Transparent for selected Mouse Events

这里是 C++ Qt 新手。我使用旨在通过鼠标滚轮控制的 QDial 对象,它工作正常,必要时发出 valueChanged() 信号。

我想在上面放一个半透明的QToolButton,允许用户点击按钮(并将QDial值设置为预定义的数字)同时保持使用鼠标滚轮控制的能力照常Q拨号。

我对 TransparentForMouseEvents 属性进行了一些试验:

ui->toolButton_Example->setAttribute(Qt::WA_TransparentForMouseEvents);

问题是 - 上面的代码关闭了所有事件,包括发出 clicked() 信号的能力。

有没有办法使 QToolButton 有选择地对 MouseWheelEvents 透明,同时保留响应 MouseClick 事件的能力?或者这是否需要从头开始重写事件过滤器?

编辑:澄清一下——这个问题是关于使 QToolButton 对 MouseWheel EVENTS 透明,同时仍然允许它响应 MouseClick EVENTS。这不是让按钮在图形意义上透明。

解决方案 好的,问题通过继承 QDial 并覆盖 MousePressEvent 和 MouseReleaseEvent 的传统方式解决了:

#include <QDial>
#include <QMouseEvent>


class QSuperDial : public QDial {

public:

    QSuperDial (QWidget *parent = nullptr) : QDial(parent) {

    }

    virtual void mousePressEvent (QMouseEvent *event) override {
        emit sliderPressed();
    }

    virtual void mouseMoveEvent (QMouseEvent * event) override {

    }

    virtual void mouseReleaseEvent (QMouseEvent *event) override {

    }

};

将 QDial 升级为 QSuperDial 会导致 QDial 对象 'behaves' 在按下时像一个按钮,发出 sliderPressed 信号,同时仍然响应 MouseWheelEvent(就像普通的 QDial)。

我认为这是最简单也是最'Qt-like'的解决方法,如果有误请指正

您可以使用 QObject::installEventFilter to have the parent object filter the events before they reach the tool button. Then, override the parent's QObject::eventFilter 来 handle/ignore 活动。

我在下面创建了一个例子:

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QToolButton>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    bool eventFilter(QObject *watched, QEvent *event) override;

private:
    QToolButton tool_button_ignored_;
    QToolButton tool_button_handled_;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"

#include <QDebug>
#include <QEvent>
#include <QHBoxLayout>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    tool_button_ignored_.setObjectName("tool_button_ignored_");
    tool_button_ignored_.setText("Ignored button");
    tool_button_ignored_.installEventFilter(this);

    tool_button_handled_.setObjectName("tool_button_handled_");
    tool_button_handled_.setText("Handled button");
    tool_button_handled_.installEventFilter(this);

    QWidget *central_widget = new QWidget{this};
    QHBoxLayout *layout = new QHBoxLayout{central_widget};
    layout->addWidget(&tool_button_ignored_);
    layout->addWidget(&tool_button_handled_);
    this->setCentralWidget(central_widget);
}

MainWindow::~MainWindow()
{
}

bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
    if (watched != &tool_button_ignored_ || event->type() != QEvent::Wheel)
    {
        qDebug() << event->type() << watched->objectName() << "handled";
        return QMainWindow::eventFilter(watched, event);
    }
    else
    {
        qDebug() << event->type() << watched->objectName() << "ignored";
        return true; // stop being handled further
    }
}