Results 1 to 19 of 19

Thread: Signals Slots and Class Pointers

  1. #1
    Join Date
    Jun 2011
    Posts
    203
    Thanks
    7
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Signals Slots and Class Pointers

    Hi guys, this is more of a class pointer and C++ but anyway. I created a window with a widget in Qt and also added a horizontal slider widget to the main window as well. My widget is an OpenGL widget and I want to be able to control an object in the OpenGL window using the slider. I went into the default constructor of the window and added the connect code:

    Qt Code:
    1. connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), *GLWidget, SLOT(setAngle int angle))
    To copy to clipboard, switch view to plain text mode 

    However I'm not really familiar with class pointers in projects with multiple files (very confused as to which files are accessed first, which second when the main window pops up and calls subsequent stuff). My understanding is that to use a class pointer, you need to first create the class pointer and assign a value to it just like any other pointer. However, in my case, I'm trying to send a value from my slider widget to an object which should already exist? Simply writing *GLWidget in the connect function doesn't seem to be able to have the program recognise the existence of my GLWidget - I don't get the auto pop up of the available slots for my GLWidget class i.e.

    Qt Code:
    1. SLOT(... nothing pops up)
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Signals Slots and Class Pointers

    You are correct, this is a C++ question.

    A class is a definition of a thing. An object is one, possibly among many, of those things. A pointer is the address of an object not a class: i.e. "class pointer" makes no sense. The QObject::connect() call requires pointers to sender and receiver objects. You are responsible for creating the object and providing the pointer to it. You can create objects as local variables (on the stack) or on in allocated memory (on the heap):
    Qt Code:
    1. class Foo {
    2. public:
    3. ...
    4. int value;
    5. void doStuff() { }
    6. ...
    7. };
    8.  
    9. void somefunc(const Foo &f) {...}
    10. void otherfunc(Foo *f) {...}
    11.  
    12. Foo foo; // an object of class Foo on the stack
    13. Foo *bar; // a pointer to an object of class Foo. The object dos not exist yet.
    14. bar = new Foo; // now it does
    15. Foo *baz = &foo; // a pointer to an object of class Foo, pointing at the same object as foo.
    16.  
    17. // Using the Foo objects
    18. foo.doStuff();
    19. bar->doStuff();
    20.  
    21. somefunc(*bar); // Supply the object pointed to by bar
    22. otherfunc(bar); // Supply the pointer to an object
    23. otherfunc(&foo); // Supply the pointer to the object foo
    24.  
    25. delete bar; // free the allocated memory
    To copy to clipboard, switch view to plain text mode 

    Objects are created in the order your code creates them, and the do what your code commands of them. Its irrelevant what file contains which class definition: classes don't do anything until you create an object or objects based on them.

    In your code ui->horizontalSlider is a pointer to an object of the QSlider class. How have you created your GLWidget object, or is GLWidget the name of the class?

  3. #3
    Join Date
    Jun 2011
    Posts
    203
    Thanks
    7
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Signals Slots and Class Pointers

    Quote Originally Posted by ChrisW67 View Post
    You are correct, this is a C++ question.

    Objects are created in the order your code creates them, and the do what your code commands of them. Its irrelevant what file contains which class definition: classes don't do anything until you create an object or objects based on them.

    In your code ui->horizontalSlider is a pointer to an object of the QSlider class. How have you created your GLWidget object, or is GLWidget the name of the class?
    Yep I understand. The bit I don't get is that when I look under main.cpp, I can clearly see my main window object being created and called 'w'. After that, I don't see where my GLWidget gets created other than seeing the .ccp code and .h head files for it and know that it works when I run the application after compilation... so it's getting called somewhere, but no idea where... hence the confusion as to what get's called in what order.

    Quote Originally Posted by ChrisW67 View Post
    How have you created your GLWidget object, or is GLWidget the name of the class?
    It's the class itself.

  4. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Signals Slots and Class Pointers

    Quote Originally Posted by Atomic_Sheep
    It's the class itself.
    That won't work.

    If you have put a widget of class GLWidget into a Designer UI (using the promotion feature) then the code generated from the .ui file (e.g. ui_mainwindow.h) is creating an object of that class during the setupUi() call you see in widget class constructors. A pointer to such an object will be accessible through the ui pointer just like the slider. I suggest you open the ui_mainwindow.h file and read it to get a better understanding.

    If you are not using Designer then I'll quote myself:
    Quote Originally Posted by Me
    You are responsible for creating the object and providing the pointer to it. You can create objects as local variables (on the stack) or on in allocated memory (on the heap):

  5. #5
    Join Date
    Jun 2011
    Posts
    203
    Thanks
    7
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Signals Slots and Class Pointers

    Quote Originally Posted by ChrisW67 View Post
    That won't work.
    A pointer to such an object will be accessible through the ui pointer just like the slider.
    Of course! Thanks, pretty sure I'll be able to get it to work now...

  6. #6
    Join Date
    Jun 2011
    Posts
    203
    Thanks
    7
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Signals Slots and Class Pointers

    Nope, looks I'm too stupid to figure this one out, after spending a few hours on this, I still can't get it to work.

    I've got the two classes (mainwindow and glwidget)... in the mainwindow class constructor I've connected:

    Qt Code:
    1. connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), ui->widget, SLOT(...);
    To copy to clipboard, switch view to plain text mode 

    However as the ... indicates... no slots from my glwidget class pop up.

    The glwidget and mainwindow are two seperate classes with their own .h and .cpp files and I've definitely added the includes but still no luck.

    I added a label to my ui and connected that to the horizontalslider and the label shows the values no problems and also pops up with "setNum(int)" when I'm typing up the connect command...

    Qt Code:
    1. connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), ui->label, SLOT(setNum(int)));
    To copy to clipboard, switch view to plain text mode 

    I've also written the code for my slot in my glwidget.cpp file:

    Qt Code:
    1. void GLWidget::SetValue(int Value)
    2. {
    3. if (Value != m_Value)
    4. {
    5. m_Value = Value;
    6. }
    7. }
    To copy to clipboard, switch view to plain text mode 

    But still no luck.
    Last edited by Atomic_Sheep; 18th July 2012 at 11:36.

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Signals Slots and Class Pointers

    The fact that Creator does not recognize your slot, doesn't mean you can't use it. Just type in the slot signature manually. And make sure you really declared the function to be a slot.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  8. #8
    Join Date
    Jun 2011
    Posts
    203
    Thanks
    7
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Signals Slots and Class Pointers

    I was wondering whether this might be the case so I tried what you suggested but the implementation of my receiving objects slot doesn't appear to be registering because my opengl's object rotation doesn't appear to be happening. I put a messagebox inside my slot implementation and it doesn't pop up as I move the slider about... the value in the label changes though.

  9. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Signals Slots and Class Pointers

    We'd have to see your actual code as currently with those little pieces you posted it is hard to tell anything. In general you need your method to be declared as a slot and you need to be passing a pointer to an instance of that class to the connect() statement to be able to connect to the slot.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  10. #10
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Signals Slots and Class Pointers

    Also look at the debug output of your program for warnings of the type:
    Qt Code:
    1. QObject::connect: No such slot GLWidget::SetValue(int)
    To copy to clipboard, switch view to plain text mode 
    indicating that the SetValue() function is not declared as a slot. The glwidget.h file should look like:
    Qt Code:
    1. ...
    2. class GLWidget: public ...
    3. {
    4. Q_OBJECT
    5. public:
    6. GLWidget(...);
    7. ...
    8. public slots: // <<<< this
    9. void SetValue(int value);
    10. ...
    11. };
    12. ...
    To copy to clipboard, switch view to plain text mode 
    and be included in the PRO file HEADERS variable.
    "We can't solve problems by using the same kind of thinking we used when we created them." -- Einstein
    If you are posting code then please use [code] [/code] tags around it - makes addressing the problem easier.

  11. #11
    Join Date
    Jun 2011
    Posts
    203
    Thanks
    7
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Signals Slots and Class Pointers

    Looks like HEADERS in pro are fine.

    As for the code...

    mainwindow.h

    Qt Code:
    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3.  
    4. #include <QMainWindow>
    5. #include "glwidget.h"
    6.  
    7. namespace Ui {
    8. class MainWindow;
    9. }
    10.  
    11. class MainWindow : public QMainWindow
    12. {
    13. Q_OBJECT
    14.  
    15. public:
    16. explicit MainWindow(QWidget *parent = 0);
    17. ~MainWindow();
    18.  
    19. int m_Angle;
    20. void AngleUpdate(int m_Angle);
    21. private:
    22. Ui::MainWindow *ui;
    23. };
    24.  
    25. #endif // MAINWINDOW_H
    To copy to clipboard, switch view to plain text mode 

    glwidget.h

    Qt Code:
    1. #ifndef GLWIDGET_H
    2. #define GLWIDGET_H
    3.  
    4. #include <QtOpenGL/QGLWidget>
    5. #include <cmath>
    6. #include "mainwindow.h"
    7. #include <QMessageBox>
    8.  
    9. class GLWidget : public QGLWidget
    10. {
    11. Q_OBJECT
    12. public:
    13. explicit GLWidget(QWidget *parent = 0);
    14.  
    15. int m_Angle;
    16.  
    17.  
    18. void initializeGL();
    19. void paintGL();
    20. void resizeGL(int w, int h);
    21.  
    22. public slots:
    23. void SetAngle(int Angle);
    24.  
    25. };
    26.  
    27. #endif // GLWIDGET_H
    To copy to clipboard, switch view to plain text mode 

    mainwindow.cpp

    Qt Code:
    1. #include "mainwindow.h"
    2. #include "ui_mainwindow.h"
    3.  
    4. MainWindow::MainWindow(QWidget *parent) :
    5. QMainWindow(parent),
    6. ui(new Ui::MainWindow)
    7. {
    8. ui->setupUi(this);
    9. connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), ui->Widget, SLOT(SetAngle(int Angle))); //Widget is just the standard widget which I've promoted to GLWidget in form editor
    10. connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), ui->label, SLOT(setNum(int)));
    11. }
    12.  
    13. MainWindow::~MainWindow()
    14. {
    15. delete ui;
    16. }
    To copy to clipboard, switch view to plain text mode 

    glwidget.cpp

    Qt Code:
    1. #include "glwidget.h"
    2.  
    3. GLWidget::GLWidget(QWidget *parent) :
    4. QGLWidget(parent)
    5. {
    6.  
    7. }
    8.  
    9. void GLWidget::SetAngle(int Angle)
    10. {
    11. if (Angle != m_Angle)
    12. {
    13. m_Angle = Angle;
    14. QMessageBox::information(0, "inside slot", "inside slot");
    15. }
    16. }
    To copy to clipboard, switch view to plain text mode 

    P.S. There might be one or two mistakes here or there e.g. m_Angle used instead of Angle or something like that... I'm 99% sure I don't have that mistake in my actual program.
    Last edited by Atomic_Sheep; 19th July 2012 at 06:32.

  12. #12
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Signals Slots and Class Pointers

    In the last few posts the slot has been referred to as SetNum(), SetValue(), and now SetAngle(). I asked you to check for run time error messages like:
    Qt Code:
    1. QObject::connect: No such slot GLWidget::SetAngle(int Angle)
    To copy to clipboard, switch view to plain text mode 
    Line 9 of mainwindow.cpp is probably generating one because the slot signature is incorrect. You do not include the argument names in the signal or slot signatures.

  13. #13
    Join Date
    Jun 2011
    Posts
    203
    Thanks
    7
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Signals Slots and Class Pointers

    Forgot to say that yes I did check for those errors, I didn't see any, but I just realised that run-time errors are under "Application Output" and yes it's spitting out the "no such slot" error. i.e. :

    Object::connect: No such slot GLWidget::SetAngle(int Angle) in ...\MainWindow.cpp:9
    Object::connect: (sender name: 'horizontalSlider')
    Object::connect: (receiver name: 'Widget')

    ...exited with code 0

    I used different names for my slots previously because I was simply typing the code up as I was writing up the message. In the latest iteration it was copy paste with some minor editing, but the latest code that I provided should have all the naming issues sorted out.

  14. #14
    Join Date
    Jun 2011
    Posts
    203
    Thanks
    7
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Signals Slots and Class Pointers

    Still unable to get my signals and slots to work .

    my .cpp files are :main.cpp, button.cpp, mainWindow.cpp and mainWindowWidget.cpp.

    mainWindowWidget.cpp has the following signal:

    Qt Code:
    1. void mainWindowWidget::mousePressEvent(QMouseEvent *event)
    2. {
    3. if(event->button() == Qt::LeftButton) //left mouse button - need to check this.
    4. {
    5. cMousePositionAtClick = event->pos();
    6. emit MouseClickLocation(cMousePositionAtClick);
    7. //QMessageBox::information(this, "Mouse Click Detected", "Mouse Click Detected");
    8. }
    9. }
    To copy to clipboard, switch view to plain text mode 

    I have a slot in my button.h and its implementation.

    here's the code in main.cpp:

    Qt Code:
    1. mainWindow w;
    2. Button button1(0,0,50,50);
    3. connect(w, SIGNAL(MouseClickLocation(QPoint)), button1, SLOT(LocationGrabber(QPoint)));
    4. w.show();
    To copy to clipboard, switch view to plain text mode 

    However when I compile it I get the following errors:

    main.cpp:11: error: cannot convert 'mainWindow' to 'SOCKET' for argument '1' to 'int connect(SOCKET, const sockaddr*, int)'
    Last edited by Atomic_Sheep; 3rd September 2012 at 05:40.

  15. #15
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Signals Slots and Class Pointers

    Two basic C++, not Qt, problems:

    The error message tells you that the compiler has found only function 'int connect(SOCKET, const sockaddr*, int)' when trying to compile line 11 (I assume line 3 of your posted snippet). The arguments you have given cannot be coerced into the arguments required by that function so it fails. You want QObject::connect() and you cannot access that as an unqualified name outside of the implementation of a QObject sub-class. Use the static QObject::connect() function.

    QObject::connect() requires a pointer to an object, i.e. &w and &button1, not the actual objects as you are current trying to do.

  16. #16
    Join Date
    Jun 2011
    Posts
    203
    Thanks
    7
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Signals Slots and Class Pointers

    Deleted... figured it out.
    Last edited by Atomic_Sheep; 4th September 2012 at 07:29.

  17. #17
    Join Date
    Jun 2011
    Posts
    203
    Thanks
    7
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Signals Slots and Class Pointers

    Thanks Chris for helping out with the previous problem.

    Another question. In the Qt example with the spinning boxes:

    Qt Code:
    1. Window::Window()
    2. {
    3. QGridLayout *mainLayout = new QGridLayout;
    4.  
    5. for (int i = 0; i < NumRows; ++i) {
    6. for (int j = 0; j < NumColumns; ++j) {
    7. QColor clearColor;
    8. clearColor.setHsv(((i * NumColumns) + j) * 255
    9. / (NumRows * NumColumns - 1),
    10. 255, 63);
    11.  
    12. glWidgets[i][j] = new GLWidget(0, 0);
    13. glWidgets[i][j]->setClearColor(clearColor);
    14. glWidgets[i][j]->rotateBy(+42 * 16, +42 * 16, -21 * 16);
    15. mainLayout->addWidget(glWidgets[i][j], i, j);
    16.  
    17. connect(glWidgets[i][j], SIGNAL(clicked()),
    18. this, SLOT(setCurrentGlWidget()));
    19. }
    20. }
    To copy to clipboard, switch view to plain text mode 

    The code creates glWidget objects for each of the cubes to spin. I just have:

    Qt Code:
    1. #include "mainwindow.h"
    2. #include "ui_mainwindow.h"
    3.  
    4. mainwindow::mainwindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::Jetstream41)
    5. {
    6. ui->setupUi(this);
    7. }
    8.  
    9. mainwindow::~mainwindow()
    10. {
    11. delete ui;
    12. }
    To copy to clipboard, switch view to plain text mode 

    and a .cpp file for mainwindowGLWidget.

    I'm trying to connect a signal from another class to a slot of my mainwindowGLWidget class, however I don't know the name of the object of my mainwindowGLWidget class. How do I find this out?

    My limited understanding is that when the compiler runs, ?moc? generates the ui.h file in the -build-desktop folder? But does this somehow solve my problem?

    I know it says this in relation to my glwidget...

    widget = new MyOpenGLWidget(centralWidget);

  18. #18
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Signals Slots and Class Pointers

    uic generates the ui_stuff.h file from your stuff.ui file.

    The name of the variable holding a pointer to your custom widget is set by you in Designer and carried over into generated UI code. In Designer:
    untitled.jpg
    and in the generated code is the class that the ui pointer points to an instance of:
    Qt Code:
    1. #include <QtGui/QButtonGroup>
    2. #include <QtGui/QFrame>
    3. #include <QtGui/QHBoxLayout>
    4. #include <QtGui/QHeaderView>
    5. #include <QtGui/QWidget>
    6.  
    7. QT_BEGIN_NAMESPACE
    8.  
    9. class Ui_Form
    10. {
    11. public:
    12. QHBoxLayout *horizontalLayout;
    13. QFrame *myCustomFrame; // <<<<< here
    14.  
    15. void setupUi(QWidget *Form)
    16. {
    17. ...
    18. // <<<< and here
    19. myCustomFrame = new QFrame(Form);
    20. myCustomFrame->setObjectName(QString::fromUtf8("myCustomFrame"));
    21. myCustomFrame->setFrameShape(QFrame::Box);
    22. ...
    23. } // setupUi
    24. ...
    25. };
    26. ...
    27. #endif // UI_UNTITLED_H
    To copy to clipboard, switch view to plain text mode 
    so in your code you can access it through the ui pointer thus:
    Qt Code:
    1. ui->myCustomFrame;
    To copy to clipboard, switch view to plain text mode 

  19. #19
    Join Date
    Jun 2011
    Posts
    203
    Thanks
    7
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Signals Slots and Class Pointers

    Thanks Chris... had to reread this whole thread a few times to pick out to what information I applied the principle of 'selective hearing'. Finally got everything to work as desired! Now comes the fun task of fixing the next problem caused by the solving of the old prob . Thanks again.

Similar Threads

  1. Custom QTreeWidgetItem class and signals&slots issue
    By devla in forum Qt Programming
    Replies: 3
    Last Post: 7th July 2012, 00:15
  2. Replies: 3
    Last Post: 6th April 2012, 16:44
  3. Replies: 8
    Last Post: 15th July 2010, 21:42
  4. Access a class without using Signals/Slots
    By impeteperry in forum Qt Programming
    Replies: 5
    Last Post: 10th January 2010, 11:14
  5. pointers behaviour in qt and specially signals/slot mechanism
    By salmanmanekia in forum Qt Programming
    Replies: 5
    Last Post: 17th August 2008, 19:34

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.