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. drags, drops, signals and slots of QGraphicsPixmapItem(s)...

drags, drops, signals and slots of QGraphicsPixmapItem(s)...

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 3 Posters 2.1k Views 3 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.
  • F Offline
    F Offline
    ffej2ffej
    wrote on last edited by
    #1
    I am creating a project which someday will resemble the game called freecell.  I'm still new-ish to QT, so I'm learning as I go along.
    For this game, I have created a QGraphicsScene which, once I've added all the elements, (cards in this case) will be contained by a QGraphicsView.  So far it's going fairly well.  By that I mean I can place the cards (which are descendants of QGraphicsPixmapItem) into the scene using the addItem() function of the scene.  Before being placed, the cards are made mobile using the setFlag() method with the parameters of (QGraphicsItem::ItemIsMoveable,true).
    So now I have cards and the user is free to move them anywhere within the scene.  What I need to do is restrict the places where the card may be dropped or, if that's not possible, changing the location of the card (setPos()) after it's dropped to a place that I've decided is appropriate.  I also would like to be able to examine the card when it's first clicked with intent to move, so the program can decide if there are other cards below it which must move also.
    My guess is that each card probably sends a signal when it's clicked, when it's moved, when it's finished moving and when it's un-clicked.  I think the scene will probably contain the slot that will react to these signals.  I don't know if this is accurate and even if it is, I don't know what the names of the signals or the slot(s) are.  Obviously, I have to override the existing slot(s) and connect them to the appropriate signals so I will need to know what they're called.  I've spent a considerable amount of time searching the help regarding QGraphicsView, QGraphicsItem, QGraphicsScene, etc. but have not been able to find out this information.  I looked through the help and tutorials for solutions to my needs, but the only thing I can find is a tutorial that starts with creating a drag and doing other things.  I don't want to create a drag, I want to REACT to a drag.  
    

    I am also aware that the possibility exists that I'm thinking about this completely the wrong way and there's actually another easy way to do it. I'd like to hear from the learned minds of QT users to set me straight.

    mrjjM 1 Reply Last reply
    0
    • F ffej2ffej
      I am creating a project which someday will resemble the game called freecell.  I'm still new-ish to QT, so I'm learning as I go along.
      For this game, I have created a QGraphicsScene which, once I've added all the elements, (cards in this case) will be contained by a QGraphicsView.  So far it's going fairly well.  By that I mean I can place the cards (which are descendants of QGraphicsPixmapItem) into the scene using the addItem() function of the scene.  Before being placed, the cards are made mobile using the setFlag() method with the parameters of (QGraphicsItem::ItemIsMoveable,true).
      So now I have cards and the user is free to move them anywhere within the scene.  What I need to do is restrict the places where the card may be dropped or, if that's not possible, changing the location of the card (setPos()) after it's dropped to a place that I've decided is appropriate.  I also would like to be able to examine the card when it's first clicked with intent to move, so the program can decide if there are other cards below it which must move also.
      My guess is that each card probably sends a signal when it's clicked, when it's moved, when it's finished moving and when it's un-clicked.  I think the scene will probably contain the slot that will react to these signals.  I don't know if this is accurate and even if it is, I don't know what the names of the signals or the slot(s) are.  Obviously, I have to override the existing slot(s) and connect them to the appropriate signals so I will need to know what they're called.  I've spent a considerable amount of time searching the help regarding QGraphicsView, QGraphicsItem, QGraphicsScene, etc. but have not been able to find out this information.  I looked through the help and tutorials for solutions to my needs, but the only thing I can find is a tutorial that starts with creating a drag and doing other things.  I don't want to create a drag, I want to REACT to a drag.  
      

      I am also aware that the possibility exists that I'm thinking about this completely the wrong way and there's actually another easy way to do it. I'd like to hear from the learned minds of QT users to set me straight.

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

      @ffej2ffej said in drags, drops, signals and slots of QGraphicsPixmapItem(s)...:

      I am creating a project which someday will resemble the game called freecell. I'm still new-ish to QT, so I'm learning as I go along.
      For this game, I have created a QGraphicsScene which, once I've added all the elements, (cards in this case) will be contained by a QGraphicsView. So far it's going fairly well. By that I mean I can place the cards (which are descendants of QGraphicsPixmapItem) into the scene using the addItem() function of the scene. Before being placed, the cards are made mobile using the setFlag() method with the parameters of (QGraphicsItem::ItemIsMoveable,true).
      So now I have cards and the user is free to move them anywhere within the scene. What I need to do is restrict the places where the card may be dropped or, if that's not possible, changing the location of the card (setPos()) after it's dropped to a place that I've decided is appropriate. I also would like to be able to examine the card when it's first clicked with intent to move, so the program can decide if there are other cards below it which must move also.
      My guess is that each card probably sends a signal when it's clicked, when it's moved, when it's finished moving and when it's un-clicked. I think the scene will probably contain the slot that will react to these signals. I don't know if this is accurate and even if it is, I don't know what the names of the signals or the slot(s) are. Obviously, I have to override the existing slot(s) and connect them to the appropriate signals so I will need to know what they're called. I've spent a considerable amount of time searching the help regarding QGraphicsView, QGraphicsItem, QGraphicsScene, etc. but have not been able to find out this information. I looked through the help and tutorials for solutions to my needs, but the only thing I can find is a tutorial that starts with creating a drag and doing other things. I don't want to create a drag, I want to REACT to a drag.
      I am also aware that the possibility exists that I'm thinking about this completely the wrong way and there's actually another easy way to do it. I'd like to hear from the learned minds of QT users to set me straight.

      Wow. Wall ;)

      anyway, i think you can use
      https://doc.qt.io/qt-5/qgraphicsitem.html#itemChange
      with this
      https://doc.qt.io/qt-5/qgraphicsitem.html#GraphicsItemChange-enum

      QGraphicsItem::ItemPositionChange

      as you can see from sample in first link. its possible to return another pos and that gives the ability
      to snap to cards or return the orginal value to cancel move.

      note.
      you most likely need to do
      setFlag( QGraphicsItem::ItemSendsScenePositionChanges, true );
      for the items to have it send the needed info.

      here is sample that snaps to a grid.
      https://www.walletfox.com/course/qgraphicsitemsnaptogrid.php

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

        Hi,

        Just in case, the Graphics View examples already provides several nice starting points.

        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
        1
        • mrjjM mrjj

          @ffej2ffej said in drags, drops, signals and slots of QGraphicsPixmapItem(s)...:

          I am creating a project which someday will resemble the game called freecell. I'm still new-ish to QT, so I'm learning as I go along.
          For this game, I have created a QGraphicsScene which, once I've added all the elements, (cards in this case) will be contained by a QGraphicsView. So far it's going fairly well. By that I mean I can place the cards (which are descendants of QGraphicsPixmapItem) into the scene using the addItem() function of the scene. Before being placed, the cards are made mobile using the setFlag() method with the parameters of (QGraphicsItem::ItemIsMoveable,true).
          So now I have cards and the user is free to move them anywhere within the scene. What I need to do is restrict the places where the card may be dropped or, if that's not possible, changing the location of the card (setPos()) after it's dropped to a place that I've decided is appropriate. I also would like to be able to examine the card when it's first clicked with intent to move, so the program can decide if there are other cards below it which must move also.
          My guess is that each card probably sends a signal when it's clicked, when it's moved, when it's finished moving and when it's un-clicked. I think the scene will probably contain the slot that will react to these signals. I don't know if this is accurate and even if it is, I don't know what the names of the signals or the slot(s) are. Obviously, I have to override the existing slot(s) and connect them to the appropriate signals so I will need to know what they're called. I've spent a considerable amount of time searching the help regarding QGraphicsView, QGraphicsItem, QGraphicsScene, etc. but have not been able to find out this information. I looked through the help and tutorials for solutions to my needs, but the only thing I can find is a tutorial that starts with creating a drag and doing other things. I don't want to create a drag, I want to REACT to a drag.
          I am also aware that the possibility exists that I'm thinking about this completely the wrong way and there's actually another easy way to do it. I'd like to hear from the learned minds of QT users to set me straight.

          Wow. Wall ;)

          anyway, i think you can use
          https://doc.qt.io/qt-5/qgraphicsitem.html#itemChange
          with this
          https://doc.qt.io/qt-5/qgraphicsitem.html#GraphicsItemChange-enum

          QGraphicsItem::ItemPositionChange

          as you can see from sample in first link. its possible to return another pos and that gives the ability
          to snap to cards or return the orginal value to cancel move.

          note.
          you most likely need to do
          setFlag( QGraphicsItem::ItemSendsScenePositionChanges, true );
          for the items to have it send the needed info.

          here is sample that snaps to a grid.
          https://www.walletfox.com/course/qgraphicsitemsnaptogrid.php

          F Offline
          F Offline
          ffej2ffej
          wrote on last edited by
          #4

          @mrjj I read the pages referred in your reply and added the ItemPositionHasChanged() function into the Card object. I also added the setFlag(QGraphicsItem::ItemSendsGeometryChanges,true) statement per the documentation.
          The function was not called when I moved the items with the mouse so I added 2 setPos() statements into the object that creates and places the cards. It still didn't call the ItemPositionHasChanged() function. AAAaaaargh!
          P.S. I tested whether the function was called by adding a qDebug("some text") statement to the function. No qDebugs occurred.

          mrjjM 1 Reply Last reply
          0
          • F ffej2ffej

            @mrjj I read the pages referred in your reply and added the ItemPositionHasChanged() function into the Card object. I also added the setFlag(QGraphicsItem::ItemSendsGeometryChanges,true) statement per the documentation.
            The function was not called when I moved the items with the mouse so I added 2 setPos() statements into the object that creates and places the cards. It still didn't call the ItemPositionHasChanged() function. AAAaaaargh!
            P.S. I tested whether the function was called by adding a qDebug("some text") statement to the function. No qDebugs occurred.

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

            @ffej2ffej
            Hi
            did you use the override keyword to be truly sure you did get function
            signature 100% right ?
            Without code, its hard to guess at :)

            F 1 Reply Last reply
            0
            • mrjjM mrjj

              @ffej2ffej
              Hi
              did you use the override keyword to be truly sure you did get function
              signature 100% right ?
              Without code, its hard to guess at :)

              F Offline
              F Offline
              ffej2ffej
              wrote on last edited by
              #6

              @mrjj
              Here is all the code with horizontal dividers to distinguish the beginnings and endings of all the files.
              ---------------------------------------card.h----------------------------------------
              #ifndef CARD_H
              #define CARD_H
              #include <QGraphicsPixmapItem>
              #include <QGraphicsSceneDragDropEvent>

              class Card : public QGraphicsPixmapItem
              {
              public:
              Card();
              int suit;
              int number;
              void setSuit(int sentSuit);
              void setNumber(int sentNumber);
              protected:
              //void dragEnterEvent(QGraphicsSceneDragDropEvent *event) override;
              void QGraphicsPixmapItem::ItemPositionHasChanged() override;
              };

              #endif // CARD_H
              -----------------------------------end of card.h-------------------------------------

              ----------------------------------card.cpp-------------------------------------------
              #include "card.h"
              #include <QDebug>

              Card::Card()
              {
              //ItemSendsGeometryChanges
              }

              void ItemPositionHasChanged()
              {
              qDebug("Card has moved.");
              }
              ------------------------------------end of card.cpp----------------------------------
              -------------------------------------game.h------------------------------------------
              #ifndef GAME_H
              #define GAME_H
              #include <QGraphicsView>

              class Game : public QGraphicsView
              {
              public:
              Game();//constructor (duh!)
              };

              #endif // GAME_H
              -----------------------------------end of game.h-------------------------------------
              ------------------------------------game.cpp-----------------------------------------
              #include "game.h"
              #include <QGraphicsScene>
              #include <card.h>
              #include <QImage>

              Game::Game()
              {
              QGraphicsScene *scene = new QGraphicsScene();
              Card *card1 = new Card();
              Card *card2 = new Card();
              Card *bigCard = new Card();
              card1->setPixmap(QPixmap(":/images/1s.png"));
              card2->setPixmap(QPixmap(":/images/2s.png"));
              bigCard->setPixmap(QPixmap(":/images/1sbigger.png"));
              card1->setFlag(QGraphicsItem::ItemIsMovable,true);
              card2->setFlag(QGraphicsItem::ItemIsMovable,true);
              bigCard->setFlag(QGraphicsItem::ItemIsMovable,true);
              bigCard->setFlag(QGraphicsItem::ItemSendsGeometryChanges,true);
              card1->setPos(0,0);
              card2->setPos(20,0);
              bigCard->setPos(30,30);//arbitrary numbers. Sometimes a cigar is just a cigar.
              scene->addItem(card1);
              scene->addItem(card2);
              scene->addItem(bigCard);
              QGraphicsView *theview = new QGraphicsView(scene);
              theview->show();
              theview->setFixedSize(800,600);//make sure to adjust this to a proper size for the game!!!!!!!!!!!!!!!!!!!!!
              scene->setSceneRect(0,0,800,600);
              setBackgroundBrush(QBrush(QImage(":/images/cardsMoveBG.png")));//Doesn't work here or on the video game from tutorial.
              bigCard->setPos(40,40);
              bigCard->setPos(50,50);
              }
              -----------------------------------------end of game.cpp-------------------------------
              --------------------------------------------main.cpp-----------------------------------
              #include <QApplication>
              #include "game.h"

              int main(int argc, char *argv[])
              {
              QApplication a(argc, argv);
              Game *theGame = new Game();
              //theGame->show();//this is weird. It shows some mysterious window that is NOT the window I created and specificied all the
              //contents, etc. However, if I don't create a Game object, nothing shows at all.

              return a.exec();
              

              }
              ----------------------------------------end of main.cpp-------------------------------

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

                Why are you creating a subclass of QGrapchicsView in which you create a QGraphicsView object and show that one separately ?

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

                F 1 Reply Last reply
                1
                • F Offline
                  F Offline
                  ffej2ffej
                  wrote on last edited by
                  #8

                  BTW, I sent the code with the override specified. I cannot, however, compile with it like that because it causes an error.

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

                    The error being that it's not overriding anything known ?

                    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
                    1
                    • SGaistS SGaist

                      Why are you creating a subclass of QGrapchicsView in which you create a QGraphicsView object and show that one separately ?

                      F Offline
                      F Offline
                      ffej2ffej
                      wrote on last edited by
                      #10

                      @SGaist I opened and studied both the 40,000 chips and the robot drag&drop examples. I'm afraid I could not figure out how they worked or how I could apply them to my work. Maybe I'm too stoopid to be a programmer. I miss doing assembly language where you simply put a character (optionally, a color too) in a memory spot and it appears on the screen. In graphics modes, you instructed BIOS of the color you want at the x and y coordinates you want then called a function and it appeared. I'm glad they simplified it for c++, he said sarcastically.

                      mrjjM 1 Reply Last reply
                      0
                      • F ffej2ffej

                        @SGaist I opened and studied both the 40,000 chips and the robot drag&drop examples. I'm afraid I could not figure out how they worked or how I could apply them to my work. Maybe I'm too stoopid to be a programmer. I miss doing assembly language where you simply put a character (optionally, a color too) in a memory spot and it appears on the screen. In graphics modes, you instructed BIOS of the color you want at the x and y coordinates you want then called a function and it appeared. I'm glad they simplified it for c++, he said sarcastically.

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

                        @ffej2ffej
                        Hi
                        Well the step from good old direct framebuffer writing - to full blown object orientated
                        GUI building is not trivial so some stumbling blocks are to be expected.
                        The code looks ok but Game class IS a QGraphicsView already so no need to
                        create another inside Game constructor.
                        QGraphicsView *theview = new QGraphicsView(scene); // seems not needed.
                        so should fix that, OR remove the class Game : public QGraphicsView
                        part so its a clean class and then let it setup the View. ( as you do in that code)

                        However, im not sure what exact error you get so its hard to help.

                        F 1 Reply Last reply
                        1
                        • F Offline
                          F Offline
                          ffej2ffej
                          wrote on last edited by
                          #12

                          If I state
                          void QGraphicsPixmapItem::ItemPositionHasChanged() override;
                          I get
                          non-friend class member 'ItemPositionHasChanged' cannot have a qualified name

                          If I state
                          void ItemPositionHasChanged() override;
                          I get
                          only virtual member functions can be marked 'override'
                          I wish I knew what either of those errors MEANT, let alone how to solve them.

                          1 Reply Last reply
                          0
                          • mrjjM mrjj

                            @ffej2ffej
                            Hi
                            Well the step from good old direct framebuffer writing - to full blown object orientated
                            GUI building is not trivial so some stumbling blocks are to be expected.
                            The code looks ok but Game class IS a QGraphicsView already so no need to
                            create another inside Game constructor.
                            QGraphicsView *theview = new QGraphicsView(scene); // seems not needed.
                            so should fix that, OR remove the class Game : public QGraphicsView
                            part so its a clean class and then let it setup the View. ( as you do in that code)

                            However, im not sure what exact error you get so its hard to help.

                            F Offline
                            F Offline
                            ffej2ffej
                            wrote on last edited by
                            #13

                            @mrjj The problem about the notifications of dragging and dropping are still unsolved but I want to thank you for pointing out the fact that I had made the Game object a descendant of QGraphicsView. The details of how I made that mistake are long a boring and suffice to say I've fixed it. I still, however, am not notified when the user drags and drops a card.

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

                              @ffej2ffej said in drags, drops, signals and slots of QGraphicsPixmapItem(s)...:

                              ItemPositionHasChanged

                              Aren't you trying to override an enum value ?

                              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
                              1
                              • mrjjM Offline
                                mrjjM Offline
                                mrjj
                                Lifetime Qt Champion
                                wrote on last edited by
                                #15

                                Hi
                                Its
                                QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override;
                                it has to match exactly.

                                1 Reply Last reply
                                2

                                • Login

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