安徽省建设干校网站多国语言网站建设

当前位置: 首页 > news >正文

安徽省建设干校网站,多国语言网站建设,wordpress签到积分商城,建设部注册中心网站Qt事件系统 day7 事件系统 在Qt中#xff0c;事件是派生自抽象QEvent类的对象#xff0c;它表示应用程序内发生的事情或应用程序需要知道的外部活动的结果。事件可以由QObject子类的任何实例接收和处理#xff0c;但它们与小部件尤其相关。Qt程序需要在main()函数创建一个…Qt事件系统 day7 事件系统 在Qt中事件是派生自抽象QEvent类的对象它表示应用程序内发生的事情或应用程序需要知道的外部活动的结果。事件可以由QObject子类的任何实例接收和处理但它们与小部件尤其相关。Qt程序需要在main()函数创建一个QApplication对象然后调用它的exec()函数。这个函数就是开始Qt的事件循环。在执行exec()函数之后程序将进入事件循环来监听应用程序的事件当事件发生时Qt将创建一个事件对象。当事件发生时Qt通过构造适当的QEvent子类的实例来创建一个事件对象来表示它并通过调用它的event()函数将它交付给QObject的一个特定实例(或它的一个子类)。这个函数event()不处理事件本身根据交付的事件类型它为该特定类型的事件调用事件处理程序并根据事件是被接受还是被忽略发送响应。一些事件如QMouseEvent和QKeyEvent来自窗口系统还有一些比如QTimerEvent来自其他来源有些来自应用程序本身。 事件处理 传递事件的通常方式是调用虚函数 自定义处理了按钮控件左键单击想要让父类也能够处理左键消息可以把父类的mousePressEvent放在最后调用(不放在else中) #include QApplication #include QWidget #include QPushButton #include QMouseEvent class Button :public QPushButton { public:Button(QWidget* parent nullptr) :QPushButton(parent){} protected://重写了父类的虚函数也就是不再使用父类的实现由自己来实现//但是按钮的点击信号是在mousePressEvent函数里面触发的void mousePressEvent(QMouseEvent* ev) override{if (ev-button() Qt::MouseButton::LeftButton){qDebug() 按下小瓜;}//所以写完实现后剩下的要交给父类处理QPushButton::mousePressEvent(ev);} }; class Widget :public QWidget { public:Widget(QWidget* parent nullptr) :QWidget(parent){auto btn new Button(this);btn-setText(小瓜);connect(btn, Button::clicked,this, {qDebug() 小瓜瓜;});}//处理鼠标点击事件重写虚函数即可void mousePressEvent(QMouseEvent* ev) override{//判断那个键按下if (ev-button() Qt::MouseButton::LeftButton){//pos是程序的客户区坐标globalPos是基于整个屏幕所在的坐标位qDebug() leftButton Press ev-pos() ev-globalPos();}}};int main(int argc, char* argv[]) {QApplication a(argc, argv);Widget w;w.setWindowIcon(QIcon(:/Resource/tubiao.ico));w.show();return a.exec(); } #include main.moc运行结果
鼠标事件 鼠标按下 void CustomButton::mousePressEvent(QMouseEvent* ev)override {//获取鼠标按键 类型为枚举:Qt::MouseButton::qDebug() ev-button();//如果同时有多个鼠标按键按下,需要判断左键是否按下qDebug() (ev-buttons() Qt::MouseButton::LeftButton);//获取鼠标坐标 position()返回浮点坐标可以使用pos()获取整型坐标qDebug() ev-position(); //鼠标在本控件上的坐标qDebug() ev-scenePosition(); //鼠标在本控件所在的窗口位置qDebug() ev-globalPosition(); //鼠标相对于屏幕的坐标//将其他按键传递给基类处理QPushButton::mousePressEvent(ev); }鼠标释放 void CustomButton::mouseReleaseEvent(QMouseEvent*ev)override {QPushButton::mouseReleaseEvent(ev); }鼠标双击 void CustomButton::mouseDoubleClickEvent(QMouseEventev)override {qDebug() 小瓜; }鼠标移动如果关闭了鼠标跟踪则只有在移动鼠标时按下鼠标按钮时才会发生鼠标移动事件。如果打开了鼠标跟踪即使没有按下鼠标按钮也会发生鼠标移动事件。按钮是自动追踪鼠标的但是QWidget是不会的如果要给QWidget的子类重写鼠标移动需要使用 void setMouseTracking(bool enable)启用鼠标追踪。 void CustomButton::mouseMoveEvent(QMouseEvent ev)override {qDebug() 鼠标移动的坐标位 ev-pos(); }鼠标滚轮返回轮子旋转的相对量单位为八分之一度。正值表示转轮向前旋转远离用户负值表示转轮向后向用户旋转。angleDelta().y()提供自上一个事件以来旋转普通垂直鼠标滚轮的角度。如果鼠标有水平滚轮angleDelta().x()提供水平鼠标滚轮旋转的角度否则就是0。有些鼠标允许用户倾斜滚轮来进行水平滚动有些触摸板支持水平滚动手势它也会出现在angleDelta().x()中。大多数鼠标类型的工作步长为15度在这种情况下delta值是120的倍数即120单位* 18 15度。然而有些鼠标的滚轮分辨率更高发送的delta值小于120单位(小于15度)。为了支持这种可能性可以累计添加来自事件的增量值直到达到120的值然后滚动小部件或者可以部分滚动小部件以响应每个轮事件 void CustomButton::wheelEvent(QWheelEvent* ev)override {//获取滚轮滚动方向QPoint numDegrees ev-angleDelta();qDebug() 水平: numDegrees.x()/8 垂直: numDegrees.y()/8; }#include QApplication #include QWidget #include QPushButton #include QMouseEvent class Button :public QPushButton { public:Button(QWidget* parent nullptr) :QPushButton(parent){} protected://重写了父类的虚函数也就是不再使用父类的实现由自己来实现//但是按钮的点击信号是在mousePressEvent函数里面触发的void mousePressEvent(QMouseEvent* ev) override{if (ev-button() Qt::MouseButton::LeftButton){qDebug() 按下小瓜;}//所以写完实现后剩下的要交给父类处理QPushButton::mousePressEvent(ev);} }; class Widget :public QWidget { public:Widget(QWidget* parent nullptr) :QWidget(parent){auto btn new Button(this);btn-setText(小瓜);connect(btn, Button::clicked,this, {qDebug() 小瓜瓜;});//设置鼠标追踪不需要的情况就不要用会降低效率//setMouseTracking(true);}//处理鼠标点击事件重写虚函数即可void mousePressEvent(QMouseEvent* ev) override{//判断那个键按下if (ev-button() Qt::MouseButton::LeftButton){//pos是程序的客户区坐标globalPos是基于整个屏幕所在的坐标位qDebug() leftButton Press ev-pos() ev-globalPos();isPress true;}}//鼠标放开void mouseReleaseEvent(QMouseEvent* ev) override{if (ev-button() Qt::MouseButton::LeftButton){isPress false;}}//移动鼠标void mouseMoveEvent(QMouseEvent* ev) override{//鼠标左键按下并且移动了鼠标实现这个要开启鼠标追踪if (isPress){qDebug() 左键按下也移动的鼠标;}//buttons判断鼠标按下后还做了别的事情if(ev-buttons() Qt::MouseButton::RightButton){qDebug() 移动了鼠标并且按了右击;}}//双击void mouseDoubleClickEvent(QMouseEvent* ev) override{qDebug() 双击;}//滚轮void wheelEvent(QWheelEvent* ev) override{//判断滚轮的方向qDebug() ev-angleDelta().y() ev-angleDelta().x();} private:bool isPress false;};int main(int argc, char* argv[]) {QApplication a(argc, argv);Widget w;w.setWindowIcon(QIcon(:/Resource/tubiao.ico));w.show();return a.exec(); } #include main.moc运行结果
按键事件 #include QApplication #include QWidget #include QPushButton #include QMouseEventclass Widget :public QWidget { public:Widget(QWidget* parent nullptr) :QWidget(parent){//遍历Qt中的所有快捷键for (size_t i 0; i 70; i){qDebug() i —– QKeySequence::StandardKey(i) —— QKeySequence::keyBindings(QKeySequence::StandardKey(i));}}//按键事件void keyPressEvent(QKeyEvent* ev) override{//当前是什么键按下qDebug() Qt::Key(ev-key());//描述键 ctrl alt shift键等等//ctrlAif (ev-modifiers() Qt::KeyboardModifier::ControlModifier ev-key() Qt::Key_A){qDebug() 全选;}//matches匹配if (ev-matches(QKeySequence::StandardKey::Save)){qDebug() 保存;}}//按键放开事件void keyReleaseEvent(QKeyEvent* ev) override{} private: };int main(int argc, char* argv[]) {QApplication a(argc, argv);Widget w;w.setWindowIcon(QIcon(:/Resource/tubiao.ico));w.show();return a.exec(); } #include main.moc运行结果
窗口关闭事件、大小改变、其他事件处理 窗口关闭 当Qt从窗口系统接收到一个顶级小部件的窗口关闭请求时将用给定的事件调用此事件处理程序。默认情况下接受事件并关闭小部件。您可以重新实现此函数以更改小部件响应窗口关闭请求的方式。例如您可以通过在所有事件上调用ignore()来防止窗口关闭。主窗口应用程序通常使用该函数的重新实现来检查用户的工作是否已保存并在关闭前请求权限。
void Widget::closeEvent(QCloseEvent* ev)override {auto ret QMessageBox::question(this, 温馨提示, 你有未保存的操作是否保存并关闭);if (ret QMessageBox::StandardButton::Yes){//保存并关闭ev-accept();//ev-setAccepted(true);}else{//不保存也不关闭ev-ignore();//ev-setAccepted(false);} }窗口隐藏、显示 除隐藏和显示窗口外窗口最小化会发送窗口隐藏事件正常显示会发送窗口显示事件。
void Widget::showEvent(QShowEvent* ev)override {qInfo() 我显示啦; } void Widget::hideEvent(QHideEvent* ev)override {qInfo() 我隐藏啦; } 窗口移动 void Widget::moveEvent(QMoveEvent* ev)override {qInfo() Widget moved oldPos ev-oldPos() newPos ev-pos(); }窗口大小改变 void Widget::resizeEvent(QResizeEvent* ev)override {qInfo() Widget SizeChanged oldSize ev-oldSize() newSize ev-size(); }程序状态改变 如果需要检测程序中某些东西是否发生了改变可以通过void QWidget::changeEvent(QEvent event)来检测。 以下是常用事件 QEvent::FontChangeQEvent::WindowTitleChangeQEvent::IconTextChangeQEvent::ModifiedChangeQEvent::MouseTrackingChangeQEvent::WindowStateChange
#include QApplication #include QWidget #include QPushButton #include QMouseEvent #include QMessageBox class Widget :public QWidget {Q_OBJECT public:Widget(QWidget
parent nullptr) :QWidget(parent), btn(new QPushButton(更改标题, this)){resize(400, 400);btn-setFixedSize(100, 100);connect(btn, QPushButton::clicked, this, {setWindowTitle(小瓜瓜);});}//窗口关闭事件void closeEvent(QCloseEvent* ev) override{auto ret QMessageBox::question(this, 关闭窗口, 是否保存);if (ret QMessageBox::StandardButton::Yes){//接收事件ev-accept();}else{//忽略事件ev-ignore();}}//当窗口大小改变的时候会调用void resizeEvent(QResizeEvent* ev) override{//这样窗口大小改变的时候按钮也会跟着变btn-move(ev-size().width() - btn-width(), 0);}void changeEvent(QEvent* ev) override{switch (ev-type()){case QEvent::Type::WindowTitleChange:qDebug() 改变标题 this-windowTitle(); break;}} private:QPushButton* btn{}; };int main(int argc, char* argv[]) {QApplication a(argc, argv);Widget w;w.setWindowIcon(QIcon(:/Resource/tubiao.ico));w.show();return a.exec(); } #include main.moc运行结果
定时器 有两种定时器定时器周期性处理因为在Qt中不能写死循环不然会导致主程序的阻塞第一种是QTimer #include QApplication #include QWidget #include QPushButton #include QMouseEvent #include QMessageBox #include QTimer class Widget :public QWidget {Q_OBJECT public:Widget(QWidget* parent nullptr) :QWidget(parent) {//两种定时器//1.QTimerauto timer new QTimer(this);//最简单的调用使用lambda表达式/timer-callOnTimeout({qDebug() upData;});/timer-callOnTimeout(this, Widget::game_upData);//发送信号到槽函数connect(timer, QTimer::timeout, this, Widget::game_upData);//开启定时器,60帧速度timer-start(100060);//QTimer的静态成员这个示例在1000毫秒后只会触发一次QTimer::singleShot(1000, {qDebug() 只触发一次;});}void game_upData(){qDebug() FUNCTION;} private:};int main(int argc, char* argv[]) {QApplication a(argc, argv);Widget w;w.setWindowIcon(QIcon(:/Resource/tubiao.ico));w.show();return a.exec(); } #include main.moc运行结果 第二种定时器事件只要在QOBject的子类里面就可以重写定时器事件 #include QApplication #include QWidget #include QPushButton #include QMouseEvent #include QMessageBox #include QTimer class Widget :public QWidget {Q_OBJECT public:Widget(QWidget* parent nullptr) :QWidget(parent){//开启定时器timer_idOne startTimer(500);timer_idTow startTimer(200);}//定时器事件void timerEvent(QTimerEvent* ev) override{static int i 0;//当i为6的时候杀死定时器if (i 6){killTimer(timer_idOne);killTimer(timer_idTow);//killTimer(ev-timerId());}if (ev-timerId() timer_idOne){qDebug() timer_idOne;}else if (ev-timerId() timer_idTow){qDebug() timer_idTow;}i;}private://timer的id接收变量int timer_idOne;int timer_idTow; };int main(int argc, char* argv[]) {QApplication a(argc, argv);Widget w;w.setWindowIcon(QIcon(:/Resource/tubiao.ico));w.show();return a.exec(); } #include main.moc运行结果
自定义事件的发送与处理 事件分发函数 传递事件通常方式是调用虚函数如果在虚函实现中不执行必要的工作则可能需要调用基类的实现如果希望替换基类的事件处理函数则必须自己实现所有的内容实现自己所需的功能后可以调用基类来获得不想处理的任何情况的默认行为 #include QApplication #include QWidget #include QPushButton #include QMouseEvent #include QMessageBox #include QTimer class Widget :public QWidget {Q_OBJECT public:Widget(QWidget* parent nullptr) :QWidget(parent){}//所有的事件处理函数都是从event()事件派发函数调用的bool event(QEvent* ev) override{switch (ev-type()){//实现自己需要的事件操作case QEvent::MouseButtonPress:mousePressEvent(dynamic_castQMouseEvent(ev)); break;default:break;}//最后交给父类去处理return QWidget::event(ev);}void mousePressEvent(QMouseEvent ev) override{qDebug() ev-button();} private:};int main(int argc, char* argv[]) {QApplication a(argc, argv);Widget w;w.setWindowIcon(QIcon(:/Resource/tubiao.ico));w.show();return a.exec(); } #include main.moc运行结果
发送事件 自定义事件创建与发送通过构造合适的事件对象并进行使用sendEvent()立即处理事件。当它返回时事件过滤器或对象本身已经处理了该事件对于许多事件类。都有一个名为isAccept()的函数它会告诉事件是被最后一个调用的处理程序接受还是拒绝postEvent()将事件发送到队列中以便进行分派。它会分发所有发布的事件。用户自定义的类型必须要在这个区间里
#include QApplication #include QWidget #include QPushButton #include QMouseEvent #include QMessageBox #include QTimer //自定义事件 class CustomEvent :public QEvent { public:enum Type { custom QEvent::User };CustomEvent(const QString data) :QEvent(static_castQEvent::Type(custom)),m_data(data){}//析构函数~CustomEvent(){qDebug() FUNCTION;}//提供接口QString data() const{return m_data;} protected:QString m_data; }; class Widget :public QWidget {Q_OBJECT public:Widget(QWidget* parent nullptr) :QWidget(parent){}void mousePressEvent(QMouseEvent* ev) override{if (ev-button() Qt::RightButton){//向指定的对象发送事件//1.sendEvent 发送栈区的事件直到事件处理或完成之后才会返回(表明sendEvent函数是阻塞的)//如果申请内存放在堆区就不会自动释放需要自己所手动释放//CustomEvent ev(小瓜 sendEvetn customEvent);//QApplication::sendEvent(this, ev);//2.postEvent 只能发送堆区的对象。一旦发送直接返回不需要等事件处理完成,一旦事件处理完成会自动释放CustomEvent* ev new CustomEvent(小瓜瓜);QApplication::postEvent(this, ev);}}//处理自定义事件函数void customEvent(QEvent* ev) override{if (ev-type() CustomEvent::custom){auto cev dynamic_castCustomEvent(ev);if (cev){qDebug() cev-data();}}} private: };int main(int argc, char argv[]) {QApplication a(argc, argv);Widget w;w.setWindowIcon(QIcon(:/Resource/tubiao.ico));w.show();return a.exec(); } #include main.moc运行结果