I'm writing an app in Qt Creator, using C++. The eventual goal is to have control over an OpenGL window from within the Qt main winow.
Initialization is fine, both mainwindow and OpenGL window start up with no issues.
The mainwindow is subclassed from QMainwindow, the OpenGL window is subclassed from public QWindow, public QOpenGLFunctions.
Here's the crux of the problem. I want event handlers in mainwindow to have access to the OpenGLWindow. I can't seem to make that happen. I've gotten past a number of obstacles so at this point I have the following set-up;
In main.cpp, I declare the objects for both mainwindow and OpenGLWindow. I have the mainwindow mousepressed event handler in main.cpp. As is, all works fine. Both windows come up as they should, and the event handler code does exactly what I want it to do in the mainwindow, just print some text in a textbox.
In order to have access to the openglwindow from the event handler in main.cpp, I declare the OpenGLWindow object as global, outside of the main () main.cpp (is this bad technique?).
Everything compiles fine, but when I run it I get the error 'QPixmap: Must construct a QGuiApplication before a QPixmap'. I assume that this means that the system is not happy that I am creating the OpenGLWindow before the application object.
Is there a more elegant way to do this? Am I a few lines away from correct code, or does this need some major rearranging.
BTW - I am doing this in Windows 10. The main reason I have chosen Qt and OpenGL for this app is that I want it portable to Linux.
Related
Currently I am writing a C++ Qt GUI standard (i.e. via Qt Creator) application.
Basically, what I am trying to do is an application, which operates the following singleton classes:
a MainWindow class, which is responsible for the core logic;
a ServerWindow class, which is responsible for the server connection;
a User class, which is returned (in form of a pointer) by the ServerWindow class after successfull authentication;
a Data class, which is initialized with the data, recieved via ServerWindow upon user authentication.
The algorithm is:
Construct a MainWindow and create a Data class; it also holds a pointer (nullptr at this step) at the current user.
When the constructor has finished, the ServerWindow (derived from QDialog) is executed (via Qt delayed connection). At this step the MainWindow is frozen and set invisible, untill the ServerWindow emits one of the signals (logged, fail). The ServerWindow has a modal mode flag set.
When the ServerWindow is done, a pointer to the current user is passed to the MainWindow. The ServerWindow also knows about the Data class and initializes it.
The main problem is that at step 2 the application icon in the taskbar (I use Windows OS) is not shown. When the MainWindow is "offline" (i.e., not shown, invisible via setVisibility(false)), there is no icon. It is highly annoying, especially if there is a bunch of other applications open. So that, my question is: what can I do to make ServerWindow create an application icon in the taskbar without MainWindow being shown?
The additional, by-the-way question is about possible application architecture remastering. I cannot find any books in my small library about similar applications designing. Frankly, I cannot even figure out, which words I should pass to the Google search line. Any advice?
Preliminary, thanks for any answers!
In my application the main window's GUI is designed in the Qt-Creator designer. I have had some trouble in getting it to look just the way I'd like, but I can when doing the GUI in C++ code.
So, I plan to change the application's main window to be laid out in code.
What should I keep in mind when doing this?
How do I make sure all the menu items and button clicks etc. get migrated, too?
In my Qt experience I almost always write layout in code and here is what I can suggest:
a) Spend some time thinking which Layout to use, personally I tend to use either QGridLayout or nested QHboxLayout and QVBoxLayout which give you lot of flexibility.
b) I normally declare all child widgets as class variables always pointers and I create the real objects in the Main windows constructor.
About not to forget any control I suggest to print the XML of the UI file and draw a line on each control you recreate in the code.
As a good starting point, simply copy-pase the setupUi method from the ui_xxx.h file that uic had generated for you. You can then manually edit the setup code to suit your needs.
I'm using Necessitas to compile and run my QT apps on Android. If I'd like to show another window over the Main Wondow, I would create an UI file from QT Creator, which also will create a class. Then, I would create an instance of that class, and finally call the exec() member function.
However, in Necessitas QT Creator, the compiler tells me that the memeber function exec() doesen't exist. If I try using the show() member function, nothing happens. Also , If I hide the Main Window, the program exits.
So ,what can I do to show the other Window that I created with QT Creator?
http://qt-project.org/doc/qt-4.8/qstackedwidget.html
This is essentially a layout that behaves like a tabbed/paged widget but it doesn't show any tabs. This should get you what you want.
I have a little question about Qt custom Widgets.
Both in http://doc.qt.digia.com/4.3/tutorial-t4.html and http://doc.qt.digia.com/4.3/tutorial-t8.html, the custom window declaration is made in the main.cpp file, where the qApp pointer is accesible(in the second link, more widgets are declared in their own files).
Couldn't the window be done in another different file and have the qApp pointer passed to it?.
Yes, the main windows can be created in another file. All you need in the main is to create the QApplication and show something that you include. And then start the event loop.
You don't have to pass qApp pointer anywhere. It is a global reference to the only single application that can be running. Just access it in any other file by including QApplication.
Also be advised, those tutorials are for Qt 4.3 which is old (unless you are bound to use that version right now). You can find tutorials for Qt 4.8 here
I'm wondering if it is possible to capture an event that is generated when all
Qt objects are initialized and ready ?
It seems that some things can't be done in window's constructor. And they work fine in slot implementation.
For example, when I want to access root window of my application I do it like that
// in *.h
MainWindow* rootWindow
// in *.cpp
rootWindow = qobject_cast<MainWindow *>(this->window());
If it is done in the contructor I can't use rootWindow object - it couses runtime error.
There is no relevant slot to implement. And create event in QMainWindow class is not virtual.
Thanks for help :)
You can use a single-shot timer for this. In your main window class, define a slot function called say, appReady(). In the constructor, create and connect a single shot timer using QTimer::singleShot(0, this, SLOT(appReady())); This timer should fire as soon as the event loop is up and running and there are no more startup events pending.
How can you be sure that root window is in fact MainWindow? Later in the project lifetime you could feed your widget to a different parent (for example a few layers of QFrame decorations for layouting purposes) and this code will fail.
Pass it in as an explicit parameter in the constructor instead.
Unless it is MainWindows all the way down :)