qt卡在消息循环

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了qt卡在消息循环相关的知识,希望对你有一定的参考价值。

参考技术A Qt消息循环,就是从一个队列中不断取出消息,并响应消息的过程。窗体的鼠标、键盘、输入法、绘制,各种消息,都来自于Qt的消息循环。以Windows操作系统为例,Qt接管Windows原生窗口消息,并翻译成Qt的消息,派发给程序下的各个子对象、子QWidget等,通过接管层,可以很好屏蔽不同平台之间的差异性,开发人员不需要关心Windows或者X11的消息的差异性,只需要搞清楚各个QEvent之间是什么含义。

QT CEF3 消息循环处理

初次写博客,可能有点乱, 按照自己的实际经历谈一下CEF3钟遇到的一些坑,希望对以后的小伙有些帮助。

    先说一下经历,当初第一次接触CEF3的时候,没做特殊处理,直接将cef3封装成控件,嵌入到QT程序中,结果QT就响应不了鼠标事件了,后来经过查资料,发现是cef3的事件循环和QT的事件循环冲突了,所以QT处理不了鼠标事件了,就是鼠标只能点击网页有反应,点击QT控件就没反应。

    我们来看一下CEF的消息循环处理机制。cef事件消息循环有两种方式,一种是cef自己处理所有的消息事件(这种情况也就是将cef嵌入到QT中,QT控件都点不动的情况),另一种就是我们程序员手动去处理cef的消息事件(不用怕,这个很简单,就是调用cef的函数就行,具体调用的时机下面会讲到)。这两种消息处理的方式是通过设置

typedef CefStructBase<CefSettingsTraits> CefSettings;
CefSettings.multi_threaded_message_loop = true;//使用CEF3的自动的消息循环处理
// CefSettings.multi_threaded_message_loop = false;//需要程序员手动调用CEF的消息处理函数
// CefDoMessageLoopWork();//手动调用CEF的消息事件处理函数  

  这里要讲一下手动调用cef事件处理函数的时机。一般情况下我们执行一次CefDoMessageLoopWork();是能处理一次事件循环,所以我们最好设置个定时器,每隔一段时间主动触发一下CefDoMessageLoopWork();
具体每隔多久触发一下这个值得商榷,如果间隔很小,处理的太频繁,对于资源浪费比较严重。但是如果间隔时间太久的话,会造成处理线程饿死。 我一般使用的都是10ms主动触发一下执行事件循环的函数。

  所以结果就是程序刚一开始执行的时候,我们打开 定时器,程序关闭的时候关闭定时器,定时器间隔设置为10ms,槽函数就是CefDoMessageLoopWork();

好了,下面贴出来cef消息事件循环的类。

#ifndef WEBMESSAGEHELPER_H
#define WEBMESSAGEHELPER_H

#include <QObject>

class QTimer;
class WebMessageHelper : public QObject
{
Q_OBJECT
public:
static WebMessageHelper* instance();
void postMessage(qint64 delay_ms);

void start();
void stop();

private:
explicit WebMessageHelper(QObject *parent = 0);
signals:
void newMessage();
private slots:
void doWork();
private:
QTimer* mTimer;
static const int MESSGET_INTERVAL = 10;
};

#endif // WEBMESSAGEHELPER_H

 

 

#include "webmessagehelper.h"
#include "include/cef_app.h"
#include <QTimer>

WebMessageHelper::WebMessageHelper(QObject *parent)
:QObject(parent)
{
mTimer = new QTimer(this);
mTimer->setInterval(MESSGET_INTERVAL);
mTimer->setSingleShot(false);
connect(mTimer, &QTimer::timeout, this, &WebMessageHelper::doWork, Qt::QueuedConnection);
connect(this, &WebMessageHelper::newMessage, this, &WebMessageHelper::doWork, Qt::QueuedConnection);
}

WebMessageHelper* WebMessageHelper::instance()
{
static WebMessageHelper helper;
return &helper;
}

void WebMessageHelper::doWork()
{
CefDoMessageLoopWork();
}

void WebMessageHelper::postMessage(qint64 delay_ms)
{
if(delay_ms > 0)
{
delay_ms = delay_ms > 20 ? 20 : delay_ms;
QTimer::singleShot(delay_ms, this, &WebMessageHelper::newMessage);
}
else
{
emit newMessage();
}
}

void WebMessageHelper::start()
{
mTimer->start();
}

void WebMessageHelper::stop()
{
mTimer->stop();
}

---------------------
作者:漫步繁华街
原文:https://blog.csdn.net/xiezhongyuan07/article/details/79237124




以上是关于qt卡在消息循环的主要内容,如果未能解决你的问题,请参考以下文章

2020-11-20 Qt事件循环

QT中|Qt::Tool类型窗口自动退出消息循环问题解决(setQuitOnLastWindowClosed必须设置为false,最后一个窗口不显示的时候,程序会退出消息循环)

QT CEF3 消息循环处理

Qt for windows消息循环libqxt分析和wince快捷键处理

事件循环和线程没有必然关系(就像Windows子线程默认没有消息循环一样),模态对话框和事件循环也没有必然关系(QWidget直接就可以)

Qt回调函数