Window partially refreshed
-
Hi,
I have two issues that I think are related to each other.
I am developing a Qt Quick application under Windows. I use a QGuiApplication with a QQuickView to display QtQuick items, and it works fine.
Fine except that, when it starts, if another window is opened (in my case a command prompt of another executable that is launched by my application), I have the two following issues:
-
My window gets frozen (its content remains still), until I activate the application window. Then, only the portion that was hidden by the other window starts refreshing normally, the other part of the window remains frozen. After playing around with the window (moving it outside the screen boundaries and bringing it back), it starts refreshing again normally.
-
I would like my application window to be top most (i.e. on top of all other Windows applications), but I can't seem to find a way to do it. All I find refers to using QWidgets or QWidget::createWindowContainer(). So I tried turning my QGuiApplication into a QApplication, but I still got the following error: QWidget: Cannot create a QWidget without QApplication.
I am using Qt 5.4.0.
I think I understand the difference between the two approaches (QApplication vs QGuiApplication), but I can't find a way to make it work using either method.
Any help/explanation/hint will be appreciated.
-
-
Hi,
I can't tell for 1 but for 2: did you check the Qt::WindowStaysOnTopHint flag ? -
That's what I tried, but I face the mentioned error when trying to turn my QQuickViews into QQuickWidgets...
I tried either:
@CQtApplication * pQtApplication = new CQtApplication ( ... );QQuickWidget * view = pQtApplication->CreateWidget(); // returns a new QQuickWidget@
... Or:
@CQtApplication * pQtApplication = new CQtApplication ( ... );QWidget * container = QWidget::createWindowContainer( view );@
But both fail, complaining that "QWidget: Cannot create a QWidget without QApplication".
Of course my CQtApplication class derives from QApplication.
-
Can you show the code of your CQtApplication ?
By the way, why subclass Q(Gui)Application ? It's really rarely a necessity
-
Technically, I don't really need to subclass it. I did it to have a place to centralize my operations linked to the QtApplication, but it does not redefine any of its methods (except the constructor). I just have a few slots/signals defined.
Could this cause issues with the widgets?
-
Can you show its declaration ?
-
@#ifndef QTAPPLICATION_H
#define QTAPPLICATION_H#include <QApplication>
#include <qqmlapplicationengine.h>
#include <QQuickView.h>
#include "QtAdapter.h"
#include "QtTranslationManager.h"
#include "QtThemeManager.h"
#include "ObjectListManager.h"
#include "UIList.h"class CGUIModuleAdapter;
class CLayoutHandler;
class CComponentHandler;
class CBaseHandler;
class HandlerComparer;typedef stdext::hash_map<WORD, CLayoutHandler> LayoutHandlerMap;
typedef std::list<CBaseHandler *> HandlerPropertiesToSet;
typedef stdext::hash_multiset<CLayoutHandler *, HandlerComparer> LayoutsToDraw;
typedef std::list<CBaseHandler *> ComponentsToDraw;
typedef std::list<CLayoutHandler *> LayoutsToDispose;
typedef std::list<CBaseHandler *> ComponentsToDispose;typedef struct
{
LayoutHandlerMap * pLayouts;
HandlerPropertiesToSet * pHandlerPropertiesToSet;
LayoutsToDraw * pLayoutsToDraw;
ComponentsToDraw * pComponentsToDraw;
LayoutsToDispose * pLayoutsToDispose;
ComponentsToDispose * pComponentsToDispose;
} QtSetup;typedef stdext::hash_map<CUString, QQuickItem *, UStringCaseComparerDefault> QuickItemsMap;
class CQtApplication : public QApplication
{
Q_OBJECTpublic:
CQtApplication ( const CUString & local, const CUString & theme, int &argc, char **argv );CQtAdapter & GetQtAdapter ();
QQuickView * GetQtView ();
void SetModule ( CGUIModuleAdapter * pModule );
CGUIModuleAdapter * GetModule ();
void SetView ( QQuickView * pView );CObjectListManager * GetObjectListManager ();
private:
CLogTrace m_trace;
static CLogTrace m_staticTrace;bool m_qtInitialized;
QtSetup * m_pSetup;
CQtAdapter m_qtAdapter;
CGUIModuleAdapter * m_pModule;
QQuickView * m_pView;
CQtTranslationManager m_qtTranslationManager;
CQtThemeManager m_qtThemeManager;CObjectListManager m_objectListManager;
static int Argc;
static void customMessageHandler ( QtMsgType type, const QMessageLogContext &context, const QString &msg );
signals:
void eventSignal ();bool macroListSelectionSignal( QString name, QString key, int action, bool bPressAndHold );
bool macroSelectionSignal ( QString name, QString eventName, bool bPressAndHold );public slots:
void updateSlot ( HANDLE hProcessedEvent );
void configureSlot ( HANDLE hProcessedEvent );
void themeUpdateSlot ( QString theme );
void languageUpdateSlot ( QString language );
void setupSlot ( QtSetup * pSetup );bool macroListSelectionSlot ( CUString & listName, int itemIndex, CUIList::Action action, bool bPressAndHold, bool bFastList );
bool macroSelectionSlot ( CBaseHandler * handler, CUString & buttonName, bool bPressAndHold );
};#endif // QTAPPLICATION_H
@ -
What is CLogTrace ?
-
Do you have any static QWidget ?
-
I will double check but I don't think so.
Could you please provide me with the minimal code that creates an application that displays a topmost window (and gets its view from a QML file)? I will try it here and eventually find the differences that make my code fail...
Thank you.
-
After playing around, I found the way to get my application window topmost.
I changed the way my QML application loads its content by:
- Using a QQmlApplicationEngine instead of a QQuickView to load my main QML file;
- Switching to a Window item (instead of an Item).
This way, I can control the window and apply the Qt::WindowStaysOnTopHint flag on it.
Regarding the refresh issue, I did not find the solution but rather implemented a (dirty) workaround which consists of resetting the window size (width = width + 1; width = width - 1;) as soon as the window's active property changes. This forces the redraw of the entire window. This is not very elegant, but it does the job for now.
-
Hi,
are you using OpenGL or DirectX via ANGLE? Looks like a bug with OpenGL to me. If your environment is configured to support both, OpenGL and ANGLE, you can force your application to use ANGLE by calling
QCoreApplication::setAttribute( Qt::AA_UseOpenGLES );
before instantiating your QApplication.
Cheers!
Wieland -
Hi,
The application runs with ANGLE. OpenGL is not an option, as the hardware that must run the application only supports OpenGL 2.0, and I have errors when forcing the use of OpenGL (could not create shader program) that tell me that OpenGL version is too low.
The dirty trick mentioned above is not sufficient as it happens even when another non-focusable window comes in front of my main application window... So my main window never loses focus.
-
I finally got a workaround solution for the issue.
It turns out that setting the render loop to threaded mode seems to prevent the refresh issues from occurring. In my case, this works:
qputenv( "QSG_RENDER_LOOP", "threaded" );
See the following link explaining the difference between the threaded and the non-threaded render loop, and thee default value (non-threaded) on Widows with ANGLE.
I found it when looking at a similar issue:
https://bugreports.qt.io/browse/QTBUG-30763Regards,