自定义控件封装
项目中新建文件,选择模板—Qt—Qt设计师界面类。这样可以得到一个带ui文件的类。
新建一个自定义的smallWidget类,在其中设计好需要封装的控件。
在main.ui设计界面创建一个Widget,右键—提升为..—新建提升的类—smallWidget—添加(勾选全局包含)—提升。
1 2 3 4 5 6 7 8 9 10 11 12 13
| smallwidget.cpp
smallWidget::smallWidget(QWidget *parent) : QWidget(parent), ui(new Ui::smallWidget) { ui->setupUi(this);
void (QSpinBox::*spSignal)(int) = &QSpinBox::valueChanged; connect(ui->spinBox, spSignal, ui->horizontalSlider, &QSlider::setValue);
connect(ui->horizontalSlider, &QSlider::valueChanged, ui->spinBox, &QSpinBox::setValue); }
|
设置数字显示和进度条的关联。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| smallwidget.h
class smallWidget : public QWidget { Q_OBJECT
public: explicit smallWidget(QWidget *parent = 0); ~smallWidget();
void setNum(int num);
int getNum();
private: Ui::smallWidget *ui; };
----- smallwidget.cpp
void smallWidget::setNum(int num) { ui->spinBox->setValue(num); }
int smallWidget::getNum() { return ui->spinBox->value(); }
----- widget.cpp
connect(ui->btn_get, &QPushButton::clicked, [=]() { QMessageBox::information(this, "当前数值", QString::number(ui->smallwidget->getNum())); });
connect(ui->btn_set, &QPushButton::clicked, [=]() { ui->smallwidget->setNum(50); });
|
为自定义控件提供接口。
事件QEvent
鼠标事件
QWidget类提供QWidget::enterEvent(QEvent *event)
捕捉鼠标进入事件,函数类型为virtual protected
。
新建类myLabel,继承自QWidget,重载函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| myLabel.cpp
void myLabel::enterEvent(QEvent *event) { qDebug() << "cursor enter!"; }
void myLabel::leaveEvent(QEvent *event) { qDebug() << "cursor leave!"; }
void myLabel::mousePressEvent(QMouseEvent *ev) { qDebug() << "mouse pressed!"; }
void myLabel::mouseReleaseEvent(QMouseEvent *ev) { qDebug() << "mouse released!"; }
void myLabel::mouseMoveEvent(QMouseEvent *ev) { qDebug() << "mouse moved!"; }
|
从QMouseEvent *ev
捕获点击的位置等信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| void myLabel::mousePressEvent(QMouseEvent *ev) { if(ev->button() == Qt::LeftButton) { QString str = QString("mouse pressed! x = %1 y = %2").arg(ev->x()).arg(ev->y()); qDebug() << str; } }
void myLabel::mouseMoveEvent(QMouseEvent *ev) { if(ev->buttons() & Qt::LeftButton) { qDebug() << "mouse moved"; } }
|
在构造函数中设置setMouseTracking(true);
可以使在没有按下鼠标键的情况下mouseMoveEvent()
也能被触发。
定时器
[virtual protected] void QObject::timerEvent(QTimerEvent *event)
提供定时器事件。
构造函数中启动定时器:
重写定时器事件函数:
1 2 3 4
| void Widget::timerEvent(QTimerEvent *ev) { static int num = 1; ui->label->setText(QString::number(num++)); }
|
可以启动多个定时器,由startTimer()
返回值和ev->timerId()
区分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this);
id1 = startTimer(1000); id2 = startTimer(2000); }
void Widget::timerEvent(QTimerEvent *ev) { if (ev->timerId() == id1) { static int num = 1; ui->label->setText(QString::number(num++)); } if (ev->timerId() == id2) { static int num2 = 1; ui->label_2->setText(QString::number(num2++)); } }
|
定时器的第二种实现方式:类QTimer
。
1 2 3 4 5 6 7 8 9 10 11 12
| QTimer *timer = new QTimer(this); timer->start(500);
connect(timer, &QTimer::timeout, [=]() { static int num3 = 1; ui->label_3->setText(QString::number(num3++)); });
connect(ui->btn_pause, &QPushButton::clicked, [=]() { if (timer->isActive()) timer->stop(); else timer->start(); });
|
事件分发器
程序接收到事件之后,会由bool event(QEvent *ev)
事件分发器将事件下发到具体的函数,如enterEvent(QEvent*)
等。
我们可以通过事件分发器对事件进行拦截。
1 2 3 4 5 6 7 8 9
| bool myLabel::event(QEvent *event) { if (event->type() == QEvent::MouseButtonPress) { QMouseEvent *ev = static_cast<QMouseEvent*>(event); QString str = QString("In func event: mouse pressed! x = %1 y = %2").arg(ev->x()).arg(ev->y()); qDebug() << str; return true; } return QWidget::event(event); }
|
事件过滤器
通过事件过滤器,可以在事件分发器之前再对事件做一次拦截。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| widget.cpp
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this);
......
ui->label->installEventFilter(this); }
bool Widget::eventFilter(QObject *watched, QEvent *event) { if (watched == ui->widget) { if (event->type() == QEvent::MouseButtonPress) { QMouseEvent *ev = static_cast<QMouseEvent*>(event); QString str = QString("In event filter: mouse pressed! x = %1 y = %2").arg(ev->x()).arg(ev->y()); qDebug() << str; return true; } } return QWidget::eventFilter(watched, event); }
|