环境:Ubuntu,Qt Creator
在我的Qt应用程序中,我发现有时Qt不会立即响应我的按键事件,但如果我等了一会儿,它最终会响应。
我认为有些事情阻碍了用户界面。
据我所知,如果Qt的组件(QWidget
等)被销毁,Qt UI将被阻止。我检查了我的代码,当我按下向上/向下键时没有任何组件被销毁。
我真的想知道有没有其他东西可以阻止Qt UI。
{
...
connect(webViewWidget, SIGNAL(loadfinished()), this, SLOT(addItem()));
...
}
void addItem()
{
delete webViewWidget; // will this delete block UI?
mListWidget = new ScrollWidget();
mScrollArea = new ScrollArea(this);
for(int i=0; i<Datalen; i++)
{
mListWidget->addSubItem(itemWidget);
}
}
void keyPressEvent(QKeyEvent *event)
{
switch(event->key)
{
case UP_KEY:
scroll up;
break;
case DOWN_KEY:
scroll down;
break;
default:
break;
}
}
答案 0 :(得分:1)
通常,在处理按键之前放入应用程序事件队列的所有其他事件之前,不会处理您的按键事件。
因此,它可能是任何尚未完成处理的事件。也许你可以弄清楚是否有任何事件,例如通过使用QApplication::hasPendingEvents或继承QApplication并在添加或完全处理事件时添加调试输出。
答案 1 :(得分:0)
除非你在析构函数中做了很多工作,否则破坏对象通常不是问题。销毁webview可能需要很长时间。你可能不应该像你一样摧毁它。删除的工具(请参阅下面的代码)并查看需要多长时间。
您自己的代码可能正在调用阻止的API。你在打电话给任何第三方图书馆吗?你在Qt自己的API中调用任何wait...
方法吗?
如果您不确定,可以检测每个插槽和每个重新实现的虚拟方法,例如xxxEvent(...)
。您需要设置仅插槽并重新实现QObject / QWidget方法,而不是代码中的每个方法。
您可能会产生一个事件风暴,可能是通过在循环中发布大量事件,或者通过发送大量信号连接到通过Qt::QueuedConnection
连接的插槽。例如,请确保您未在repaint()
内拨打paintEvent()
。
下面的仪器示例使用RAII,非常容易应用。或者,您可以使用分析器。
#include <QElapsedTimer>
#define INSTRUMENT() Instrument instr__ument(__FUNCTION__)
#define INSTRUMENTLIM(lim) Instrument instr__ument(__FUNCTION__, (lim))
class Instrument {
QElapsedTimer timer;
int limit;
const char * function;
public:
Instrument(const char * name, int timeLimitMs = 20) :
function(name), limit(timeLimitMs) { timer.start(); }
~Instrument() {
if (timer.elapsed() > limit) {
qDebug("%s was slow, took %d ms", function, timer.elapsed());
}
}
}
void slot(...)
{
INSTRUMENT();
...
}
void addItem()
{
INSTRUMENT();
delete webViewWidget; // will this delete block UI?
mListWidget = new ScrollWidget();
mScrollArea = new ScrollArea(this);
for(int i=0; i<Datalen; i++)
{
mListWidget->addSubItem(itemWidget);
}
}