Important: Please read the Qt Code of Conduct -

Showing a qmenu disrupts graphics engine

  • I finally have the basic interface for my project working nicely. So I am moving on to the next step and adding a graphics engine. I am using a 3rd party engine for several reasons which don't really matter. I am running into a problem however.

    With a graphics engine embedded in a qt widget the scene must be drawn every couple of milliseconds. RIght now I am shooting for a frame-rate of 60fps so I update my widget every 16 milliseconds using a QTimer of the precise quality.

    The problem occurs when I display a menu attached to a QToolButton. It takes too long to draw and I get a grey flash in the drawing of the scene. I need to overcome this.

    My first thought was to override the QMenu class and make my own paint method that updates the scene periodically throughout the method but the in order to do that I believe I would need access to QMenu's private data. I looked at the code for QMenu and it seems there is a protected constructor:

    QMenu(QMenuPrivate &dd, QWidget* parent = 0);@

    However there is no documentation of this constructor nor of the QMenuPrivate data and I need to make sure I can actually construct a QMenuPrivate class in order to use it.

    How can I overcome this issue? Is implementing my own paint method the best approach? If so, do I have access to QMenuPrivate somehow? My current guess is that I will need to include the qmenu_p.h file in my project. Is this an ok thing to do?

  • Lifetime Qt Champion


    If you only want to paint the menu yourself, just re-implement the paintEvent method, no need to fiddle with the private part of Qt.

    Starting to use private bits of Qt means that you're going to be tied to a particular version of Qt since these headers and corresponding code can change and disappear at anytime.

    What version of Qt on what OS are you currently running ?

  • I am using the msvc2012_opengl version 5.3.2 on Windows 7

    I want to draw the menu exactly as its already being drawn. However, I want to insert a call to the scene updater in key places. I don't think this is possible without access to private data. The code that Qt uses to draw the menu accesses the the private data in several places.

    For example. How would I do this (from qmenu's paint event) in my own method? unless d is protected (which it isn't...)?

    Heck... I suspect that this call itself takes up most of the time. So I may even want to somehow do this myself. But I don't believe I have access to the actual list of actions installed on the menu do I? Unless I manually track them as they are added.

  • There also could be another approach. (More of a workaround really... but might work for the short term while I figure out a more complete method). Even if the update method wasn't called, is there a way to keep the currently rendered image on the widget instead of it filling up with grey? (which is what causes the flash?) Is that a Qt thing or a graphics engine thing?

Log in to reply