Transparent QDialog - toggle on/off



  • I have this current Interface that is a custom QDialog :
    https://www.dropbox.com/s/m2cyi7ueuuzm5nt/mainQDialog.png?dl=0

    I would like to have a button that trigger a "transparent" version of the same Dialog, so that most of the widgets are transparent and you can see under them. I looked a bit and found that you can use stylesheet to do so, but i'm having problem changing dynamically.
    In other words, I can set the QDialog to be transparent with this after setupUI :

        setStyleSheet("background:transparent;");
        setAttribute(Qt::WA_TranslucentBackground);
        setWindowFlags(Qt::FramelessWindowHint); 
    

    But If I tried to call this above code in a function, my QDialog close and return from .exec(). I don't understand why it closes the QDialog.

        void WorkoutDialog::toggleTransparent() {
        
        
            if (isTransparent) {
                qDebug() << "SHOW NORMAL!";
        
                //revert back to normal QDialog, use saved stylesheet
                this->setStyleSheet(bakStylesheet);
        
                Qt::WindowFlags flags = Qt::Window;
                setWindowFlags(flags);
        
            }
            else {
                qDebug() << "SHOW TRANSPARENT!!";
        
                //save current stylesheet
                bakStylesheet = this->styleSheet();
        
                setStyleSheet("background:transparent;");
                setAttribute(Qt::WA_TranslucentBackground);
                setWindowFlags(Qt::FramelessWindowHint); //this close the QDialog? why?
        
                ui->widget_allSpeedo->setStyleSheet("background:transparent;");
                ui->widget_allSpeedo->setAttribute(Qt::WA_TranslucentBackground);
                ui->widget_allSpeedo->setWindowFlags(Qt::FramelessWindowHint);
        
                ui->widget_topMenu->setStyleSheet("background:transparent;");
                ui->widget_topMenu->setAttribute(Qt::WA_TranslucentBackground);
                ui->widget_topMenu->setWindowFlags(Qt::FramelessWindowHint);
        
            }
            isTransparent = !isTransparent;
        }
    

    Any help appreciated!


  • Lifetime Qt Champion

    Hi,

    Are you using 5.4.1 ?



  • Hey master SGaist,

    Yes Qt 5.4.1 - MSVC2013 32bit
    Just trying to toggle my QDialog from normal to transparent with stylesheets.
    People have been requesting this feature to see a video under the Widgets for example.
    Or If I could toggle transparent on all my Widgets, not the QDialog, that would also work.
    Just trying to find if it's possible. I know some native Windows app can have transparent widgets.

    Thanks!


  • Lifetime Qt Champion

    Transparency can be done although I haven't tried it "dynamically", but at first, I don't see any problem doing it like that.

    IIRC setWindowFlags(Qt::FramelessWindowHint); is causing trouble to another forum user since the update to 5.4.1 so you might want to skip that one to see it the rest works correctly



  • Thanks SGaist, I did some more trials,

    If I set theses 3 lines in my QDialog constructor, the QDialog is transparent and working perfectly like I want :
    https://www.dropbox.com/s/226bmro0f8jzfi4/transparentBackgroundOk.png?dl=0

            setStyleSheet("background:transparent;");
            setAttribute(Qt::WA_TranslucentBackground);
            setWindowFlags(Qt::FramelessWindowHint);
    

    But if I tried to call the same 3 lines in a function after the QDialog is already shown, the QDialog closes.
    If I remove the line "setWindowFlags(Qt::FramelessWindowHint);", the transparent effect doesn't work.
    So it seems I can't do it "dynamically" with 5.4.1. I guess changing the QDialog WindowsFlags after it's already shown is prohibited?
    Wonder if there is another way to "hack" the same effect...

    Not working if called after constructor (same code as above):

        void WorkoutDialog::toggleTransparent() {
        
            if (isTransparent) {
                qDebug() << "SHOW NORMAL!";
        
                //revert back to normal QDialog, use saved stylesheet
                this->setStyleSheet(bakStylesheet);
        
                Qt::WindowFlags flags = Qt::Window;
                setWindowFlags(flags);
            }
            else {
                qDebug() << "SHOW TRANSPARENT!!";
        
                //save current stylesheet
                bakStylesheet = this->styleSheet();
        
                setStyleSheet("background:transparent;");
                setAttribute(Qt::WA_TranslucentBackground);
                setWindowFlags(Qt::FramelessWindowHint); //this close the QDialog if not called in Constructor, why?.
            }
            isTransparent = !isTransparent;
        }

  • Lifetime Qt Champion

    So, after some testing, it seems that the Qt::WA_TranslucentBackground attribute changing doesn't have any effect outside the constructor (however, I can't tell if it's a bug or not) at least on OS X.

    In any case, IIRC your application heavily relies on style sheet so what you can do is to set Qt::WA_TranslucentBackground in the constructor and set the color in your style sheet using e.g. rgba(100, 100, 100, 255 when you don't want transparency and rgba(100, 100, 100, 0 when you want full transparency.

    Or if it still is problematic, "reload" the UI when your user asks for transparency



  • @SGaist

    Thanks SGaist, I tried every combination possible but without "setWindowFlags(Qt::FramelessWindowHint);" on the QDialog itself, I can't achieve transparency. That's on Windows7.

    On Windows, if you set "setAttribute(Qt::WA_TranslucentBackground);", the background will go black whatever you put the stylesheet at.
    So I don't think transparency is possible without the flag "setWindowFlags(Qt::FramelessWindowHint);", and you can only set this flag in the constructor, not after. I don't mind having a different code for OSX and Windows for this part if it's possible, but as of right now I can't toggle transparency after the QDialog is already shown.

    Will keep looking for solution if it comes, could be a great feature to have a minimalist transparent view for my app.
    Thanks for your research, I haven't try on OSX yet, the behavior is probably different.


  • Lifetime Qt Champion

    No, it's not, it's even stated in the documentation. However, AFAIK, these flags should be dynamically changeable. In any case, try with 5.4.0 to see if this works for you. If not, then I'd take the second way if feasible: reload the UI so you can set the parameters correctly in the constructor.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.