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

Turn entire app in grayscale



  • Since i make a minesweeper clone i also want to emulate its original feature of turning everything into grayscale like this:

    fb02bfdb-ec26-419a-8ea5-c8a74f5df4fa-image.png

    f0d50430-d2a3-48df-af84-35f7740d7e63-image.png

    I wonder what is the easiest way.

    In my app all the paint events draw images and display them. I could just convert them in a step:

    void Cell::paintEvent(QPaintEvent *event)
    {
        Q_UNUSED(event)
        QPainter painter{ this };
    
        auto image = displayImage(mDisplayType);
        
        if(mGrayScaleOn) {
            image = image.convertToFormat(QImage::Format_Grayscale16);
        }
    
        painter.drawImage(rect(), image);
    }
    

    This way i have to implement that in all the classes i have (The smilie button, the cells, the minefield the LCDDisplays) and add methods to toggle the bits.

    I wonder if theres some easy global way to render everything QMainWindow displays into grayscale.


  • Lifetime Qt Champion

    Hi,

    You can try to make a custom style.



  • @sandro4912
    If it works for what you want to achieve, could you just use a global stylesheet?


  • Moderators

    You could override the paintEvent() just at the main widget level and render() the entire main widget and its contents in one go into a QImage. Then cenvert it to grayscale like you did and paint that.

    The tricky part is that the render method would call your paint event, so this would recurse. What you can do is in your paint event set some sort of bool flag that you would check and depending on if that flag is set or not either paint normally by calling the base class implementation when you're inside a render call or go into the render and convert path if you're at the "top level" paint event.



  • @Chris-Kawa

    I tryed this but i think its still recurse:

    void Game::paintEvent(QPaintEvent *event)
    {
        if(mInsideRender) {
            mInsideRender = false;
            QWidget::paintEvent(event);
        }
        else {
            mInsideRender = true;
            QPixmap pixmap(size());
            render(&pixmap);
            auto image = pixmap.toImage();
            image = image.convertToFormat(QImage::Format_Grayscale16);
    
            QPainter painter{ this };
            painter.drawImage(rect(), image);
        }
    }
    

    Can you explain some more what to do?

    @JonB

    Can you show how to set a stylesheet with graycale?

    @SGaist

    The custom style sounds like a lot a lot of work or isn't it?


  • Lifetime Qt Champion

    I'll let you decide. Take a look at the examples to have an idea of the possible amount of work.


  • Moderators

    @sandro4912 Well you've got the mInsideRender = false; line in the wrong place, it should be either under call to paintEvent or under call to render. But even then Qt seems to warn about recursive paint event. I guess technically we do want recursion here, but just one time. So anyway - this way won't work. Sorry for turning you in the wrong direction.


Log in to reply