QT 重绘/重绘/更新/做某事

Posted

技术标签:

【中文标题】QT 重绘/重绘/更新/做某事【英文标题】:QT Repaint/Redraw/Update/Do Something 【发布时间】:2011-01-04 09:43:54 【问题描述】:

我是 QT 的新手。我知道您可以强制刷新显示,但我已经竭尽全力试图弄清楚如何。这是我特别想做的事情。

我按下一个按钮(onClick 信号事件),该按钮运行代码以更改显示器上的图像(QLabel),等待输入,然后继续更改新图像(不同的 QLabel)。我已经尝试了所有方法,并且在 onclick 信号事件代码完成之前显示不会刷新。现在,我不是在等待用户输入,而是使用 usleep(~500 ms) 进行测试。

根据我的阅读,QT 是事件驱动的,这意味着我基本上是在创建一堆事件,这些事件被放入一个队列中,并在(onClick 信号事件)返回到(主循环)/(事件时执行)处理程序)。我不想等到函数完成,如果我必须完全基于事件来完成这个例程,那会让编程变得非常痛苦。

如何强制 QLabel 像素图刷新。我什么都试过了。下面是我在 onClick 信号事件处理程序中尝试过的所有代码。 (upButton 是 QLabel 的名称,它是一个像素图)

update();
repaint();
ui->upButton->setUpdatesEnabled(TRUE);
update();
repaint();
QPaintEvent paintevent(ui->upButton->childrenRegion());
QPaintEvent * test = &paintevent;
paintEvent(test);
this->changeEvent(test);
ui->upButton->update();
ui->upButton->repaint();
ui->upButton->repaint(ui->upButton->childrenRegion());
repaint();
QApplication::sendPostedEvents();
this->parentWidget()->update();
usleep(100000);

如您所见,我现在只是在黑暗中拍摄。我试图查看示例代码并完成所有作业,但我迷路了。感谢任何帮助、建议和/或示例代码。

【问题讨论】:

在事件驱动的 GUI 系统中,您通常不会在回调中“等待输入”。等待输入的状态仅仅意味着你在事件循环中。所以我很困惑为什么你会使用 usleep 来处理任何事情——当你要处理用户输入时,你想调用什么例程?不要担心事件是痛苦的......信号和插槽不会咬人(通常)。 【参考方案1】:

您不应该在事件处理程序中等待输入。您需要重新考虑程序的逻辑,以便按照预期的方式使用事件。如果您返回事件循环,则代码中的所有 update() 和 repaint() 调用都是不必要的。

【讨论】:

【参考方案2】:

我使用睡眠来模拟计算机等待某事发生的短暂时间。

正如我在问题中所说,我不想使用事件,因为要完成一件极其简单的事情是一大堆不必要的工作。

此外,程序继续运行所需的“事件”是 USB 事件。由于我使用的是 HID 类设备,因此无法设置事件在没有等待循环的情况下发生。 USB HID 类不允许设置中断,操作系统声称该设备。

我设法让上述工作。我走过调试器,注意到显示器会在睡眠功能之前刷新。独立运行程序,我得到了随机结果,显示刷新率为 1%。我摆脱了睡眠功能,并在其中添加了一些其他代码来模拟延迟,这很好。

据大家所知,这是可能的,不是禁止的,而且很容易做到以下几点:

qApp->processEvents();

qApp 是 QApplication 标头中的全局外部变量。

因为这个 USB 事件让我的流程变得棘手,所以我偶然发现了 QWaitCondition 类。我打算开始一个等待 USB 事件的进程。我会等到进程释放等待条件,让我的例程继续。

但是,如果有人认为这是一个坏主意,请说出来。非常感谢您的反馈 PiedPiper 和 Hostile Fork。

谢谢。

【讨论】:

这为我省去了很多痛苦。谢谢。【参考方案3】:

如果我理解正确,您有一个插槽,并且在此插槽中,您可以更新 QLabel 中显示的图像。但您希望在广告位结束之前显示此更改。

如果是这种情况,请发出 update() 事件,并调用 qApp->processEvents()。此方法处理在事件队列中等待的事件然后返回,因此这可能是您所追求的。

PS:可能根本不需要 update(),我不确定。

【讨论】:

【参考方案4】:

我注意到有时当您有多个分层小部件或小部件内部的小部件时,调用它们的 repaint() 事件会有所帮助。

例如

this->repaint();
this->parentWidget()->repaint();
this->parentWidget()->parentWidget()->repaint();

这比将任何处理推送到另一个线程或创建额外的事件处理程序要容易得多。

【讨论】:

以上是关于QT 重绘/重绘/更新/做某事的主要内容,如果未能解决你的问题,请参考以下文章

在 QQuickWidget 中更新/重绘仪表

QWidget::repaint:更新进度条时检测到递归重绘

无法在 Qt 应用程序中重绘 matplot

JFrame / JPanel不会更新重绘或重新验证

android涂鸦工具,笔刷的定义,撤销与重绘

小部件不会更新/重绘