Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[SOLVED] Handling maximise/un-maximise events using QMainWindow::changeEvent



  • I'm attempting to handle the maximisation of my main window using the changeEvent like so

    @void MainWindow::changeEvent( QEvent e )
    {
    if( e->type() == QEvent::WindowStateChange ){
    QWindowStateChangeEvent
    stateChangeEvent = static_cast<QWindowStateChangeEvent*>( e );
    if( stateChangeEvent->oldState() == Qt::WindowNoState && this->windowState() == Qt::WindowMaximized ){
    // Do stuff with the newly maximised window
    }
    else if( stateChangeEvent->oldState() == Qt::WindowMaximised && this->windowState() == Qt::Window--NoState){
    // Do stuff with the newly un-maximised window
    }
    }
    QMainWindow::changeEvent( e )
    }@

    The line where the if statement is interrogating the old and new states is attempting to spot if the window has gone from having no state, ie just floating normally on the desktop, to being maximised. The else condition is looking for the reverse, ie, going from maximised to floating normally.

    My problem is that breakpoints within both loops are never getting hit, leading me to believe my logic in the conditions is incorrect. What is the correct logic for catching the maximise and unmaximise events on the main window?



  • Two guesses:

    • call the base class implementation at the top

    If that doesn't help

    • Debug output e->type() and if it's WindowStateChange, debug output stateChangeEvent->oldState() as well as this->windowState(). It might be that the window manager you're using doesn't support the concepts of maximised windows and thus Qt just emulates the behaviour.


  • I've discovered that the problem come from the way I'm using the changeEvent. I have a custom implementation of the showMaximized function and so I am manually constructing a QEvent object and passing it to the changeEvent when the mainWindowIsMaximized signal is emitted. The following function does this:

    @void MainWindow::mainWindowMaximised()
    {
    QEvent *e = new QEvent( QEvent::WindowStateChange );
    changeEvent(e);
    }@

    The problem is that when I cast this event to a QWindowStateChangeEvent, I always end up with an event object that has no information attached to it. Is it possible to construct an event object that can successfully pass the if tests in my original posts?



  • I've managed to come up with a solution. QEvent has a static public function called registerEventType which can be used to create a new event type. Rather than trying to cast the QEvent going into the changeEvent, I have simply registered a new type of event, rather than trying to determine the state of the window before and after maximization/un-maximization. My solution is:

    @class MainWindow : public QMainWindow
    {
    //Some stuff
    //The enum value must be between 1000 and 65535 in order not to clash with existing event types
    enum MainWindowEvent { Maximise = 3000, UnMaximise = 3001 };
    // Some more stuff
    };

    void MainWindow::maximiseButtonClicked()
    {
    // Some stuff
    emit mainWindowMaximised();
    // Some more stuff
    }

    void MainWindow::mainWindowMaximised()
    {
    QEvent::Type type::registerEventType( MainWindowEvent::Maximise );
    QEvent *e = new QEvent( type );
    changeEvent(e);
    }

    void MainWindow::changeEvent( QEvent *e )
    {
    if( e->type == MainWindowEvent::Maximise ){
    //Do something with the newly maximised window
    }
    else if( e->type() == MainWindowEvent::Unmaximise) {
    //Do something with the newly unmaximised window
    }
    }@

    }


Log in to reply