编程语言
757
自定义按钮
基于Qt提供的事件处理器函数,我们可以非常轻松地按照自己的想法制作出一个按钮,按钮的要求如下:
- 从视觉上看是一个不规则按钮(按钮实际上都是矩形的)
- 按钮上需要显示指定的背景图片
- 按钮在鼠标的不同操作阶段(无操作、鼠标悬停、鼠标按下)能够显示不同的背景图
1. 添加子类
新添加的按钮类可以让它继承 QPushButton,也可以让它继承其他的窗口类(代价是当鼠标点击事件触发之后需要自己发射自定义信号)
,这里让添加的子类从QWidget类派生。
自定义类头文件
#ifndef MYBUTTON_H #define MYBUTTON_H #include <QWidget> class MyButton : public QWidget { Q_OBJECT public: explicit MyButton(QWidget *parent = nullptr); void setImage(QString normal, QString hover, QString pressed); protected: void mousePressEvent(QMouseEvent* ev); void mouseReleaseEvent(QMouseEvent* ev); void enterEvent(QEvent* ev); void leaveEvent(QEvent* ev); void paintEvent(QPaintEvent* ev); signals: void clicked(); private: QPixmap m_normal; QPixmap m_press; QPixmap m_hover; QPixmap m_current; }; #endif // MYBUTTON_H
自定义类源文件
#include "mybutton.h" #include <QPainter> MyButton::MyButton(QWidget *parent) : QWidget(parent) { } void MyButton::setImage(QString normal, QString hover, QString pressed) { // 加载图片 m_normal.load(normal); m_hover.load(hover); m_press.load(pressed); m_current = m_normal; // 设置按钮和图片大小一致 setFixedSize(m_normal.size()); } void MyButton::mousePressEvent(QMouseEvent *ev) { // 鼠标被按下, 发射这个自定义信号 emit clicked(); m_current = m_press; update(); } void MyButton::mouseReleaseEvent(QMouseEvent *ev) { m_current = m_normal; update(); } void MyButton::enterEvent(QEvent *ev) { m_current = m_hover; update(); } void MyButton::leaveEvent(QEvent *ev) { m_current = m_normal; update(); } void MyButton::paintEvent(QPaintEvent *ev) { QPainter p(this); p.drawPixmap(rect(), m_current); }
2. 使用自定控件
由于Qt的UI工具箱中提供的都是标准控件,自定义的控件是不能直接拖拽到UI窗口中的,这时我们需要先看一下自定义控件的基类类型:上面自定义的 MyButton
的基类是 QWidget
类型,因此需要往窗口中拖拽一个QWidget类型的标准控件,然后在这个标准控件上鼠标右键:
这样添加的控件类型就变成了自定义的子类类型:
3. 设置图片
在主窗口中通过添加的按钮的对象,调用子类的成员函数给其添加图片:
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); // 给自定义按钮设置图片 ui->button->setImage(":/ghost-1.png", ":/ghost-2.png", ":/ghost-3.png"); // 处理自定义按钮的鼠标点击事件 connect(ui->button, &MyButton::clicked, this, [=]() { QMessageBox::information(this, "按钮", "莫要调戏我..."); }); } MainWindow::~MainWindow() { delete ui; }