I'm porting over a OpenGL application from a win32 project to a Qt project.
In the win32 project I simply had a mainloop that kept executing the next frame as soon as the previous was finished.
In the tutorials I find about Qt and OpenGL, they're using timers to control the update of the scene. However, I'd like to render as many frames as frequent as possible - how to do that?
However, I'd like to render as many frames as frequent as possible - how to do that?
Not with Qt. Qt takes full control of the event loop thus not giving you any means of directly performing idle operations. The standard way to perform idle operations in Qt is to use a QTime with a timeout of 0.
Another possibility was using a second thread just for OpenGL operations. However to work reliably you should create a dedicated OpenGL context for that one thread.
Qt simply is not the right toolkit for those kinds of program where the primary task of the main loop is rendering pictures and input and event management are only secondary.
Try calling update() at the end of your paint handler.
That will queue up another repaint event.
The intrinsic principles of Qt and OpenGL are not about rendering as soon as possible, but it's rendering whenever we want (huge difference).
You have to ask for the system max framerate (search for samples in OpenGL i'm sorry I don't rememember where I saw that). Once you've done that, just create a timer based on this max framerate, so you'll get what you want.
However, I'd like to render as many frames as frequent as possible - how to do that?
Use QTimer with zero interval.
Related
I am trying to use an external to Qt OpenGL context using a window handle that comes from Qt. The setup is:
A QMainWindow - contains various widgets including a QWebEngineView to make some web content available (in my case it's Leaflet for render and interact with OpenStreetMaps tiles)
Panda3D engine - rendered on top of my Qt application using a window handle of the central QWidget.
The setup works...when Panda3D is set to DirectX9 (aka pandadx9). When I switch the pipeline to OpenGL (aka pandagl) I get a black screen (Panda3D's window) and a very glitch OpenGL content (Qt). The reason is simple yet beyond my ability to fix it - QWebEngineView uses OpenGL. Somehow there is a conflict on a OpenGL context level between the engine and Qt. I am looking for a way to resolve this without removing the direct interaction with Panda3D's window (in my case using ShowBase) since the engine already offers a lot in terms of features for handling mouse events that I would otherwise be forced to reimplement in Qt and pass down to the engine. In addition I am not sure if I can make Panda3D render its scene as an FBO and how to load it in a - let's say - QOpenGLWidget. Activating shared OpenGL context before initializing QApplication allows multiple OpenGL widgets to render OpenGL content.
So far I have experimented to integrate Panda3D with Qt in two ways:
run two event loops in parallel - start the Panda3D engine in a child process and then using a pipe communicate with it
run a single event loop - use the event loop of Panda3D engine to also handle the main event loop of Qt by adding a task to the engine's task manager to run QApplication::processEvents() on every cycle
In both cases I am handing over a window Id (QWidget::winId()) as the parent window of Panda3D.
CASE 1 - parallel processes, separated event loops
This resolution comes with a lot of overhead. All the communication between the Qt content (running in the parent process) needs to be sent (via pipe hence involving IPC) to the engine (running in the child process). This adds a lot of code complexity and in case of my logging (using Python's logging module with a custom logging handler that writes records into an SQLite3 database) introduces a whole lot of issues. Concurrent write access to a file between processes is a tricky thing in general and I'm definitely not an expert. This case however does not exhibit the behaviour I'm describing below. In this case however the issue with OpenGL is not present!
CASE 2 - single process, single event loop
In my opinion this is a more elegant and is what I would like to go with (if possible). An example can be found here. I use the engine's main loop to process Qt's main loop. This is due to the fact that a 3D game engine usually would need to deal with far more events for a shorter period of time (processing rendering, audio, video, filesystem access, physics and so on) then a standard Qt GUI. This is also the recommended way as described in the official documentation of the engine. The other way around (Qt's main loop handling Panda3D's) is also possible. Imho neither have anything to do with my issue namely the moment I add anything Qt-ish that uses OpenGL, the problem I've described above occurs. On Windows this is not a huge deal breaker since I can also use DirectX for the engine, while Qt does it's OpenGL thing. On Linux it is not possible (without something like wine). In addition I want to use exclusively OpenGL including GLSL.
Here is a visual representation of case 1 and case 2 (but with mixed DX9 and OpenGL):
And below there are two visual representations of case 2 with only OpenGL:
While Panda3D offers CPU rendering (aka p3tinydisplay), QWebEngineView does not. Falling back to CPU rendering on the engine side is not an option considering the huge amount of polygons I have to render not to mention the fact that I can do something more useful with the CPU (e.g. processing the physics).
Last but not least I have seen a third integration attempt, which I quickly discarded - rendering the scene as an image to RAM, reading it in Qt, generating a QPixmap from it and painting on top of a QLabel. Needless to say this is a no go for my scenario due to the heavy hit on performance among others.
Any ideas how to tackle this?
I don't think event loops have to do with anything here; the problem is that by default child windows get the same device-context (DC) as the parent. In your case that's a problem because two different components (Qt framework, and Panda3D engine) try to ChoosePixelFormat and initialize OpenGL context twice on the same DC, which is not supported.
The proper solution is to create the Panda3D engine QWidget from a QWindow with the Qt::MSWindowsOwnDC style, which corresponds to the CS_OWNDC window-class style. Normally QWidget doesn't create any window at all -- but is rather implemented entirely within the Qt framework by drawing itself on the parent window.
I created table widget with check box and push button.
Now ,how to go on next page with all checked data, after click on push button.
the initial question was:
How to go on next page using push button in qt c++ without use of Qt signals and slots?
This is practically impossible, and certainly inadvisable, since Qt signals and slots is the basic foundational mechanism of Qt, used everywhere inside it.
Be sure to take more time to understand Qt signals and slots and study several Qt tutorials and examples. Consider also studying the source code of Qt5 itself (since it is free software). And you can also find many Qt open source applications (e.g. on github, gitlab, inside a Linux distribution, etc...) which should be inspirational (if you don't have time, you could pay some Qt consulting corporation to do your work).
My recommendation is to create some Qt QPushButton (perhaps subclassing that) and connect its clicked signal to your appropriate slot somewhere. The calculator example should be inspirational. You probably should subclass QTableWidget to add a new slot, and use that for your m_pTableWidget or at least declare your MainWindow::on_pushButton_clicked as a public slot (and of course connect it appropriately).
If you don't want to use Qt signals and slots, you should give up using Qt and choose some other widget toolkit. They all have some notification machinery (at least based on callbacks), and IMHO the design of Qt signals and slots is quite good (and sometimes better than what other toolkits provide).
Read also How to debug small programs
It seems that you don't understand the design principles of Qt (i.e. the fact that Qt signals and slots are central to Qt, so you should use them extensively). So I recommend taking a few days to study carefully the documentation of Qt (it is well written, but extensive; start with Getting Started Programming with Qt Widgets) and the source code of existing examples (including Qt itself); throw your current code to the trash bin; then rewrite it with an iterative and incremental development approach : code a few dozen lines at once, compile them (with all warnings and debug info, so g++ -Wall -Wextra -g with GCC), improve them to get no warnings, test your incomplete program - using the GDB debugger -, make sure it works as you want it to, and add one more small feature (perhaps just a single new widget) and repeat. Of course, use a version control system (I recommend git) and commit your code frequently (at least, at every loop of your iterative and incremental development approach).
NB. you have changed your question entirely (at first, you refused to use Qt signals and slots; now you accept to use them). Of course, you need to read carefully the documentation of every used widget (including the superclasses), notably of QTableWidget and of QTableView. And you need to define what a "page" is (and what going to the next page means), since QTableWidget don't know about them.
take time (several days or a few weeks) to read the documentation of Qt.
I'm currently writing a programme which has a function to hash a number of files in the background. I've read the Qt4 documentation a number of times over and I still can't really figure out which threading option is best for this.
http://doc.qt.io/qt-5/thread-basics.html
There's really no need to update the GUI when it's done with each file, I just don't wish to block the GUI and I really only need a single signal/slot connection upon completion. I'm thinking of extending QThread for a hashing thread. Does this sound reasonable/right?
I have this article bookmarked as it nicely illustrates the use of QThread and highlights some common misconceptions about it. Sample code available, which runs without blocking the GUI. Sample is hosted on RapidShare, but they seem to have implemented some sort of timed waiting period since I last used it.
This sounds like a good place to use the QtConcurrent::map() function. The map function can apply the same operation to a container of objects, in your case, files. Once you start the map function, you can create a QFutureWatcher and connect to its finished signal to be notified when all of the work is done.
I'm pretty new to QT's graphic view frame, and I couldn't find anything about this in the docs or on Google.
I have a GUI application that draws a representation for some data. The application itself does some work with matrices / vectors (a neural net thing) and has to represent it on a QGraphicsScene. So far so good, but I've noticed that the app segfaults & crashes sooner or later (and usually sooner) if I try to update the QGraphicsScene from another thread. The QT Docs say nothing about thread-safety & Google gives nothing. What I want (and pretty much need) to do is run the calculations & update the GUI representation accordingly, but the GUI controls etc themself have to remain responsive. As I said, my first thought was to do the whole thing in another thread, but it crashes randomly if I try to.
Is there any "accepted practice" to do this kind of thing in QT or is there some gotcha that I don't know of in the graphics view framework itself?
The Qt docs actually say quite a lot about thread safety. If the docs for QGraphicsScene don't say anything it's because they are not thread-safe, consistent with the behaviour you are seeing.
What you need to do is run your calculations in another thread and synchronise that thread with the main GUI thread as appropriate. A simple way to do this would be to set a flag in the main thread when the calculations are ready for display. That way you can call the appropriate QGraphicsScene methods in the main thread at the right time by simply checking the flag.
i wan't to use Native OpenGL in the paint function of my widgets(QPainter), to improve performance.
i saw that there is function QPainter::begin/endNativePainting(), that can help me.
but i can't find examples for that...
i wanted to know if those functions are low cost, or evry use of them reduce performance?
2.can i define beginNativePainting() and endNativePainting(), in general for all the widgets i use, instead of using that in every paint function i have.
tnx for any help....
There is some basic example code right in the documentation: http://doc.qt.io/qt-4.8/qpainter.html#beginNativePainting
The functions themselves should be fairly low-cost, but calling them might still cause a noticeably overhead, because Qt has to flush its internal painting queue on the beginNativePainting() call and probably has to assume that everything is changed as soon as endNativePainting() is called.
For the second part I am not sure if I understand what you are aiming at. Basically if you have a QPainter object, you can call beginNativePainting() once. But you have to match it with an endNativePainting() call. So the usual place would be the paint() method.
Qt is using a range of OpenGL functionalities to implement its 2D painting, including custom shaders and various frame buffers. It puts OpenGL into a pretty messy state.
beginNativePainting / endNativePainting are there to allow Qt's drawing engine to save this context and retrieve it once the user is done drawing.
It would have been nice to have the xxxNativePainting methods do the contrary (i.e. automatically save and restore user configuration of OpenGL), but since Qt allows to call OpenGL primitives directly, saving the global state is nigh impossible without tons of code and potential serious performance hit.
Instead, these methods simply save Qt's internal OpenGL state and, rather than having user code start in a configuration that would be meaningless anyway (and likely to change with each new Qt release), reset OpenGL to a "neutral" state.
It means that, inside a begin/end section, you will start with a clean slate: no shader linked, no vertex array, most of global parameters reset, etc.
Contrary to a simple QGLWidget / PaintGL scenario where you can afford to setup the global OpenGL state once and for all and simply call the rendering primitives each frame, you will have to restore pretty much everything just after the call to beginNativePainting (link/bind your shaders, set global parameters, select and enable various buffers, etc).
It also means that you should use native painting sparringly. Having each single widget do custom painting might soon bring your rendering to its knees.