[Solved] Signal & Slot to QGraphicView items
-
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.
-
Also, you could just inherit your QGV items from [[doc:QGraphicsObject]] to enable signal/slot functionality.
-
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 -
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.
-
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?
-
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.
-
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() << 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 -
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.
-
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?
-
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 -
[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.