Results 1 to 11 of 11

Thread: Signals and Slots across different classes (Qt5 Version)

  1. #1
    Join Date
    Sep 2014
    Posts
    11
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Signals and Slots across different classes (Qt5 Version)

    Currently in a situation where I want to have two classes, one a layout class controlling all the GUI items that are being displayed. Then a second class that contains implementation methods, what I would like to specifically do is press a button that would add 10 to a count number, then use this count number to update a progress bar (just a basic example so i get my head round it).

    So currently looking at implementing this I decided to use Qt5 version of signals and slots, below is my current attempt which seems not to be firing off the slot even though i'm not receiving a compiler or runtime error. If anyone has an idea how I should be implementing this that would be great, or a good link to a decent example would be great.

    counter.h
    Qt Code:
    1. #ifndef COUNTER_H
    2. #define COUNTER_H
    3.  
    4. #include <QObject>
    5.  
    6. class counter : public QObject
    7. {
    8. Q_OBJECT
    9. public:
    10. explicit counter(QObject *parent = 0);
    11.  
    12.  
    13. signals:
    14.  
    15. public slots:
    16. int count();
    17.  
    18. private:
    19. static int number;
    20.  
    21. };
    22.  
    23. #endif // COUNTER_H
    To copy to clipboard, switch view to plain text mode 

    counter.cpp
    Qt Code:
    1. #include "counter.h"
    2. #include "mainwindow.h"
    3.  
    4. int counter::number;
    5.  
    6. counter::counter(QObject *parent) :
    7. QObject(parent)
    8. {
    9. number = 10;
    10. }
    11.  
    12. int counter::count()
    13. {
    14.  
    15. number += 10;
    16. //emit countworked;
    17. qDebug() << number;
    18. return number;
    19. }
    To copy to clipboard, switch view to plain text mode 

    mainwindow.h
    Qt Code:
    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3.  
    4. #include <QMainWindow>
    5. #include <QPushButton>
    6. #include <QWidget>
    7. #include <QApplication>
    8. #include <QPushButton>
    9. #include <QVBoxLayout>
    10. #include <QLabel>
    11. #include <QState>
    12. #include <QStateMachine>
    13. #include <QDebug>
    14.  
    15. namespace Ui {
    16. class MainWindow;
    17. }
    18.  
    19. class MainWindow : public QMainWindow
    20. {
    21. Q_OBJECT
    22.  
    23. public:
    24. explicit MainWindow(QWidget *parent = 0);
    25. ~MainWindow();
    26.  
    27. private:
    28. Ui::MainWindow *ui;
    29. };
    30.  
    31. #endif // MAINWINDOW_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. #include "counter.h"
    4. #include <QDebug>
    5. #include <iostream>
    6. #include <string>
    7. #include <sstream>
    8.  
    9.  
    10. MainWindow::MainWindow(QWidget *parent) :
    11. QMainWindow(parent),
    12. ui(new Ui::MainWindow)
    13. {
    14. ui->setupUi(this);
    15. counter counting;
    16. this->setWindowTitle(QApplication::translate("toplevel", "CCTV"));
    17. //int (counter::*intfunction)();
    18. //int count(10);
    19. //intfunction = &counter::count;
    20. connect(ui->pushButton_2,&QPushButton::clicked,&counting,&counter::count);
    21. //connect(countworked,countworkedvaluechanged(),ui->progressBar,&QProgressBar::valueChanged)
    22. // int *valuechanged = *intfunction;
    23. ui->progressBar->setValue(50);
    24. }
    25.  
    26. MainWindow::~MainWindow()
    27. {
    28. delete ui;
    29. }
    To copy to clipboard, switch view to plain text mode 

    main.cpp
    Qt Code:
    1. #include "mainwindow.h"
    2. #include <QApplication>
    3.  
    4. int main(int argc, char *argv[])
    5. {
    6. QApplication a(argc, argv);
    7. MainWindow w;
    8. w.show();
    9.  
    10. return a.exec();
    11. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Signals and Slots across different classes (Qt5 Version)

    Your object "counting" goes out of scope at then end of the MainWindow constructor.

    Cheers.
    _

  3. #3
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Signals and Slots across different classes (Qt5 Version)

    Not only that, but slots and signals can't return values (i.e. they are declared as void someFunc()). If you need something passed or returned through a signal / slot mechanism, pass an argument:

    Qt Code:
    1. // counter.h
    2.  
    3. signals:
    4. void countIncremented( int newCount );
    5.  
    6. public slots:
    7. void count();
    8.  
    9. // counter.cpp
    10.  
    11. void counter::count()
    12. {
    13. number += 10;
    14. emit countIncremented( number );
    15. qDebug() << number;
    16. }
    17.  
    18. // MainWindow.cpp
    19.  
    20. // In the constructor:
    21. counter * counting = new counter( this );
    22. connect(ui->pushButton_2,&QPushButton::clicked, counting, &counter::count );
    23. connect( counting, &counter::countIncremented(), ui->progressBar, &QProgressBar::setValue() );
    To copy to clipboard, switch view to plain text mode 

    The other problem is that by declaring counter::number as static, all instances of the counter object will be using the same value. So if you have two push buttons, even if they are connected to different instances of the counter object they will be incrementing the same value. If the value is initialized to zero, on the first click it becomes 10, the second click 20, and so on, regardless of which button gets clicked.

    And further, if different instances of push buttons are connected to different instances of counters, and the counters are connected to different instances of progress bars, then the progress bars will be out of sync with the counter value because they are not connected to the same counter instance.

    Button1 -> counter 1 -> progress bar 1
    Button2 -> counter 2 -> progress bar 2


    1. Start: Number = 0, progress bar values = 0
    2. Click button 1
    3. Counter 1 increments; number = 10
    4. Progress bar 1 increments; value = 10
    5. Progress bar 2 doesn't increment; value = 0
    6. Click button 2
    7. Counter 2 increments; number = 20
    8. Progress bar 2 increments; value = 20
    9. Progress bar 1 doesn't increment; value = 10


    Is that what you intend to happen? If not, don't make "number" a static member of counter.

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Signals and Slots across different classes (Qt5 Version)

    Quote Originally Posted by d_stranz View Post
    Not only that, but slots and signals can't return values (i.e. they are declared as void someFunc()).
    Well, a slot an return a value because it is also a normal C++ method.
    But the return value is only accessible when called as such, not when called through signal/slots.

    Cheers,
    _

  5. The following user says thank you to anda_skoa for this useful post:

    d_stranz (14th September 2014)

  6. #5
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Signals and Slots across different classes (Qt5 Version)

    Well, a slot an return a value because it is also a normal C++ method.
    But the return value is only accessible when called as such, not when called through signal/slots.
    Yes, quite true, but I was thinking only in the signals/slots context. Most times, my normal thinking is, why bother to make something having a return value into a signal or slot when you can't use the value in a connection? In some sense, the return value is like a side effect, which I try to avoid in my code.

  7. #6
    Join Date
    Sep 2014
    Posts
    11
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Signals and Slots across different classes (Qt5 Version)

    Thanks for replying guys, d_stranz just trying out your code but a little stuck as it's complaining about not being supplied arguements to countincremented.

    Yes this is what I wanted to do this is just for testing the new method of signal and slots so that I understand it correctly.

    currently getting failure due to no matching function call, (incorrect amount of arguments supplied). As I supposed to give count_incremented a parameter in the connect or am I doing something else wrong (should I be using a lamda function or ?). Also "&QProgressBar::setValue() is also failing with the same thing (no matching function for call, too many arguements)

    Code listed below

    Counter.h
    Qt Code:
    1. #ifndef COUNTER_H
    2. #define COUNTER_H
    3.  
    4. #include <QObject>
    5.  
    6. class counter : public QObject
    7. {
    8. Q_OBJECT
    9. public:
    10. explicit counter(QObject *parent = 0);
    11.  
    12. signals:
    13. void Increment_Count(int newcount);
    14.  
    15. public slots:
    16. void count();
    17.  
    18.  
    19. private:
    20. static int number;
    21.  
    22. };
    23.  
    24. #endif // COUNTER_H
    To copy to clipboard, switch view to plain text mode 

    Counter.cpp
    Qt Code:
    1. #include "counter.h"
    2. #include "mainwindow.h"
    3.  
    4. int counter::number;
    5.  
    6. counter::counter(QObject *parent) :
    7. QObject(parent)
    8. {
    9. number = 10;
    10. }
    11.  
    12. void counter::count()
    13. {
    14.  
    15. number += 10;
    16. emit Increment_Count(number);
    17. qDebug() << number;
    18. // return number;
    19. }
    To copy to clipboard, switch view to plain text mode 

    mainwindow.cpp
    Qt Code:
    1. #include "mainwindow.h"
    2. #include "ui_mainwindow.h"
    3. #include "counter.h"
    4. #include <QDebug>
    5. #include <iostream>
    6. #include <string>
    7. #include <sstream>
    8.  
    9.  
    10. MainWindow::MainWindow(QWidget *parent) :
    11. QMainWindow(parent),
    12. ui(new Ui::MainWindow)
    13. {
    14. ui->setupUi(this);
    15. counter * counting = new counter(this);
    16. this->setWindowTitle(QApplication::translate("toplevel", "CCTV"));
    17.  
    18. connect(ui->pushButton_2,&QPushButton::clicked,counting,&counter::count);
    19. connect(counting, &counter::Increment_Count(10), ui->progressBar, &QProgressBar::setValue());
    20. //connect(counting, counting->Increment_Count(), ui->progressBar, &QProgressBar::setValue());
    21. }
    22.  
    23. MainWindow::~MainWindow()
    24. {
    25. delete ui;
    26. }
    To copy to clipboard, switch view to plain text mode 

    Thanks for the help so far so where am I going wrong?Just want to be able to use a signal and slot to change the progressbar via a count variable (should I be using a different method like a signal mapper ?). As I said just want two buttons to control a single instance of count, would like to be able to adjust the number for both which would be nice, but not required as this is just an example so it makes it easier for me to learn. Thanks for your help so far.
    Last edited by Ion; 16th September 2014 at 10:24.

  8. #7
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Signals and Slots across different classes (Qt5 Version)

    You have a parentheses in your signal parameter of the connect call, it should only be the name of the class + name of the signal.
    See the connect of the pusbutton.

    Cheers,
    _

  9. #8
    Join Date
    Sep 2014
    Posts
    11
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Signals and Slots across different classes (Qt5 Version)

    Ah thanks didn't see that. Ok implemented that however the same error is also occurring for Setvalue.

    C:\mainwindow.cpp:19: error: no matching function for call to 'QProgressBar::setValue()'
    connect(counting, &counter::Increment_Count, ui->progressBar, &QProgressBar::setValue());
    ^
    so how am I supposed to correct QProgressbar so that it now works (in the Qt5 version of setting it)?

  10. #9
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Signals and Slots across different classes (Qt5 Version)

    Quote Originally Posted by Ion View Post
    Ah thanks didn't see that. Ok implemented that however the same error is also occurring for Setvalue.
    Same mistake again. Parentheses.

    Cheers,
    _

  11. #10
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Signals and Slots across different classes (Qt5 Version)

    Same mistake again. Parentheses.
    Yes, sorry. I haven't switched over to the Qt 5 style of connect(), so I goofed on the syntax. Should have been obvious C++ that the expression for the address of a member function doesn't contain parentheses.

    connect(counting, &counter::Increment_Count(10), ui->progressBar, &QProgressBar::setValue());
    In any case, even if you used the old SIGNAL() and SLOT() syntax for the connect() statement, you can't pass in a value as you apparently are trying to do here. The macros are simply the signature of the method with only the parameter types, no variable names or values. The return value is assumed to be void and is ignored anyway. So the equivalent SIGNAL / SLOT version of your connect() should be:

    Qt Code:
    1. connect(counting, SIGNAL( Increment_Count(int) ), ui->progressBar,SLOT( setValue(int) ));
    To copy to clipboard, switch view to plain text mode 

  12. #11
    Join Date
    Sep 2014
    Posts
    11
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Signals and Slots across different classes (Qt5 Version)

    Ok brill thanks guys, yea I am very new to signal and slots so this was a bit of a crash course for me, so didn't want to bother learning the old method. Thanks guys

Similar Threads

  1. Replies: 2
    Last Post: 18th April 2013, 12:15
  2. Replies: 2
    Last Post: 29th June 2012, 09:32
  3. Accessing slots of other classes
    By papillon in forum Qt Programming
    Replies: 1
    Last Post: 14th January 2011, 06:24
  4. Signals/slots between classes
    By been_1990 in forum Qt Programming
    Replies: 19
    Last Post: 27th November 2009, 13:04
  5. Signals and Slots between 2 classes
    By probine in forum Qt Programming
    Replies: 1
    Last Post: 31st March 2006, 00: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.