Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] Scaled background image using stylesheet
QtWS25 Last Chance

[SOLVED] Scaled background image using stylesheet

Scheduled Pinned Locked Moved General and Desktop
17 Posts 5 Posters 113.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    mbnoimi
    wrote on last edited by Chris Kawa
    #1

    How can I make a scaled background image using stylesheet?

    I tried to use:

    #centralWidget {
     background: url(:/res/background.jpg) no-repeat center center fixed;
     background-size: cover;
    }
    

    But it seems that Qt ignores background-size: cover; so I wonder is there any trick I can do?

    P.S. I want a similar behavior of the background in "this page":http://css-tricks.com/examples/FullPageBackgroundImage/progressive.php

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      AFAIK, background-size is not supported by Qt's style-sheet

      Maybe image might do the trick ?

      Hope it helps

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      said_osloS 1 Reply Last reply
      0
      • Chris KawaC Offline
        Chris KawaC Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on last edited by Chris Kawa
        #3

        background-size is not supported but there's a trick with border-image ;)

        #centralWidget {
        border-image: url(:/res/background.jpg) 0 0 0 0 stretch stretch;
        }
        
        1 Reply Last reply
        3
        • M Offline
          M Offline
          mbnoimi
          wrote on last edited by Chris Kawa
          #4

          @SGaist said:

          Maybe image might do the trick ?

          Actually I saw this trick before but unfortuantely I missed it; for that I asked this question here.

          1 Reply Last reply
          0
          • M Offline
            M Offline
            mbnoimi
            wrote on last edited by Chris Kawa
            #5

            @chrisaverage said:

            background-size is not supported but there's a trick with border-image ;)
            #centralWidget {
            border-image: url(:/res/background.jpg) 0 0 0 0 stretch stretch;
            }

            Unfortunately it doesn't help because it doesn't keep same aspect ratio as shown in the link I pointed it above ( http://css-tricks.com/examples/FullPageBackgroundImage/progressive.php ).

            I need a background image scaled with keeping on same aspect ratio.

            1 Reply Last reply
            0
            • C Offline
              C Offline
              clochydd
              wrote on last edited by
              #6

              Hi, if using the styleSheet is not mandatory: There a some good tips to sizing an image with the right aspect ratio in the Qt Image Viewer Example.

              1 Reply Last reply
              0
              • Chris KawaC Offline
                Chris KawaC Offline
                Chris Kawa
                Lifetime Qt Champion
                wrote on last edited by
                #7

                Yeah, you won't get the exactly same effect with border-image, but you can change one of the dimensions from stretch to repeat.
                This would keep the aspect ratio. If that's no good I would just override paintEvent and draw it however you need with QPainter.

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  mbnoimi
                  wrote on last edited by Chris Kawa
                  #8

                  @chrisaverage said:

                  If that's no good I would just override paintEvent and draw it however you need with QPainter.

                  Unfortunately I couldn't find a solution using qss so may you please guide from where I can start by using paintEvent.

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    mbnoimi
                    wrote on last edited by Chris Kawa
                    #9

                    I fixed this issue by using the following:

                    void MainWindow::paintEvent(QPaintEvent *pe)
                    {
                        QPixmap pixmap;
                        pixmap.load(":/res/background.jpg");
                        QPainter paint(this);
                        int widWidth = this->ui->centralWidget->width();
                        int widHeight = this->ui->centralWidget->height();
                        pixmap = pixmap.scaled(widWidth, widHeight, Qt::KeepAspectRatioByExpanding);
                        paint.drawPixmap(0, 0, pixmap);
                        QWidget::paintEvent(pe);
                    }
                    

                    P.S. I feel very upset because I hoped to use QSS, I always prefer to use it instead of manual theme manipulation .

                    1 Reply Last reply
                    0
                    • Chris KawaC Offline
                      Chris KawaC Offline
                      Chris Kawa
                      Lifetime Qt Champion
                      wrote on last edited by Chris Kawa
                      #10

                      A comment on your paintEvent(). At the end you call QWidget::paintEvent(). This is not a good idea. If someday you flip the autoFillBackground flag or a future theme adds some background to the widgets, it will paint over whatever you draw.
                      Either call it before you draw or, if you're filling the whole area anyway, don't call it at all.
                      Also you can just do QPixmap pixmap(":/res/background.jpg"), no need to load separately. You could also store it somewhere and not load again each time it's drawn.

                      As for you being upset - cheer up :) QSS just doesn't support it so there's nothing you can do about it. Unless of course you want to implement it and offer a patch to Qt ;)
                      And it's not like it's slower or anything. It just looks funny.
                      If you don't want to mix this drawing code into your widget there's another way.
                      Make a class that derives from QObject and implement eventFilter method that will do the drawing for the paint event. Then you can install instance of that class on your widget. Something ike this:

                      SuperBackgroundPainter blah(":/res/background.jpg");
                      MainWindow w;
                      w.installEventFilter(blah);
                      w.show();
                      ...
                      

                      This way you can nicely separate this unfortunate painting stuff from the main purpose of your widget.

                      1 Reply Last reply
                      1
                      • M Offline
                        M Offline
                        mbnoimi
                        wrote on last edited by Chris Kawa
                        #11

                        @chrisaverage said:

                        A comment on your paintEvent(). At the end you call QWidget::paintEvent(). This is not a good idea. If someday you flip the autoFillBackground flag or a future theme adds some background to the widgets, it will paint over whatever you draw.
                        Either call it before you draw or, if you're filling the whole area anyway, don't call it at all.
                        Also you can just do QPixmap pixmap(":/res/background.jpg"), no need to load separately. You could also store it somewhere and not load again each time it's drawn.

                        I appreciate your comment Chris; Thank you :)

                        Below the solution depending on your advice:

                        MainWindow::MainWindow(QWidget *parent) :
                            QMainWindow(parent),
                            ui(new Ui::MainWindow)
                        {
                            ui->setupUi(this);
                            _pixmapBg.load(":/res/background.jpg");
                        }
                        
                        void MainWindow::paintEvent(QPaintEvent *pe)
                        {
                            QPainter paint(this);
                            int widWidth = this->ui->centralWidget->width();
                            int widHeight = this->ui->centralWidget->height();
                            _pixmapBg = _pixmapBg.scaled(widWidth, widHeight, Qt::KeepAspectRatioByExpanding);
                            paint.drawPixmap(0, 0, _pixmapBg);
                        }
                        

                        A Side discussion:
                        The solution above scales the pixmap from (0,0) do you've any idea how to scale the pixmap from the center of the pixmap?

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          mbnoimi
                          wrote on last edited by Chris Kawa
                          #12

                          @mbnoimi said:

                          A Side discussion:
                          The solution above scales the pixmap from (0,0) do you've any idea how to scale the pixmap from the center of the pixmap?

                          Forget it guys, I found out the solution as following:

                          void MainWindow::paintEvent(QPaintEvent *pe)
                          {
                              QPainter paint(this);
                              int widWidth = this->ui->centralWidget->width();
                              int widHeight = this->ui->centralWidget->height();
                              _pixmapBg = _pixmapBg.scaled(widWidth, widHeight, Qt::KeepAspectRatioByExpanding);
                              QPoint centerOfWidget = ui->centralWidget->rect().center();
                              QRect rectOfPixmap = _pixmapBg.rect();
                              rectOfPixmap.moveCenter(centerOfWidget);
                              paint.drawPixmap(rectOfPixmap.topLeft(), _pixmapBg);
                          }
                          
                          1 Reply Last reply
                          0
                          • Chris KawaC Offline
                            Chris KawaC Offline
                            Chris Kawa
                            Lifetime Qt Champion
                            wrote on last edited by Chris Kawa
                            #13

                            Yeah, another thing I noticed now is that you're using scaled(). That's also creating a copy of the image, thus is not very good performance-wise. It's better to just use one of the drawPixmap methods with explicit dimensions.
                            Besides the way you use scaled() is no good. If your image is 1000x1000 and you scale it to 10x10 and then back to say 500x500 it will be ugly blurred.

                            Calculating dimensions might be a little harder, but is a lot faster than copying bitmaps around.

                            This is one way to do the drawing (sorry if it's not perfect, It's kinda brain-fart :) )

                            QPainter painter(this);
                            
                            auto winSize = size();
                            auto pixmapRatio = (float)_pixmapBg.width() / _pixmapBg.height();
                            auto windowRatio = (float)winSize.width() / winSize.height();
                            
                            if(pixmapRatio > windowRatio)
                            {
                              auto newWidth = (int)(winSize.height() * pixmapRatio);
                              auto offset = (newWidth - winSize.width()) / -2;
                              painter.drawPixmap(offset, 0, newWidth, winSize.height(), _pixmapBg);
                            }
                            else
                            {
                              auto newHeight = (int)(winSize.width() / pixmapRatio);
                              painter.drawPixmap(0, 0, winSize.width(), newHeight, _pixmapBg);
                            }
                            
                            1 Reply Last reply
                            1
                            • M Offline
                              M Offline
                              mbnoimi
                              wrote on last edited by
                              #14

                              Thank you but it doesn't show it in the cente.

                              Any way loading _pixmapBg inside paintEvent() will fix scaled() issue.

                              1 Reply Last reply
                              0
                              • Chris KawaC Offline
                                Chris KawaC Offline
                                Chris Kawa
                                Lifetime Qt Champion
                                wrote on last edited by Chris Kawa
                                #15

                                Didn't noticed it should also center vertically. Easy fix:

                                else
                                {
                                  auto newHeight = (int)(winSize.width() / pixmapRatio);
                                  auto offset = (newHeight - winSize.height()) / -2;
                                  painter.drawPixmap(0, offset, winSize.width(), newHeight, _pixmapBg);
                                }
                                

                                As said before loading it and then scaling inside paint event is not a good idea. It's IO and then also copying. You're doing a lot of the same work over and over again.

                                1 Reply Last reply
                                1
                                • SGaistS SGaist

                                  Hi,

                                  AFAIK, background-size is not supported by Qt's style-sheet

                                  Maybe image might do the trick ?

                                  Hope it helps

                                  said_osloS Offline
                                  said_osloS Offline
                                  said_oslo
                                  wrote on last edited by
                                  #16

                                  @SGaist
                                  Screenshot 2021-07-05 at 14.43.26.png
                                  Hi.
                                  I have a problem to move to top my rfid interface.
                                  It's seems like my interface hidden by a logo or something else.
                                  please if you have some solutions. please shares it ?

                                  1 Reply Last reply
                                  0
                                  • SGaistS Offline
                                    SGaistS Offline
                                    SGaist
                                    Lifetime Qt Champion
                                    wrote on last edited by
                                    #17

                                    Hi,

                                    Not knowing anything about the code you are using, I cannot answer.

                                    Since you necro-posted this thread, did any of the advices put here help ? Do they relate to your issue ?

                                    Interested in AI ? www.idiap.ch
                                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                    1 Reply Last reply
                                    0

                                    • Login

                                    • Login or register to search.
                                    • First post
                                      Last post
                                    0
                                    • Categories
                                    • Recent
                                    • Tags
                                    • Popular
                                    • Users
                                    • Groups
                                    • Search
                                    • Get Qt Extensions
                                    • Unsolved