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. How to invoke QBrush.setTexture() with QPixmap on QGraphicsRectItem?
Forum Updated to NodeBB v4.3 + New Features

How to invoke QBrush.setTexture() with QPixmap on QGraphicsRectItem?

Scheduled Pinned Locked Moved Solved General and Desktop
24 Posts 4 Posters 7.2k Views 2 Watching
  • 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.
  • K Offline
    K Offline
    Kevin Zhong
    wrote on last edited by VRonin
    #1

    I am trying to use QBrush.setTexture() to update QGraphicsRectItem with a .png background. But I cannot set the exact size to fit the QGraphicsRectItem with the QPixMap.

    brush->setTexture((QPixmap(":/images/h_shutdown.png"))
    .scaled(70,30,Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
    

    But the .png always piled to extend from center crossed.
    As the png in the link:
    Example Image

    Do you have any suggestions?

    BRs
    Kevin

    1 Reply Last reply
    0
    • m.sueM Offline
      m.sueM Offline
      m.sue
      wrote on last edited by
      #2

      Hi,
      you can try to use a QGraphicsProxyWidget containing a QLabel instead. The latter can show the pixmap directly.
      -Michael.

      1 Reply Last reply
      0
      • K Offline
        K Offline
        Kevin Zhong
        wrote on last edited by
        #3

        Thank you very much for your quick answer!
        Do you have code example for reference?

        On more thing, I am not sure if the HoverEvent and contextMenu still work after using QGraphicsProxyWidget?

        BRs
        Kevin

        1 Reply Last reply
        0
        • m.sueM Offline
          m.sueM Offline
          m.sue
          wrote on last edited by m.sue
          #4

          Hi,
          You create a QLabel and set the pixmap with the setPixmap function. You create a QGraphicsProxyWidget and set the label with the setWidget function. Everything else you do as with the rect item you had before.

          Hover- and context menu events should work as with any QGraphicsItem.
          -Michael.

          1 Reply Last reply
          0
          • A Offline
            A Offline
            Asperamanca
            wrote on last edited by
            #5

            QGraphicsProxyWidget is not a good choice, because it's terribly slow and unnecessarily complex.

            How about QGraphicsPixmapItem?

            1 Reply Last reply
            1
            • K Offline
              K Offline
              Kevin Zhong
              wrote on last edited by
              #6

              Thanks for your suggestion.

              Maybe I don't make myself clear.

              What I want to implement a QGraphicsRectItem with a png as background.

              Is it possible to use QGraphicsPixmapItem as the background for QGraphicsRectItem?

              BRs
              kevin

              1 Reply Last reply
              0
              • A Offline
                A Offline
                Asperamanca
                wrote on last edited by Asperamanca
                #7

                You could add a QGraphicsPixmapItem as a child to the QGraphicsRectItem. To get the clipping and z-Order right, you would need to set QGraphicsItem::ItemClipsChildrenToShape (to the QGraphicsRectItem)
                and QGraphicsItem::ItemStacksBehindParent (to the QGraphicsPixmapItem)

                An alternative is to write a class derived from QGraphicsRectItem, overload paint(), paint the background pixmap, then call the base class paint().

                Edit: On re-reading your initial post, this might not be quite what you need. In this case, it might be easier to implement your own QGraphicsItem and write the paint () method exactly as you want it.

                1 Reply Last reply
                1
                • K Offline
                  K Offline
                  Kevin Zhong
                  wrote on last edited by
                  #8

                  Be honest, I am not very familiar with Qt.

                  Could you please show me some example code?

                  Many thanks.

                  BRs
                  Kevin

                  mrjjM 1 Reply Last reply
                  0
                  • K Kevin Zhong

                    Be honest, I am not very familiar with Qt.

                    Could you please show me some example code?

                    Many thanks.

                    BRs
                    Kevin

                    mrjjM Offline
                    mrjjM Offline
                    mrjj
                    Lifetime Qt Champion
                    wrote on last edited by mrjj
                    #9

                    @Kevin-Zhong
                    Hi
                    The solution mentioned is to create your own class
                    http://www.bogotobogo.com/Qt/Qt5_QGraphicsView_QGraphicsScene_QGraphicsItems.php

                    Something like. ( pseudo code-ish)

                    class MyItem :public QGraphicsRectItem  ( OR QGraphicsItem )
                    {
                    public:
                    ...
                        // overriding paint()
                    void paint(QPainter * painter,   const QStyleOptionGraphicsItem * option,   QWidget * widget) 
                    {
                      // draw pixmap
                      QPixmap pix(":/images/h_shutdown.png")
                      painter->drawPixmap(pix);
                      // draw normally
                      QGraphicsRectItem::paint(painter, option, widget); ( or QGraphicsItem::paint)
                     }
                    };
                    
                    1 Reply Last reply
                    0
                    • K Offline
                      K Offline
                      Kevin Zhong
                      wrote on last edited by
                      #10

                      Thanks for all of you kindly support.

                      It really works.

                      One more questions, How can I update the png after the item status changed?
                      I mean if the item changed status from shutdown to startup, the png should changed into ":/images/h_startup.png".

                      mrjjM 1 Reply Last reply
                      0
                      • K Kevin Zhong

                        Thanks for all of you kindly support.

                        It really works.

                        One more questions, How can I update the png after the item status changed?
                        I mean if the item changed status from shutdown to startup, the png should changed into ":/images/h_startup.png".

                        mrjjM Offline
                        mrjjM Offline
                        mrjj
                        Lifetime Qt Champion
                        wrote on last edited by mrjj
                        #11

                        @Kevin-Zhong

                        • One more questions, How can I update the png after the item status changed?

                        You make the class know which image to draw via variable

                        
                        **NEW** 
                        const int StartImage=1; ( or use enum)
                        const int StopImage=2;
                        
                        class MyItem :public QGraphicsRectItem  ( OR QGraphicsItem ) {
                        int Status=StartImage; // some flag to tell if start or stop  **NEW**
                        public:
                        void SetStatus(int newStatus) {  Status=newStatus;  update(); /* this makes it redraw ( i hope) */ } **NEW**
                        ...
                            // overriding paint()
                        void paint(QPainter * painter,   const QStyleOptionGraphicsItem * option,   QWidget * widget) 
                        {
                          // draw pixmap
                          QPixmap pixStart(":/images/h_startdown.png"); // could be loaded in constructor so we dont do each draw
                          QPixmap pixStop(":/images/h_shutdown.png");
                        // draw one or the other   
                        if (Status == StartImage )
                          painter->drawPixmap(pixStart);
                          else
                          painter->drawPixmap(pixStop);
                        
                          // draw normally
                          QGraphicsRectItem::paint(painter, option, widget); ( or QGraphicsItem::paint)
                         }
                        };
                        
                        

                        Then from outside, you can do

                        myitem->SetStatus(StartImage);
                        or
                        myitem->SetStatus(StopImage);

                        K 1 Reply Last reply
                        0
                        • K Offline
                          K Offline
                          Kevin Zhong
                          wrote on last edited by
                          #12

                          Thank you very MUCH!!!
                          It's very helpful.

                          You are so nice!

                          BRs
                          Kevin

                          1 Reply Last reply
                          1
                          • mrjjM mrjj

                            @Kevin-Zhong

                            • One more questions, How can I update the png after the item status changed?

                            You make the class know which image to draw via variable

                            
                            **NEW** 
                            const int StartImage=1; ( or use enum)
                            const int StopImage=2;
                            
                            class MyItem :public QGraphicsRectItem  ( OR QGraphicsItem ) {
                            int Status=StartImage; // some flag to tell if start or stop  **NEW**
                            public:
                            void SetStatus(int newStatus) {  Status=newStatus;  update(); /* this makes it redraw ( i hope) */ } **NEW**
                            ...
                                // overriding paint()
                            void paint(QPainter * painter,   const QStyleOptionGraphicsItem * option,   QWidget * widget) 
                            {
                              // draw pixmap
                              QPixmap pixStart(":/images/h_startdown.png"); // could be loaded in constructor so we dont do each draw
                              QPixmap pixStop(":/images/h_shutdown.png");
                            // draw one or the other   
                            if (Status == StartImage )
                              painter->drawPixmap(pixStart);
                              else
                              painter->drawPixmap(pixStop);
                            
                              // draw normally
                              QGraphicsRectItem::paint(painter, option, widget); ( or QGraphicsItem::paint)
                             }
                            };
                            
                            

                            Then from outside, you can do

                            myitem->SetStatus(StartImage);
                            or
                            myitem->SetStatus(StopImage);

                            K Offline
                            K Offline
                            Kevin Zhong
                            wrote on last edited by
                            #13

                            @mrjj

                            I try to update the png for the item when some status changed.

                            But every time I need to trigger the ui to repaint, it seems that it never repaint the ui unless there are some change in the UI, such as move cursor or focus on the UI.

                            Is there any way to update the UI automatically?

                            BRs
                            Kevin

                            mrjjM 1 Reply Last reply
                            0
                            • A Offline
                              A Offline
                              Asperamanca
                              wrote on last edited by
                              #14

                              Calling update() on the item should do the trick.

                              1 Reply Last reply
                              1
                              • K Kevin Zhong

                                @mrjj

                                I try to update the png for the item when some status changed.

                                But every time I need to trigger the ui to repaint, it seems that it never repaint the ui unless there are some change in the UI, such as move cursor or focus on the UI.

                                Is there any way to update the UI automatically?

                                BRs
                                Kevin

                                mrjjM Offline
                                mrjjM Offline
                                mrjj
                                Lifetime Qt Champion
                                wrote on last edited by
                                #15

                                @Kevin-Zhong
                                Hi
                                Did you call the
                                void SetStatus(int newStatus) {
                                Status=newStatus;
                                update(); /* this makes it redraw ( i hope) */ << this should make it draw the other bitmap?
                                }

                                K 1 Reply Last reply
                                0
                                • mrjjM mrjj

                                  @Kevin-Zhong
                                  Hi
                                  Did you call the
                                  void SetStatus(int newStatus) {
                                  Status=newStatus;
                                  update(); /* this makes it redraw ( i hope) */ << this should make it draw the other bitmap?
                                  }

                                  K Offline
                                  K Offline
                                  Kevin Zhong
                                  wrote on last edited by
                                  #16

                                  @mrjj

                                  The behavior is the same as I mentioned before whatever I use update or repaint. Actually, I prefer to use repaint because I need to refresh the item secondly.

                                  BRs
                                  Kevin

                                  mrjjM 1 Reply Last reply
                                  0
                                  • K Kevin Zhong

                                    @mrjj

                                    The behavior is the same as I mentioned before whatever I use update or repaint. Actually, I prefer to use repaint because I need to refresh the item secondly.

                                    BRs
                                    Kevin

                                    mrjjM Offline
                                    mrjjM Offline
                                    mrjj
                                    Lifetime Qt Champion
                                    wrote on last edited by
                                    #17

                                    @Kevin-Zhong
                                    Ok, im not sure why.
                                    maybe update() dont trigger painter.
                                    Would need to debug to know.
                                    Normally it just works.

                                    K 1 Reply Last reply
                                    0
                                    • mrjjM mrjj

                                      @Kevin-Zhong
                                      Ok, im not sure why.
                                      maybe update() dont trigger painter.
                                      Would need to debug to know.
                                      Normally it just works.

                                      K Offline
                                      K Offline
                                      Kevin Zhong
                                      wrote on last edited by
                                      #18

                                      @mrjj

                                      I try to overload the paintEvent in my own code.
                                      But after I call item.repaint() the paintEvent was not invoked.

                                      But this is the interface description for Qt 5.6.

                                      [slot] void QWidget::repaint()
                                      Repaints the widget directly by calling paintEvent() immediately, unless updates are disabled or the widget is hidden.
                                      We suggest only using repaint() if you need an immediate repaint, for example during animation. In almost all circumstances update() is better, as it permits Qt to optimize for speed and minimize flicker.
                                      Warning: If you call repaint() in a function which may itself be called from paintEvent(), you may get infinite recursion. The update() function never causes recursion.
                                      See also update(), paintEvent(), and setUpdatesEnabled().

                                      1 Reply Last reply
                                      0
                                      • mrjjM Offline
                                        mrjjM Offline
                                        mrjj
                                        Lifetime Qt Champion
                                        wrote on last edited by mrjj
                                        #19

                                        Hi
                                        are we still talking about the QGraphicsItem ?
                                        As far as I know they do not have paintEvent only
                                        void paint(QPainter * painter,xx)

                                        So item.update() should trigger it ?

                                        Maybe show full code of what you are doing ?

                                        K 1 Reply Last reply
                                        0
                                        • mrjjM mrjj

                                          Hi
                                          are we still talking about the QGraphicsItem ?
                                          As far as I know they do not have paintEvent only
                                          void paint(QPainter * painter,xx)

                                          So item.update() should trigger it ?

                                          Maybe show full code of what you are doing ?

                                          K Offline
                                          K Offline
                                          Kevin Zhong
                                          wrote on last edited by
                                          #20

                                          @mrjj

                                          My code is a little bit complex.
                                          Let's recap my original purpose.
                                          At the beginning, I just want to use a png as background at the GraphicsRectItem.
                                          I tried to use code below:

                                          QImage mage = (QImage(":/images/h_" + filename + ".png"));                        
                                          brush.setTextureImage(image.scaled(70,30,Qt::KeepAspectRatio, Qt::FastTransformation));
                                          

                                          The result is not what I want.
                                          So, I try to follow your guys' suggestion.

                                          map = QPixmap(":/images/h_" + statusStr + ".png");
                                          painter->drawPixmap((int)x, (int)y, 40, 50, map);
                                          

                                          It's really works, the png can be shown correctly, not collage.
                                          But the png cannot be redraw immediately only I move the cursor or focus the window.
                                          So, is it possible to show the png in the GraphicsRectItem? Because I need to show lots of triangle, rectangle and cricle on the QGraphsicsView with hoverEvent and click Event.

                                          BRs
                                          Kevin

                                          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