Page 1 of 2 12 LastLast
Results 1 to 20 of 29

Thread: How to remove background

  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
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    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
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    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
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    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
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    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
    Thanks
    5
    Thanked 5 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    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
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    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
    Thanks
    5
    Thanked 5 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    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
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How to remove background

    Behave, please.

    Doesn't your platform API (you're using it to have the client rect changed in the first place, right?) allow you to somehow protect or retrieve the "glassy" area? I'm just guessing here, but it'd seem reasonable if such a call existed. You're trying to use a feature which is relatively new, so I suspect Qt doesn't have any support for this yet and you have to dig into WinAPI. I hope I'm just correctly guessing what you're trying to do If not then sorry for bothering you with my awful postcount-increasing-message (after all, we're all here just for the post count, right?).

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

    Default Re: How to remove background

    Hi durbrak,
    This bug it a Qt bug. I'm trying to make a workaround for this but it still not working fine yet. I will pm you when I will manage to make it work.

    Sorry marcel but the pix trick don't work.

    wysota, the problem is not the api, it's that Qt do not paint directly on the window but on one layer and won't leave us paint on the base window. If you extend the frame trought the client area, you won't see the glass. But if you look at the small line all around the client area, you will see that the glass is extend but cover by the background of the widget.

    In fact, for the glass to extend, the dwm need to paint on a black background. So by using this api and then using setPalette(0, 0, 0, 0);, you will se than the widget background is just a layer because the real background is show as black.

    If I'm right, the best version of Qt to work with this api is Qt 4.1 because of it's way to manage transparency and layers.

    As writing this, I got an idea to finish my workaround, leave me 2 hours and I reply with the solution.
    Last edited by kawazoe; 19th May 2007 at 23:33.

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

    Default Re: How to remove background

    You're not respecting my "authorithy" here...
    Holy mother of god... I'm sorry to have to say this, but do you actually only post just to enlarge your posts count?
    Yes, I'm getting close to that magic 700 aren't I?
    No, it's not for the posts, and the answer wasn't for you. I was trying to find a solution for the thread starter. It seemed that he was trying to achieve global widget transparency.

    If you don't like a solution, then don't use it.

    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()"...
    I'm sure I answered about two similar posts about this.
    By the way? Do I know you? This seems kind of personal.

    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
    Maybe you, but not him, from what he explained.

    Bottom line, it's not anybody's fault that you can't find solutions for your problems.
    If a solution seems "stupid" to you, then don't use it.

    Oh, and what do you know? Look at that! It's 660!

    Regards

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

    Default Re: How to remove background

    Okay, sorry wysota

    Well, actually I stopped using winapi calls for the time being out of curiosity (meaning that I just paint on the background of a top level window with WA_NoSystemBackground with nothing more) just to exclude the possibility that it's not Qt's "fault".

    Qt Code:
    1. Window::Window() : QWidget(0)
    2. {
    3. this->setWindowFlags(Qt::FramelessWindowHint);
    4. this->setAttribute(Qt::WA_NoSystemBackground);
    5. }
    6. Window::paintEvent(QPaintEvent *)
    7. {
    8. QPainter painter(this);
    9. painter.setOpacity(.2);
    10. painter.setPen(Qt::red);
    11. painter.drawText(50, 50, "Please stop overpainting yourself.");
    12. }
    To copy to clipboard, switch view to plain text mode 

    Now with this code, it just keeps painting the text over the previously painted text and I can see how the red text gets brighter every time (notice how I used painter.setOpacity() to see the overlapping easier).

    I already tried filling it with transparent colors, transparent pixmaps etc. Nothing works

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

    Default Re: How to remove background

    Woh, relax
    I wasn't angry or something, I was just pointing out that you frequently make use of the everything-will-work-with-setWindowOpacity solution.

    Cool new signature by the way :P

    Edit: kawazoe, thank you. I already know that this is lack of feature in Qt I tried to send you a PM but I couldn't because you disabled that option

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

    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

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

    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.

  19. #19
    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.

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

    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

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.