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] Signal & Slot to QGraphicView items
QtWS25 Last Chance

[Solved] Signal & Slot to QGraphicView items

Scheduled Pinned Locked Moved General and Desktop
16 Posts 4 Posters 7.3k 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.
  • T Offline
    T Offline
    ThaRez
    wrote on last edited by
    #1

    Hello
    I have a main window to which a couple of QSpinBox es are attached, as well as a graphicsview. To the graphicsview there's a scene attached which then has qgraphicsview items attached. These again have graphicsviewitem attached to them as well, making the full path to the final item:

    mainwindow->graphicsview->scene->rootgraphicsviewitem->childgraphicsviewitem

    The childgraphicsviewitem inherits QObject making it support signal/slots, and emits the following signal:

    @void updateCordSpinBox(int);@

    I'm now wondering how to attach this signal to the setValue(int) slot of the spinbox? The following naturally fails:

    @QObject::connect(this,SIGNAL(updateCordSpinBox(int)),spinBox_Y2,SLOT(setValue(int)));@

    but I don't know what to set as the target object...

    If any additional information is needed,
    please don't hesitate to request and I'll do my best to respond. Thank you!
    Best regards
    Richard

    1 Reply Last reply
    0
    • EddyE Offline
      EddyE Offline
      Eddy
      wrote on last edited by
      #2

      maybe

      @ui->spinBox_Y2 @

      if you used Qt Designer to make your mainwindow, are you?

      what error do you get exactly?

      Qt Certified Specialist
      www.edalsolutions.be

      1 Reply Last reply
      0
      • T Offline
        T Offline
        ThaRez
        wrote on last edited by
        #3

        first "spinBox_Y2 was not declared in this scope" and with the "ui->" "ui was not declared in this scope"

        The QGraphicsView is added via the designer. The scene is attached using:

        @ scene = new QGraphicsScene();

        ui->graphicsView->setScene(scene);
        ui->graphicsView->setDragMode(QGraphicsView::RubberBandDrag);
        ui->graphicsView->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
        ui->graphicsView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
        

        @

        The rootgraphicsitem is then attached to the scene with:

        @myGItem = new GItem(this, QPixmap(folderPath+"/"+fileName), true, 0, scene);@

        and finally the childitem is added within the myGItem:

        @ Node *node = new Node;
        node->setText("Node");

        node->setPos(cord);
        scene->addItem(node);
        
        scene->clearSelection();
        node->setSelected(true);
        

        @

        (there can be several children attached to one rootgraphics item) Hopefully this clearified the situation...Thanks
        Best regards
        Richard

        ps. heh actually just noticed as I copied the code that the children aren't attached to the rootgraphicsitem but directly to the scene...but I can't really see how this would affect the situation..

        1 Reply Last reply
        0
        • EddyE Offline
          EddyE Offline
          Eddy
          wrote on last edited by
          #4

          Have you checked the scope of your varables?

          Where did you put the connect? In the constructor? Can you show its code? Also the definition of you slot.

          Qt Certified Specialist
          www.edalsolutions.be

          1 Reply Last reply
          0
          • T Offline
            T Offline
            ThaRez
            wrote on last edited by
            #5

            The connect instruction is in the constructor of the "Node", that is the child graphicalitem. Unfortunately I don't really know what to check for regarding the scope...I'm new to Qt and still a bit unsure with the signal/slot principle.

            To be able to connect these, does the element need to know the full path to the object to which it refers to, or does the macros take care of this? In case they need to know the full path, can it be extracted from the information available, being the nodes parent is a graphical scene (though there should be the myGItem in between) which is attached to a main window that has the object in question attached to it? Or do I need to pass a pointer to the main window along the creation path all the way to the Node?

            I'll post the code asap, but I'm away for the weekend and unfortunately do not have access to my code as I forgot to copy it with me... :( But I'll follow the forum and try to reply as well as possible.

            Thank you for you assistance!
            Best regards
            Richard

            1 Reply Last reply
            0
            • Z Offline
              Z Offline
              ZapB
              wrote on last edited by
              #6

              It depends on which method you have used to create your UI widgets from the ui_*.h file. Inheritance vs encapsulation. Please post your code.

              Nokia Certified Qt Specialist
              Interested in hearing about Qt related work

              1 Reply Last reply
              0
              • Z Offline
                Z Offline
                ZapB
                wrote on last edited by
                #7

                Also, you could just inherit your QGV items from [[doc:QGraphicsObject]] to enable signal/slot functionality.

                Nokia Certified Qt Specialist
                Interested in hearing about Qt related work

                1 Reply Last reply
                0
                • T Offline
                  T Offline
                  ThaRez
                  wrote on last edited by
                  #8

                  Hello
                  OK so here's the constructor of each class as well the the lines creating the objects:

                  @MainWindow::MainWindow(QWidget *parent) :
                  QMainWindow(parent),
                  ui(new Ui::MainWindow)
                  {
                  ui->setupUi(this);

                  setUpModels();
                  setUpScene();
                  setUpConnections();
                  
                  pop = new Preview(this);
                  clickedFile = "";
                  

                  }

                  GItem::GItem(QObject *root, const QPixmap &pixmap, bool hidden, QGraphicsItem *parent,
                  QGraphicsScene *scene)
                  : QObject(root), QGraphicsPixmapItem(pixmap, parent, scene){

                  this->scene = scene;
                  this->mainImage = pixmap;
                  
                  if(hidden)
                      this->hideElement();
                  
                  QObject::connect(this,SIGNAL(clicked(QPointF)),this,SLOT(addNode(QPointF)));
                  

                  }

                  Node::Node(QObject *parent) :
                  QObject(parent)
                  {
                  myTextColor = Qt::red;
                  myOutlineColor = Qt::red;
                  setFlags(ItemIsSelectable);

                  QObject::connect(this,SIGNAL(updateCordSpinBox(int)),spinBox_Y2,SLOT(setValue(int)));
                  
                  emit updateCordSpinBox(15); // to test the connection
                  

                  }

                  // Scene setup

                  void MainWindow::setUpScene(){
                  scene = new QGraphicsScene();

                  ui->graphicsView->setScene(scene);
                  ui->graphicsView->setDragMode(QGraphicsView::RubberBandDrag);
                  ui->graphicsView->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
                  ui->graphicsView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
                  

                  }

                  // Constructing the objects:
                  MainWindow w;
                  GItem *myGItem = new GItem(this, QPixmap("C:/test/ab.png"), false, 0, scene);
                  Node *node = new Node(this);@

                  With high probability there's something really wrong with the whole logic... Both the GItem and the Node class begin with the "Q_OBJECT" macro.
                  B.R.
                  Richard

                  1 Reply Last reply
                  0
                  • L Offline
                    L Offline
                    ludde
                    wrote on last edited by
                    #9

                    If you want to connect the Node object to the spinbox in the Node constructor, the Node class must know about the spinbox. You could accomplish this by passing the spinbox as an extra parameter in the Node constructor.

                    But, you probably don't want the Node class to know about the spinbox. A better solution is probably to connect the Node object to the spinbox somewhere else, e.g. in the code that uses the Node constructor to create the Node object. Not sure this is universally true, but I tend to think that connecting two objects a and b is usually better done by the object creating a and/or b, rather than a or b themselves.

                    1 Reply Last reply
                    0
                    • T Offline
                      T Offline
                      ThaRez
                      wrote on last edited by
                      #10

                      If I do it this way, and create multiple instances of the Node, do I then need to connect each one of the new instances after creating them?

                      And do yo happen to know if this is the correct practice, or if a pointer should be passed all the way to the node?

                      1 Reply Last reply
                      0
                      • Z Offline
                        Z Offline
                        ZapB
                        wrote on last edited by
                        #11

                        It depends on the use case but often connections between objects are made by a higher-level object that has knowledge of how they should interact. Usually when designing QObject classes you aim for loose coupling ie so that your class does not directly depend upon knowledge of another QObject subclass.

                        Having said that it is sometimes convenient to have some level of coupling if the classes in question really are closely related. If your item must always be connected to a spinbox then fine pass the pointer down and have the item make the connection.

                        If the item may sometimes not be used in conjunction with a spin box then I would recommend having your higher-level object make the connection.

                        Nokia Certified Qt Specialist
                        Interested in hearing about Qt related work

                        1 Reply Last reply
                        0
                        • T Offline
                          T Offline
                          ThaRez
                          wrote on last edited by
                          #12

                          slowly getting the hang of this... though I'm still a bit uncertain how to make the proper connection...
                          Just to try I made a connection inside the mainwindo:

                          @connect(this,SIGNAL(udsb(int)),ui->spinBox_X1,SLOT(setValue(int)));@

                          were the udsb was a signal emitted with a static value when a pushbutton was hit, just to see the value of the spinbox actually changed. This worked fine. My problem is I can't manage to duplicate this from the GItem object... I've made a private MainWindow pointer variable to the GItem class,

                          @MainWindow *root;@

                          and when creating the object I pass the main window to that pointer.

                          @GItem *myGItem = new GItem(this, QPixmap("C:/test/ab.png"), false, 0, scene);@

                          were

                          @GItem::GItem(MainWindow *root, const QPixmap &pixmap, bool hidden, QGraphicsItem *parent,
                          QGraphicsScene *scene)
                          : QObject(root), QGraphicsPixmapItem(pixmap, parent, scene){
                          this->root = root;
                          this->scene = scene;
                          this->mainImage = pixmap;@

                          The nodes are then created inside myGItem after which I try to connect them to the spinbox, without success...

                          @Node *node = new Node(this);
                          node->setText("Node");

                          node->setPos(cord);
                          scene->addItem(node);
                          
                          scene->clearSelection();
                          node->setSelected(true);
                          

                          // qDebug() << root->
                          QObject::connect(node,SIGNAL(updateCordSpinBox(int)),root->ui->spinBox_X1,SLOT(setValue(int)));

                          linkList << node;
                          qDebug() <&lt; linkList.length();@
                          

                          I get a error saying

                          "invalide use of incomplete type struct Ui::MainWindow"

                          The ui variable (holding the UI is set as private, but it didn't help making it public... Any suggestions how to correctly pass a pointer so that I can refer to the spinbox element, added via the designer to ui?
                          Thanks
                          Richard

                          1 Reply Last reply
                          0
                          • Z Offline
                            Z Offline
                            ZapB
                            wrote on last edited by
                            #13

                            Quick work around is to add:

                            @
                            #include "ui_mainwindow.h"
                            @

                            in your item class implementation. The error just means that your item class has no idea what the Ui::MainWindow type is.

                            A better solution would be to have your main window pass through a pointer to the respective spin box rather than a pointer to itself.

                            Nokia Certified Qt Specialist
                            Interested in hearing about Qt related work

                            1 Reply Last reply
                            0
                            • T Offline
                              T Offline
                              ThaRez
                              wrote on last edited by
                              #14

                              The problem is there are several spin boxes and then I'd have to pass a pointer to all of them (?). By passing the main window, can't I then access them all?

                              1 Reply Last reply
                              0
                              • T Offline
                                T Offline
                                ThaRez
                                wrote on last edited by
                                #15

                                YEY the line you suggested did the trick!! :D Now I'm only curious if this is the best way to do it or if there's another way to pass the information about the multiple spinboxes from the ui...

                                A HUGE thanks to all you that participated in helping me!! :D
                                Richard

                                1 Reply Last reply
                                0
                                • Z Offline
                                  Z Offline
                                  ZapB
                                  wrote on last edited by
                                  #16

                                  [quote author="ThaRez" date="1317039266"]The problem is there are several spin boxes and then I'd have to pass a pointer to all of them (?). By passing the main window, can't I then access them all?[/quote]

                                  Yes you can access them all this way. But the coupling (as I understand it) is between an item and a specific spinbox. So you should better pass through the appropriate spinbox corresponding to each item when you create each item. Or use the other approach and have the mainwindow make the connections as needed.

                                  Anyway, glad you got something working.

                                  Nokia Certified Qt Specialist
                                  Interested in hearing about Qt related work

                                  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