Results 1 to 20 of 29

Thread: How to remove background

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    May 2007
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default How to remove background

    Hi, I'm trying to use the dwm api on a Qt application but I don't know how to remove the widget background. There's a way by using setPalette(0, 0, 0, 0); but i't will affect child widget.

    I's there an other way?

  2. #2
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: How to remove background

    Do you want a child widget to be transparent, or what?
    Or do you want the main window to be transparent?

    What exactly are you trying to achieve?
    If you are using DWM composition, then you don't need to do any hacks to make the window transparent. The window manager does it for you.
    Also Qt 4.3 transparently supports some DWM features.

  3. #3
    Join Date
    May 2007
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to remove background

    I't ok, I found a way to do it.

    But now I got two big problem. When I use QPainter to paint a semi-transparent rectangle on the glass. The widget will repaint over the last rectangle normaly (it will erase the widget and then paint the rectangle) but if I click on an other window (like the taskbar) it will repaint over the last rectangle without erase it.

    And the text won't render corectly on glass.

    PS : sorry for posting in the installation forum, if some one can move it to the programming forum it will be nice, thanks.

  4. #4
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: How to remove background

    Still not clear
    Try explaining what is it you are trying to achieve.
    Anyway, there is QWidget::setWindowOpacity. But note this also affects the widget's children.

    Regards

  5. #5
    Join Date
    May 2007
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to remove background

    I'm trying to make the left side of a widget in glass. And for this, I use the DWM api of Windows Vista. But when I use the api, I still have the background color that cover the glass. To remove it, I used setAttribute(Qt::WA_NoSystemBackground);.

    All worked fine until I draw a semi-transparent rectangle with a QPainter over the glass. It will render fine but if the widget get or lose the focus, the widget won't repaint itself corectly. Normaly when the widget repaint itselft, it will clear every object already drawn and then will paint the new one. But when the widget get or lose focus, it won't erase the previous draw. This will cause semi-transparent draw to append them self to the previous draw and they will be less and less transparent.

    Here is the code to reproduce the bug


    #include<QtGui/QApplication>
    #include
    <QtGUI>

    class test :public QMainWindow
    {
    Q_OBJECT

    public:
    test();

    protected:
    void paintEvent(QPaintEvent *event);
    };

    test::test()
    {
    setAttribute(Qt::WA_NoSystemBackground);
    }

    void test::paintEvent(QPaintEvent *)
    {
    QPainter painter(this);
    //Here we set the brush to white with alpha
    painter.setBrush(QColor(255, 255, 255, 64));
    painter.drawRect(0, 0, 200, 200);
    }


    int main(int argc, char*argv[])
    {
    QApplication app(argc, argv);
    test win1;
    win1.show();
    return app.exec();
    }


    I don't test it but it should show you what I mean. You just have to compile the code, start the application and then click on the taskbar or any other window and then click on the application. You will notice that the color should be more opaque than before and if you resize the widget, the color should return to the good one.

    And I'm using Qt 4.2.2
    Last edited by kawazoe; 19th May 2007 at 20:20.

  6. #6
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: How to remove background

    WA_NoSystemBackground:
    Indicates that the widget has no background, i.e. when the widget receives paint events, the background is not automatically repainted. Note: Unlike WA_OpaquePaintEvent, newly exposed areas are never filled with the background (e.g after showing a window for the first time the user can see "through" it until the application processes the paint events). Setting this flag implicitly disables double buffering for the widget. This is set/cleared by the widget's author.
    This is your explanation.
    I believe you have to update the background manually. In every paint event clear the background and draw it again.

    Regards.
    Last edited by marcel; 19th May 2007 at 20:25.

  7. #7
    Join Date
    May 2007
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to remove background

    I can't use painter.eraseRect(0, 0, width(), height()); because it will erase using the current palette so it will paint the the zone with the color that I remove using setAttribute(Qt::WA_NoSystemBackground);.

    Is there an onther way to clear it?

  8. #8
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: How to remove background

    what about:
    Qt Code:
    1. QPixmap pix( size() );
    2. pix.fill( Qt::transparent );
    3. painter.drawPixmap( 0, 0, pix );
    To copy to clipboard, switch view to plain text mode 

    that, or use QPixmap grabWidget after you first update the widget. Then you can paint this pixmap. But this is useful only if you don't want to paint other things too.

    Regards

  9. #9
    Join Date
    Oct 2006
    Location
    Germany
    Posts
    84
    Qt products
    Qt4
    Platforms
    Windows
    Thanks
    5
    Thanked 5 Times in 3 Posts

    Default Re: How to remove background

    Hey,

    I got the same problem (top level window with WA_NoSystemBackground).

    I finally managed to get my window painted but there an slight issue.
    Everytime the window receives a new paint event, it just paints the new window content on top of the previously painted content without deleting it first.

    The eraseRect() is the same as fill(rect(), background()) so there's no use to call it as it will just paint everything black (filling it with a transparent pixmap or a transparent brush also).

    Is there any way to delete the previously drawn stuff? The only workaround I can think of right now is to delete and recreate the window everytime a new paint event comes up, but this is sorta stupid

  10. #10
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: How to remove background

    OK.
    Then if you want to paint with a certain transparency, why not use setWindowOpacity?

  11. #11
    Join Date
    Oct 2006
    Location
    Germany
    Posts
    84
    Qt products
    Qt4
    Platforms
    Windows
    Thanks
    5
    Thanked 5 Times in 3 Posts

    Default Re: How to remove background

    Holy mother of god... I'm sorry to have to say this, but do you actually only post just to enlarge your posts count?

    We just spoke 2 days ago and I told you a couple of times that this is not what I and the thread start want. Also I used the search a few times and every time someone asks about this kind of question, it always seems that your answer is "why not use setWindowOpacity()"...

    Man, come on... I think you already know that we want to achieve semi transparent painting on a pixel basis and not stupidly for the whole window but still it seems like you're giving your standard-setWindowOpacity-reply

  12. #12
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: How to remove background

    This is why the background doesn't get updated!

    Quote Originally Posted by marcel View Post
    WA_NoSystemBackground:
    Indicates that the widget has no background, i.e. when the widget receives paint events, the background is not automatically repainted. Note: Unlike WA_OpaquePaintEvent, newly exposed areas are never filled with the background (e.g after showing a window for the first time the user can see "through" it until the application processes the paint events). Setting this flag implicitly disables double buffering for the widget. This is set/cleared by the widget's author.

    This is your explanation.
    I believe you have to update the background manually. In every paint event clear the background and draw it again.

    Regards.
    So try finding a way to update the background while using that flag. I that doesn't work, you can always use setWindowOpacity, as it proved to be a global solution.

    661

  13. #13
    Join Date
    Oct 2006
    Location
    Germany
    Posts
    84
    Qt products
    Qt4
    Platforms
    Windows
    Thanks
    5
    Thanked 5 Times in 3 Posts

    Default Re: How to remove background

    I know that it is because of WA_NoSystemBackground and the background kinda does get updated but Qt won't clear the widget's content before painting on it again.

    Furthermore WA_NoSystemBackground proved to be the only solution (combined with a few dwmapi.dll calls) for now to achieve semi transparent painting on a pixel basis.

  14. #14
    Join Date
    May 2007
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to remove background

    I updated my last post, go get a look and you will see the good news.

    PS : You should be able to pm me now.

    And by the way, yes, durbark have the same problem as me.
    Last edited by kawazoe; 19th May 2007 at 23:50.

  15. #15
    Join Date
    Oct 2006
    Location
    Germany
    Posts
    84
    Qt products
    Qt4
    Platforms
    Windows
    Thanks
    5
    Thanked 5 Times in 3 Posts

    Default Re: How to remove background

    Oh, I already can paint onto the glass frame (but this is a separate matter because I want to paint on the desktop (well, not really on the desktop, but you know what I mean)).

    So kawazoe, I know a solution how you can paint on the glass

    Qt Code:
    1. typedef struct
    2. {
    3. int cxLeftWidth;
    4. int cxRightWidth;
    5. int cyTopHeight;
    6. int cyBottomHeight;
    7. } MARGINS;
    8. typedef HRESULT (WINAPI *PtrDwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS *margins);
    9. static PtrDwmExtendFrameIntoClientArea pDwmExtendFrameIntoClientArea = 0;
    10.  
    11. Window::Window() : QWidget(0)
    12. {
    13. pDwmExtendFrameIntoClientArea = (PtrDwmExtendFrameIntoClientArea)QLibrary("dwmapi").resolve("DwmExtendFrameIntoClientArea");
    14. MARGINS margins = {-1}; //setting it to -1 makes the glass available throughout the entire window,
    15. // like you have in the Windows Sidebar Add Gadgets dialog
    16. pDwmExtendFrameIntoClientArea(this->winId(), &margins);
    17.  
    18. this->setAttribute(Qt::WA_NoSystemBackground);
    19. }
    To copy to clipboard, switch view to plain text mode 

    Now you're good to go and you can put your widgets and everything as usual in the window. It works for me on Windows Vista with Qt4.3RC1
    Last edited by jacek; 20th May 2007 at 17:03. Reason: wrapped too long line

  16. #16
    Join Date
    Oct 2006
    Location
    Germany
    Posts
    84
    Qt products
    Qt4
    Platforms
    Windows
    Thanks
    5
    Thanked 5 Times in 3 Posts

    Default Re: How to remove background

    Okay, I found the solution. It's weird though, I though I already tried that...
    Anyway, resizing the window erases the content:

    Qt Code:
    1. void Window::paintEvent(QPaintEvent *paintEvent)
    2. {
    3. static int isResizing = 0;
    4.  
    5. if(isResizing == 0)
    6. {
    7. QSize size = this->size();
    8.  
    9. size.setHeight(size.height()+1);
    10. isResizing = 1;
    11. this->resize(size);
    12.  
    13. QApplication::processEvents();
    14.  
    15. size.setHeight(size.height()-1);
    16. isResizing = 2;
    17. this->resize(size);
    18.  
    19. QApplication::processEvents();
    20.  
    21. isResizing = 3;
    22. return;
    23. }
    24. else if(isResizing < 3)
    25. {
    26. QWidget::paintEvent(paintEvent);
    27. return;
    28. }
    29. else
    30. isResizing = 0;
    31.  
    32. //Now you can start painting
    33. }
    To copy to clipboard, switch view to plain text mode 
    Somehow I'm thinking that I overkilled it a little bit with isResizing... am I so tired right now and just can't see a simpler solution to do that resizing thingy?
    Last edited by durbrak; 20th May 2007 at 00:22.

  17. #17
    Join Date
    May 2007
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to remove background

    I don't have the problem when resizing but when changing the focus. Even resizing seem to restore the corect color.

  18. #18
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: How to remove background

    to durbrak:
    Qt Code:
    1. CTestWidget::CTestWidget(QWidget* parent )
    2. :QWidget( parent )
    3. {
    4. setWindowFlags( Qt::FramelessWindowHint );
    5. setFixedSize( 400, 400 );
    6. mPixmap = QPixmap( "C:\\ellipse.png" );
    7. QBitmap mask = mPixmap.createHeuristicMask(true);
    8. setMask( mask );
    9. }
    10.  
    11. CTestWidget::~CTestWidget()
    12. {
    13. }
    14.  
    15. void CTestWidget::paintEvent(QPaintEvent* e)
    16. {
    17. QPainter p( this );
    18. p.drawPixmap( 0, 0, mPixmap );
    19. }
    To copy to clipboard, switch view to plain text mode 

    I knew I did it some time ago.
    I attached a screen of how it looks.
    The png is just a black ellipse on a white background.
    The method is limited because it does not work when the image you want to display contains transparent shadings ( such as shadows ).
    However, you can give the whole masked widget a shadow if you set the flags Qt::FramessWindowHint | Qt::Popup.

    Although, never tested it on Mac.

    regards
    Last edited by marcel; 20th May 2007 at 01:07.

  19. #19
    Join Date
    Oct 2006
    Location
    Germany
    Posts
    84
    Qt products
    Qt4
    Platforms
    Windows
    Thanks
    5
    Thanked 5 Times in 3 Posts

    Default Re: How to remove background

    kawazoe: No, you missed the point. My solution fixes the problem where the background wasn't erased by Qt (it was just painted over). Now with this solution, everytime the window wants to repaint itself, it will resize itself first (thus erasing the garbage painted before), and then paint the stuff.

    marcel: Stuff like shadows is exactly what I'm trying to do the whole time You scaled your screenshot a little bit too much and I can't see if your circle is anti aliased or not. But I guess not, since this would be equal to shadows

    Anyway, I can finally do that now. But here comes the kinda weird part:
    I paint text and circles (anti aliased) in my widget and everything looks smooth. But if I paint a pixmap first and then the text and the circles, the circles are still smooth but now the text is crispy as hell
    Weird, I can paint every type of form/shape smooth on my png pixmap window, but not text...

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.