I'm developing a simple QML application right now and I noticed that resizing and moving a QML window generates an ugly flicker compared to a QtWidgets window, for instance.
So I created 2 test applications to show the difference:
QWidgets:
QML:
As you can see the QML version of the application flickers pretty ugly while the QtWidgets one is clean. Now this gets pretty ugly when your UI grows in complexity.
Do you have any knowledge about this? Is this a bug? Is there any fix/workaround for this issue?
You can try this:
int main(int argc, char* argv[]) {
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
or
QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
The first option uses OpenGl2DirecX angle library (like Google Chrome)
The second one uses OpenGL emulation by software... for small programs work very good and is 100% compatible with old OS like Windows XP.
Note: You can try with Qt 5.7 and new Qtquick.Controls 2.0 ...performs much better...
https://blog.qt.io/blog/2016/06/10/qt-quick-controls-2-0-a-new-beginning/
The issue with resizing of QML apps is about updating a window with outdated geometry. The fix would be to sync the updates and resizing.
Since there might be sudden updates from update timer to render scene graph, which can update the window at any time, it causes drawing of the content with outdated geometry.
https://bugreports.qt.io/browse/QTBUG-46074
Either Basic or Extended synchronization should be used to synchronize resizing and the window updates.
Currently Basic sync is used and implemented in Qt, but still need to synchronize the window updates (from timer) with resizing events from Windows Manager.
But, as always, there is a list of issues:
The problem is observed when the window is being resizing too fast.
Since sync events (from WM) should be sent consistently, next after previous:
<= _NET_WM_SYNC_REQUEST is sent from WM, the size is changing now.
_NET_WM_SYNC_REQUEST is received and handled by app.
<= some other events received, like new geometry.
.. update the content, swapBuffers.
=> Sent _NET_WM_SYNC_REQUEST_COUNTER back to WM.
<= _NET_WM_SYNC_REQUEST is sent again from WM, the size is changing.
.. swapBuffers // here is the problem, the update is performed when the window is being changing its geometry.
_NET_WM_SYNC_REQUEST received and handled again.
So the issue happens when (7) swapBuffers appears after _NET_WM_SYNC_REQUEST is sent but not received/processed yet.
And finally conclusion:
Actual resizing of the window is started right after _NET_WM_SYNC_REQUEST is sent by The Window Manager. And not when the app receives it. The window could be even updated at this time, when sync request is sent, but not handled by the app yet. Which will draw the content with outdated geometry.
_NET_WM_FRAME_DRAWN could help to sync between resizing and updates, but also might not be supported (and guess it is not) by The Window Manager.
In other words, either basic or extended synchronization does not help, (at least without _NET_WM_FRAME_DRAWN), because there is no way to know when actual resizing is done.
Extended sync protocol is a try to handle this, but since actual changing of geometry is done without syncing with the client, as I can see, without _NET_WM_FRAME_DRAWN there is always a chance to update the window with outdated geometry.
https://lists.freedesktop.org/archives/xcb/2019-February/011280.html
In my case, i solved this by adding the next flag:
QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);
But this will add other rendering problems. Or not.
In golang therecipe/qt this help me :
func main() {
var format = gui.NewQSurfaceFormat()
format.SetVersion(4, 5)
format.SetProfile(gui.QSurfaceFormat__CoreProfile)
format.SetRenderableType(gui.QSurfaceFormat__OpenGL)
format.SetSwapInterval(0)
format.SetDefaultFormat(format)
os.Setenv("QT_SCALE_FACTOR", "1")
ap := widgets.NewQApplication(len(os.Args), os.Args)
ap.SetApplicationName("APP 1.1")
System: Linux debian 10
gpu: Radeon 570
but the animations are faster because not all frames are rendered...
Related
On Windows, in the display settings I could change the size of the contents of the screen in %.
Now, if the display settings were updated BEFORE launching the GUI, the GUI would look fine.
However, if the display settings were updated WHILE the GUI is open, then all fonts would increase (as expected) in size but the widgets such as push buttons and others would stay the same size (unlike in the previous scenario).
So after some research and thinking, it might make sense to use:
QScreen::logicalDotsPerInchChanged signal to signal that display settings were changed.
Upon receiving this signal, the whole ui window should update all of its widgets to match this new scale % factor.
Btw, this question was asked and solved before in the Qt Forum; however, without showing some implementation as in : here
So my question resides in how can this be implemented:
For number 1: where do I place this signal connection and how can I react to it
For number 2: what is a good way to resize or update widgets without doing so one by one, but rather at the ui window level.
This is QT5. Its on an embedded Yocto system, with QT drawing to the framebuffer, no X11. The problem is this. I want to play a video using gstreamer. So, I tried to launch gstreamer with gst-launch-1.0 linked to a touch event in QT. Problem is, it flickers as QT also tries to render frames.
Next, we tried Q media player. However, this proprietary gstreamer doesn't support playbin, so, I went into QGstreamerPlayerSession and modified the constructor to use gst_parse_launch to set up my pipeline instead of playbin.
This works, in that my video plays. However, there is still the same flickering! I tried to throw up a white rectangle before launching the video, but it still flickers.
How could I prevent QT from redrawing? Do I need an empty scene before playing the video? Or is there a function call to pause redrawing?
I could of course send a SIGSTOP to QT, play the video in an external application, then resume with a SIGCONT. That works, but is obviously a very inelegant and restrictive solution (I need the app to be processing in the background still as its controlling other things as well).
I am using Qt4.8 Windows version to develope an application to stream video using libvlc 2.2.1. When I use libvlc_media_player_set_hwnd() to render the video on my QWidget, its rather creating a separate window to display the video.
libvlc_media_player_set_hwnd(m_player, (void*)videoWidget->winId());
I have tried all versions of libvlc and all the examples related to libvlc with Qt. Also followed the steps given in https://wiki.videolan.org/LibVLC_SampleCode_Qt/
But I am not sure if I m missing anything.
It looks like as if libvlc_media_player_set_hwnd() is not able to take the QWidget WinId and creating its own window. However the value of (void*)videoWidget->winId() seems to be a valid one. (I got the value as 0x65).
Please let me know if I am missing anything.
You need to make sure you are configuring your VLC instance correctly first, so that it uses the dummy interface, for example:
/* Load the VLC engine */
std::vector<const char*> options;
options.push_back("--intf=dummy");
return libvlc_new(int(options.size()), options.data());
Also, are you sure you are passing the handle to the correct widget to render on? Also, make sure to set some size on the parent widget, otherwise you may not see anything render at all. Finally, check what media options you are setting to your media player instance, you may be inadvertently telling it to render to generated window.
I've been able to get VLC to work in my own Qt application using the following example as a starting point, even though it is for VLC 1.X:
LibVLC SampleCode Qt - VideoLAN Wiki
I'm trying to implement a screen dimmer using QT4 and I wanted some advice before I get cracking instead of going into this blindly.
I want to create a top-level window that has no frame. I was thinking of making the background black and messing with the opacity so that it will dim the screen out after the system is idle for a given period of time.
The problem with this is that if this window is always on top, how can I pass click events to the window underneath it? I'm not the least bit familiar with the windows API (the solution only has to work under windows), but I'm guessing that's a good place to start. Can anyone point me to some useful classes/functions or suggest another way of doing this via QT?
If anyone's interested in the solution I came up with and the windows API functions I used, you can check out my blog posting here: http://sarcastichacker.com/getnextwindowandgetforegroundwindow
I will be updating the source and making another related posting on the same blog within the next couple of days.
I'm not having an easy time making a workable mouse pointer interface on the Kindle with Qt (unofficial, of course). The fiveway joystick can't track more than one direction at a time (no diagonal moves), and the screen is too slow to update for good feedback.
I've got limited acceleration, but with the screen delay it's very frustrating to use. When you release the fiveway, the mouse will keep moving for 1-2 seconds... and it's not always a constant delay.
Given these limitations, I really need help from the application side. I need a method the mouse driver plugin could use to identify what the acceleration profile should be... so it can say slow down as it crosses a button. The app could help define regions where different acceleration made sense (start with single pixel shifts in a drawing area, but start at 10 or so for dialog dead space). More simply, the application should be able to tell the mouse pointer to transition from cursor to keypad mode, etc.
However, I can enumerate the mouse drivers, but I don't seem to get driver names. They're not QObjects, so there's no qobject_cast. How can I identify them as mine, and safe to cast to? I can force a cast, but that seems pretty lame.
Do I just assume the plugins are mine and cast them?
I'd like some simple signal/slot way to wire this up.
UPDATE
Maybe the plugins can notify the app somehow. Maybe using QApplication::topLevelWidgets(), trying qobject_cast looking for the QMainWindow... then sending it a custom signal with the plugin's internal QObject-based signal handler class? Then the app could turn around and set up the connections it actually wanted to deal with. I'll try it tonight or tomorrow.
Why don't you implement right as "tab" and left as "shift+tab". That way, you can move the focus around. Now, just center the pointer over the active area of the widget with focus (think checkboxes, they need the pointer over the box, not the center). I expect the user to be more interested in this and actually having a pointer to mover around in an environment where it is down right impossbile to use.