好学校平台网站模板下载,野望王绩翻译,wordpress添加og标签,宛城区网站制作第三章Qt事件系统 文章目录 第三章Qt事件系统1.事件系统事件是如何传递的事件类型事件处理发送事件 2.事件传播机制事件接受和忽略事件分发事件过滤 3.事件和信号的区别 1.事件系统
在Qt中#xff0c;事件是派生抽象QEvent类的对象#xff0c;它表示应用程序内发生的事情事件是派生抽象QEvent类的对象它表示应用程序内发生的事情或应用程序需要知道的外部活动的结果。事件可以由QObject子类的任何实例接收和处理。 Qt程序需要在main函数创建一个QApplication对象然后调用它的exec()函数。这个函数就是开始Qt的事件循环。执行后程序将进入事件循环来监听应用程序的事件当事件发生时Qt将创建一个事件对象。
事件是如何传递的 #mermaid-svg-vpLiAJ9GHDFex7Kn {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-vpLiAJ9GHDFex7Kn .error-icon{fill:#552222;}#mermaid-svg-vpLiAJ9GHDFex7Kn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vpLiAJ9GHDFex7Kn .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-vpLiAJ9GHDFex7Kn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vpLiAJ9GHDFex7Kn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vpLiAJ9GHDFex7Kn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vpLiAJ9GHDFex7Kn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vpLiAJ9GHDFex7Kn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vpLiAJ9GHDFex7Kn .marker.cross{stroke:#333333;}#mermaid-svg-vpLiAJ9GHDFex7Kn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vpLiAJ9GHDFex7Kn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-vpLiAJ9GHDFex7Kn .cluster-label text{fill:#333;}#mermaid-svg-vpLiAJ9GHDFex7Kn .cluster-label span{color:#333;}#mermaid-svg-vpLiAJ9GHDFex7Kn .label text,#mermaid-svg-vpLiAJ9GHDFex7Kn span{fill:#333;color:#333;}#mermaid-svg-vpLiAJ9GHDFex7Kn .node rect,#mermaid-svg-vpLiAJ9GHDFex7Kn .node circle,#mermaid-svg-vpLiAJ9GHDFex7Kn .node ellipse,#mermaid-svg-vpLiAJ9GHDFex7Kn .node polygon,#mermaid-svg-vpLiAJ9GHDFex7Kn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-vpLiAJ9GHDFex7Kn .node .label{text-align:center;}#mermaid-svg-vpLiAJ9GHDFex7Kn .node.clickable{cursor:pointer;}#mermaid-svg-vpLiAJ9GHDFex7Kn .arrowheadPath{fill:#333333;}#mermaid-svg-vpLiAJ9GHDFex7Kn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-vpLiAJ9GHDFex7Kn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-vpLiAJ9GHDFex7Kn .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-vpLiAJ9GHDFex7Kn .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-vpLiAJ9GHDFex7Kn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-vpLiAJ9GHDFex7Kn .cluster text{fill:#333;}#mermaid-svg-vpLiAJ9GHDFex7Kn .cluster span{color:#333;}#mermaid-svg-vpLiAJ9GHDFex7Kn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-vpLiAJ9GHDFex7Kn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 通过QCoreApplication::sendEvent()发送事件 用户触发事件 操作系统接收 将事件分发给对应的应用程序 应用程序事件过滤器处理nativeEventFilter() 通过QCoreApplication::postEvent()发送事件 事件队列 事件分发给对应控件QApplication::notify() 控件事件过滤处理QObject::eventFilter() 将事件进行分发QObject::event() 控件处理例如mousePressEvent() 忽略该事件 控件的父级处理 事件类型
#include QWidget
#include QMouseEventclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent nullptr);~Widget();
protected://鼠标事件void mouseDoubleClickEvent(QMouseEvent *)override;void mousePressEvent(QMouseEvent *)override;void mouseReleaseEvent(QMouseEvent *)override;void mouseMoveEvent(QMouseEvent *)override;//按键事件void keyPressEvent(QKeyEvent *)override;void keyReleaseEvent(QKeyEvent * )override;//窗口事件void closeEvent(QCloseEvent *) override;void hideEvent(QHideEvent *)override;void resizeEvent(QResizeEvent *)override;//焦点事件void focusInEvent(QFocusEvent*)override;void focusOutEvent(QFocusEvent*)override ;void contextMenuEvent(QContextMenuEvent*)override;//程序状态改变事件void changeEvent(QEvent*)override;//定时器事件void timerEvent(QTimerEvent*)override;
};
事件处理
#include Widget.h
#include QPushButtonWidget::Widget(QWidget *parent): QWidget(parent)
{this-setMouseTracking(false);//启用鼠标追踪this-setFocus();new QPushButton(按钮,this);this-startTimer(10);//10毫秒
}Widget::~Widget() {}void Widget::mouseDoubleClickEvent(QMouseEvent *)
{qInfo()鼠标双击;
}void Widget::mousePressEvent(QMouseEvent *)
{qInfo()鼠标按下;
}void Widget::mouseReleaseEvent(QMouseEvent *)
{qInfo()鼠标释放;
}void Widget::mouseMoveEvent(QMouseEvent *)
{static int16_t i0;qInfo()鼠标移动i;
}void Widget::keyPressEvent(QKeyEvent *event)
{qInfo()event-text()按键已按下;
}void Widget::keyReleaseEvent(QKeyEvent *event)
{auto kevent-key();qInfo()k按键已弹起;
}void Widget::closeEvent(QCloseEvent *)
{qInfo()窗口关闭;
}void Widget::hideEvent(QHideEvent *)
{qInfo()窗口隐藏;
}void Widget::resizeEvent(QResizeEvent *)
{qInfo()窗口大小改变;
}void Widget::focusInEvent(QFocusEvent *)
{qInfo(有焦点);
}void Widget::focusOutEvent(QFocusEvent *)
{qInfo(失去焦点);
}void Widget::contextMenuEvent(QContextMenuEvent *)
{qInfo()收到信号弹出菜单;
}void Widget::changeEvent(QEvent *e)
{if(e-type()QEvent::WindowStateChange)qInfo()发生改变;
}void Widget::timerEvent(QTimerEvent *)
{static qint32 x0,y 0;this-move(x%600500,y%800);
} bool event(QEvent *event) override;bool Widget::event(QEvent *event)
{if(event-type()QEvent::Type::MouseButtonPress)return true;//屏蔽了MouseButtonPress事件return QWidget::event(event); //把事件交给父类处理
}发送事件
自定义事件
#include QWidget
#include QMouseEvent
#include QEventclass MyCustomEvent:public QEvent
{
public:MyCustomEvent():QEvent(QEvent::Type::User){info 自定义事件;}QString getMessage(){return info;}
private:QString info;
};class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent nullptr);
protected://鼠标事件void mousePressEvent(QMouseEvent *)override;//自定义事件void customEvent(QEvent *event)override;};Widget::Widget(QWidget *parent): QWidget(parent)
{resize(640,480);
}void Widget::mousePressEvent(QMouseEvent *)
{qInfo()鼠标按下;MyCustomEvent* ce new MyCustomEvent;qApp-sendEvent(this,ce);
}void Widget::customEvent(QEvent *event)
{if(event-type()QEvent::User){auto ce dynamic_castMyCustomEvent*(event);if(!ce)return;qInfo()ce-getMessage();}
}sendEvent和postEvent的区别 sendEvent 事件发送后事件不会被删除是分配在栈上的 postEvent 事件必须在堆上分配事件发布后会被删除事件按优先级降序排列。 2.事件传播机制
事件接受和忽略 QEvent()有accept()和ignore()函数 accept,本组处理该事件不会被传递 ignore,不处理交给父处理 事件分发
事件过滤
用事件过滤器实现鼠标拖动无边框窗口案例
#include QWidget
#include QMouseEvent
#include QEvent
#include QPushButtonclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent nullptr);~Widget();
protected://事件过滤处理器bool eventFilter(QObject *watched, QEvent *event)override;
private:QPoint pressPos;#include Widget.h
#include QPushButtonWidget::Widget(QWidget *parent): QWidget(parent)
{resize(640,480);setWindowFlag(Qt::FramelessWindowHint);//设置无边框installEventFilter(this);//在对象上安装事件过滤器如果不装过滤器重写无效
}Widget::~Widget() {}bool Widget::eventFilter(QObject *watched, QEvent *event)
{if(watchedthis){if(event-type()QEvent::MouseButtonPress){auto medynamic_castQMouseEvent*(event);pressPos me-pos();return true;}else if(event-type()QEvent::MouseMove){auto medynamic_castQMouseEvent*(event);move(me-globalPosition().toPoint()-pressPos);//globalPosition是鼠标在全局的位置pressPos是鼠标相对于窗口左上角的位置两者一减就是窗口左上角在全局的位置}elsereturn false;}elsereturn QObject::eventFilter(watched,event);
}};3.事件和信号的区别
事件信号与QObject的关系由具体对象进行处理由具体对象主动产生对程序的影响改写事件处理函数可能导致程序行为发生改变信号是否存在对应的槽函数不会改变程序的行为两者的联系一般而言信号在具体的事件处理函数中产生
信号和事件是两个不同层面的东西发出者不同作用不同。