I have a QChart in my application that receives information in real time.
The chart is also scrolling to the left every 100 millisecond with the help of a timer. This chart works well but the problem is that in two minutes, my application is taking all ressources from my CPU and my computer becomes very slow.
Does anyone already had this problem and how did you solve it ?
Related
the MFC application I'm currently working on is a little hobby project, supposed to look like the green code rain from the movie Matrix. My application has the window divided into thousands of little squares, each holding a letter and each of which might need a redraw to the screen after 25 milliseconds (one frame). Currently, I tried to do this with CClientDC::TextOutW. However, depending on how many of the tiles need an update, calling TextOutW for all the necessary tiles might take anywhere from 30 to 75 milliseconds, which is obviously way too long. The output looked great, but it was just progressing too slowly.
Then I tried to use some multithreading to do the redrawing, but for that, each thread needed access to the screen. I couldn't find any documentation on whether a CClientDC can be used by multiple threads or if multiple threads can have several CClientDCs at once, writing to the same device. The multithreaded apllication I wrote compiles and runs, but the output looks pretty garbled.
I might have made a mistake somewhere (I'm not that well-experienced with multithreading yet), but then again, I might be trying to push butter through stone here. Can anyone tell me if what I'm trying to do with the CClientDC is even possible?
If multithreaded output to the screen via CClientDC is not possible, does anyone have another idea how I could output about 2000 letters on different positions onto the screen in the timespan of 20 milliseconds?
Thanks in advance!
I'm writing a C++ application whose main window needs to receive real-time data from a server and draw plots and histograms in realtime based on this data. I'm using GTK3 (actually its C++ binding gtkmm) and Cairo.
In particular, data is received every 1 second from the network, and refresh happens every time the data is received, thus every 1 second. Refresh is done by calling the invalidate_rect() method for the entire drawing area, whose on_draw() even redraws all figures and plots using the newly received data.
Now, the application works but it's extremely unreliable. In particular, it freezes very often, especially when the CPU load increases. The CPU usage of my application, as well as memory, are very low. Suddenly the window becomes grey and unresponsive, and I need to kill it with Ctrl-C, since even pressing the window close icon doesn't work.
I'm wondering: is it the wrong approach to call invalidate_rect() in the scenario above? What is a better way, using GTKMM/Cairo, to obtain smooth graphics in a reliable way?
I am working on a Qt project in which exact time at which certain events occur is of prime importance. To be specific: I have a very simple animation that must be drawn to the screen at certain time say t1. Once I issue the QWidget update to start the animation, it will take a small time dt (depending on screen refresh rates etc.) to actually show the update on screen. I need to measure this extra time dt. I am unsure as to how to do it.
I thought of using QTime and QElapsedTimer object in the paint event of the QWidget but I'm not sure if that would achieve my goal.
Similarly, when the user presses a key it will be registered after a small delay based on the polling rate of the keyboard. I need to account for this delay as well. If I could get the polling rate I know on average how much will the delay be.
What you're asking for is--by definition--not possible from within the computer.
How would you expect to be able to tell when a pixel "actually showed up" on the screen, without a sensor stuck to the monitor and synchronized to an atomic clock the computer has access to also? :-)
The odds are stacked even further against Qt because it's generally used as an abstraction layer on top of Win/OSX/Linux. Those weren't Real-Time Operating Systems of any kind in the first place.
All you can know is when you asked for something to happen. Then you can time how long it takes for you to get back control to make another request. You can set some expectations on your basic "frame rate" throughput by doing this, but there are countless factors that could lead to wide variations in performance at any moment in time.
If you can dig through to the kernel/driver level you can find out a closer-to-the-metal measure of when the actual effect went to the hardware. But that's not Qt's domain, and still doesn't tell you the "actual" answer of when the effect manifested in the outside world.
About the best you're going to get out of Qt is a periodic QTimer. It can make a callback at (roughly) millisecond resolution. If that's not good enough... you're going to need a smaller boat. :-)
You might get a little boost from stuff related to the search term "high resolution timer":
Qt high-resolution timer
http://qt-project.org/forums/viewthread/31941
I thought of using QTime and QElapsedTimer object in the paint event of the QWidget but I'm not sure if that would achieve my goal.
This is, in fact, the only way to do it, and is all you can actually do. There is nothing further that can be done without resorting to a real-time operating system, custom drivers, or external hardware.
You may not need both - the QElapsedTimer measuring the time passed since the last update is sufficient.
Do note that when the event loop is empty, the delay between invocation of widget.update() and the paintEvent executing is under a microsecond, assuming that your process wasn't preempted.
it is a reaction time experiment for some studies. A visual input is presented to which the user responds via keyboard or mouse. To be able to find the reaction time precisely I need to know when was the stimulus presented on the screen and when was the key pressed.
There is essentially only one way of doing it right without resorting to a realtime operating system or a custom driver, and a whole lot of ways of doing it wrong. So, what's the right way?
A small area of the screen needs to change color or brightness coincidentally with the presentation of the visual stimulus. You attach a fiber optic to the screen, and feed it into a receiver attached to an external event timer. The contact closure in the keyboard is also fed to the same event timer. This lets you precisely time the latency of the response with no regard for operating system latencies, thread preemption, etc. The event timer can be something as cheap as an Arduino, if you are willing to do a bit more development work.
If you are showing the stimulus repetitively and need a certain timing between stimulus presentations, you simply repeat the presentation often and collect both response latency and stimulus-to-stimulus timing in your data. You can then discard the presentations that were outside of desired tolerances.
This approach is screen-agnostic and you can use it even on a mobile device, as long as it can somehow interface with your timer hardware. The timer hardware can of course be networked, making interfacing easy.
I have two timers to repaint a QGLWidget and determine the FPS
QObject::connect(&fpsTimer, SIGNAL(timeout()), this, SLOT(updateFps()));
fpsTimer.start(1000);
QObject::connect(&updateTimer, SIGNAL(timeout()), this, SLOT(updatePanel()));
updateTimer.start(0);
void GLPanel::updatePanel()
{
updateBuffers();
updateGL();
frameCount++;
}
I also update the vbos with new data each and every frame.
On my machine with Qt installed I get a consistent 60 FPS since the update timer will fire based off the GUI thread. I have tried setting it to update every 15ms instead of relying on the GUI thread with no luck. On other machines it ramps up to around 1000 FPS.
Another problem I am having is that my points are not drawing correctly on other machines. They are drawn in the wrong place and colors. As to whether this is related to Qt or OpenGL...?
Any ideas on what would cause this?
Other machines after clicking in the middle of the screen
Other machines
Working Dev Machine after clicking on a point
Working Dev Machine
They are both supposed to look exactly the same.
Your drawing timer is using interval of 0 ms. So the program tries to draw as fast as possible. That's why the other computers have very high frame rates. Your computer is most probably using the display driver's vsync setting. Vsync will synchronize the drawing to the refresh rate of the monitor, that's why the 60 Hz framerate. So you can limit the other computers' frame rate to 60 by using the vsync setting.
However, some old and cheap display cards do not support the vsync at all. Then you need to change the timer's interval, for example to 15 ms. It won't produce as good results as vsync, but it is much better than drawing at 1000 Hz.
I created a widget that serves as some kind of popup window und hence should have a drop shadow all around to optically raise it from the background. I initialize the drop shadow effect in the constructor of my popup widget as follows:
dropshadow = new QGraphicsDropShadowEffect(this);
dropshadow->setBlurRadius(32);
dropshadow->setColor(QColor("#121212"));
dropshadow->setOffset(0,0);
setGraphicsEffect(dropshadow);
The application runs on an embedded system with an Intel Atom CPU, a custom Linux distribution, Qt v4.7.3 running with a qws server. When I disable the drop shadow, my cpu usage is less than 10% when the GUI is idle. Enabling the drop shadow raises the cpu usage to more than 80%. Profiling the app shows that most of the CPU time is spent within libQtGui.so.4.7.3.
Does anyone have an idea why the cpu usage explodes like this even though there is absolutely nothing going on in the GUI, not even mouse movement?
Edit: Changing the size of the popup changes the amount of cpu usage. Reducing the size to a quarter reduces the cpu usage to about a quarter. Very strange.
The problem was only partly with the drop shadow. It seems that repainting a drop shadow requires quite a lot of CPU time - which is OK if it is not redrawn too often. The problem was simple really. The widget that was behind this popup was redrawn four to five times per second and hence, the popup needed to be redrawn, too. This swallowed huge amounts of CPU time. The solution is equally simple: Avoid repaint events if nothing really changes on screen.