c++ - 选定鼠标事件的 Qt 透明
问题描述
C++ Qt 新手在这里。我使用旨在通过鼠标滚轮控制的 QDial 对象,它可以正常工作,在必要时发出 valueChanged() 信号。
我想在它上面放一个半透明的 QToolButton,允许用户单击按钮(并将 QDial 值设置为预定义的数字),同时保持像往常一样使用鼠标滚轮控制 QDial 的能力。
我对 TransparentForMouseEvents 属性做了一些试验:
ui->toolButton_Example->setAttribute(Qt::WA_TransparentForMouseEvents);
问题是 - 上面的代码关闭了所有事件,包括发出 clicked() 信号的能力。
有没有办法让 QToolButton 选择性地为 MouseWheelEvents 透明,同时保留响应 MouseClick 事件的能力?或者这是否需要从头开始重写事件过滤器?
编辑:澄清一下 - 这个问题是关于使 QToolButton 对 MouseWheel 事件透明,同时仍然允许它响应 MouseClick 事件。这不是让按钮在图形意义上透明。
解决方案 好的,通过继承 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 对象在按下时“行为”像一个按钮,发出 sliderPressed 信号,同时仍然响应 MouseWheelEvent(就像一个普通的 QDial)。
我认为这是最简单和最“类似 Qt”的解决方案,但如果我弄错了,请纠正我。
解决方案
您可以使用QObject::installEventFilter
让父对象在事件到达工具按钮之前对其进行过滤。然后,覆盖父QObject::eventFilter
级以处理/忽略该事件。
我在下面创建一个示例:
主窗口.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
主窗口.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
}
}
推荐阅读
- python - 使用python解析HTML + CSS时获取标签中文本大小的最佳方法是什么?
- android - 当我单击按钮时,Android 回收站视图未更新
- r - 对具有相同名称的列求和
- haskell - 单子的运算符关联性、关联律和值依赖性如何结合在一起?
- .htaccess - .htaccess 并按大小写区分查询字符串
- java - Apache POI,在同一行中将文本左对齐,其他文本右对齐
- r - 根据动态列数和名称对数据框进行子集化
- python - 从txt文件中提取数据
- c++11 - 多重定义错误(collect2:error:ld returned 1 exit status)
- java - 飞溅前的Android白屏