C++ QT 重绘/重绘/更新/做点什么
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2052907/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
QT Repaint/Redraw/Update/Do Something
提问by Jason Kotzin
I'm New to QT. I understand that you can force a display refresh, but I've pulled all my hair out trying to figure out how. Here is what I'm specifically trying to do.
我是 QT 的新手。我知道你可以强制刷新显示,但我已经把我所有的头发都拉出来试图弄清楚如何。这是我特别想做的事情。
I press a button (onClick signal event), which runs code that changes an image (QLabel) on the display, waits for input, and then proceeds by changing a new image (different QLabel). I've tried everything and the display doesn't refresh until the onclick signal event code is complete. Right now, I'm not waiting for user input, I'm using usleep(~500 ms) for testing purposes.
我按下一个按钮(onClick 信号事件),它运行代码来更改显示器上的图像 (QLabel),等待输入,然后更改新图像(不同的 QLabel)。我已经尝试了所有方法,并且在 onclick 信号事件代码完成之前显示不会刷新。现在,我不是在等待用户输入,而是使用 usleep(~500 ms) 进行测试。
From what I read, QT is event driven meaning that I'm basically creating a bunch of events, that get put in a que, and executed when the (onClick signal event) returns to the (main loop)/(event handler). I don't want to wait until the function is complete, it's going to make programming extremely painful if I have to accomplish this routine entirely based on events.
从我读到的内容来看,QT 是事件驱动的,这意味着我基本上是在创建一堆事件,这些事件被放入队列中,并在(onClick 信号事件)返回到(主循环)/(事件处理程序)时执行。我不想等到函数完成,如果我必须完全基于事件来完成这个例程,这会让编程变得非常痛苦。
How can I force the QLabel pixmap to refresh. I've tried everything. Below is all the code I have tried in my onClick signal event handler. (upButton is the name of the QLabel which is a pixmap)
如何强制 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);
As you can see, I'm just shooting in the dark at this point. I've tried to look at sample code and do all my homework, but I'm lost. Appreciate any help, advice, and or sample code.
如您所见,此时我只是在黑暗中拍摄。我试图查看示例代码并完成所有功课,但我迷路了。感谢任何帮助、建议和/或示例代码。
回答by Jason Kotzin
I was using sleep to emulate a brief amount of time the computer was waiting for something to happen.
我正在使用睡眠来模拟计算机等待某事发生的短暂时间。
As I stated in my question, I didn't want to use events because it's a whole lot of unnecessary work to accomplish something extremely simply.
正如我在我的问题中所述,我不想使用事件,因为要极其简单地完成某些事情需要进行大量不必要的工作。
Also, the 'event' that needs to take place for the program to continue, is a USB event. Since I'm using an HID class device, there is no way to set an event to happen without a wait loop. USB HID classes don't permit setting interrupts, the OS claims the device.
此外,程序继续需要发生的“事件”是 USB 事件。由于我使用的是 HID 类设备,因此无法在没有等待循环的情况下设置事件发生。USB HID 类不允许设置中断,操作系统声称该设备。
I managed to get the above to work. I walked through the debugger and noticed the display would refresh before the sleep function. Running the program independently, I got random results with the display refreshing 1% of the time. I got rid of the sleep function, and added some other code in it's place to emulate a delay, and it was fine.
我设法让上述工作。我走过调试器并注意到显示会在睡眠功能之前刷新。独立运行程序,我得到了随机结果,显示刷新率为 1%。我摆脱了睡眠功能,并在它的地方添加了一些其他代码来模拟延迟,这很好。
Just for everyone's knowledge, this is possible, it's not forbidden, and it's easy to do with the following:
就大家所知,这是可能的,这不是禁止的,而且很容易做到以下几点:
qApp->processEvents();
qApp is a global external variable in the QApplication header.
qApp 是 QApplication 标头中的全局外部变量。
Because this USB event is making my flow tricky, I stumbled upon the QWaitCondition Class. I was going to start a process waiting for the USB event. I would wait until the process releases the wait condition for my routine to continue.
因为这个 USB 事件使我的流程变得棘手,所以我偶然发现了 QWaitCondition 类。我打算启动一个等待 USB 事件的进程。我会等到进程释放等待条件让我的例程继续。
But if anyone thinks this is a bad idea, please, speak out. I really do appreciate your feedback PiedPiper and Hostile Fork.
但如果有人认为这是一个坏主意,请说出来。我真的很感谢您的反馈 PiedPiper 和 Hostile Fork。
Thank you.
谢谢你。
回答by PiedPiper
You shouldn't be waiting for input in your event handler. You need to rethink the logic of your program to use events the way they were intended. All the update() and repaint() calls in your code are unnecessary if you return to the event loop.
您不应该在事件处理程序中等待输入。您需要重新考虑程序的逻辑,以按预期方式使用事件。如果您返回到事件循环,则代码中的所有 update() 和 repaint() 调用都是不必要的。
回答by Goddard
I noticed sometimes when you have multiple layered widgets, or widgets inside of widgets it helps to call their repaint() events.
我注意到有时当您有多层小部件或小部件内的小部件时,它有助于调用它们的 repaint() 事件。
For example
例如
this->repaint();
this->parentWidget()->repaint();
this->parentWidget()->parentWidget()->repaint();
This is far easier then pushing out any processing to another Thread, or creating additional event handlers.
这比将任何处理推送到另一个线程或创建额外的事件处理程序要容易得多。
回答by erelender
If i understood correctly, you have a slot and in this slot, you update the image shown in a QLabel. But you want this change to be displayed before the slot finishes.
如果我理解正确,你有一个插槽,在这个插槽中,你更新 QLabel 中显示的图像。但是您希望在插槽完成之前显示此更改。
If that is the case, issue an update() event, and call qApp->processEvents(). This method processes events that are waiting in the event queue and then returns, therefore this may be what you are after.
如果是这种情况,请发出 update() 事件,并调用 qApp->processEvents()。此方法处理在事件队列中等待的事件然后返回,因此这可能是您所追求的。
PS: an update() may not be necessary at all, i am not sure.
PS:可能根本不需要 update(),我不确定。