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. Basic Signals and Slots - don't know where to go.

Basic Signals and Slots - don't know where to go.

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 2 Posters 366 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.
  • U Offline
    U Offline
    Uberlinc
    wrote on last edited by
    #1

    HI,

    So, basic Signals and Slots here.
    I just can't work out where to place the code in order to have it executed.

    Short of it is:
    I have a MainWindow.
    When you click on "Set Date" it opens a Qt Designer Form Class that contains a Calendar Widget.
    If you hit "Okay" it executes an accept();
    If you hit "Cancel" it executes close();

    I have found how to get these 3 values (day, month, year) back to the MainWindow.
    I want these three values to then trigger a signal which is picked up by a slot to populate a few form fields on MainWindow, but then also be sent off other places.
    If no date is selected, then a default date is set for those values in MainWindow instead.

    Just can't quite get my head around it.

    Code below:

    mainwindow.cpp:

    #include "mainwindow.h"
    #include "./ui_mainwindow.h"
    #include "littledate.h"
    #include <QString>
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::populateStuff(int thisDay, int thisMonth, int thisYear)
    {
    
        // Need thisDay, thisMonth and thisYear to receive values from a signal/slot
        // If none are received, need the following defaults:
        //int thisDay = 1;
        //int thisMonth = 5;
        //int thisYear = 2021;
    
        ui->Day->setText(QString::number(thisDay));
        ui->Month->setText(QString::number(thisMonth));
        ui->Year->setText(QString::number(thisYear));
    
        // Do some other stuff with values stored in thisDay, thisMonth, thisYear
    
    }
    
    void MainWindow::on_quitButton_clicked()
    {
        close();
    }
    
    void MainWindow::on_pushButton_clicked()
    {
        int day, month, year;
    
        littleDate dateSel;
        dateSel.setModal(true);
        if (dateSel.exec() == QDialog::Accepted)
        {
           day = dateSel.getDay();
           month = dateSel.getMonth();
           year = dateSel.getYear();
        }
    
        // Need day, month, year to trigger a signal/slot that
        // sends values to populatestuff()
    
    
    
    }
    
    

    littledate.cpp:

    #include "littledate.h"
    #include "ui_littledate.h"
    
    littleDate::littleDate(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::littleDate)
    {
        ui->setupUi(this);
    }
    
    littleDate::~littleDate()
    {
        delete ui;
    }
    
    void littleDate::setDay(int thisDay)
    {
        day = thisDay;
    }
    
    void littleDate::setMonth(int thisMonth)
    {
        month = thisMonth;
    }
    
    void littleDate::setYear(int thisYear)
    {
        year = thisYear;
    }
    
    int littleDate::getDay() const
    {
        return day;
    }
    
    int littleDate::getMonth() const
    {
        return month;
    }
    
    int littleDate::getYear() const
    {
        return year;
    }
    
    void littleDate::on_cancelButton_clicked()
    {
        close();
    }
    
    void littleDate::on_okButton_clicked()
    {
        QDate date = ui->calendarWidget->selectedDate();
        setDay(date.day());
        setMonth(date.month());
        setYear(date.year());
        accept();
    
    }
    
    

    Any ideas?

    Many thanks.

    JonBJ 1 Reply Last reply
    0
    • U Uberlinc

      HI,

      So, basic Signals and Slots here.
      I just can't work out where to place the code in order to have it executed.

      Short of it is:
      I have a MainWindow.
      When you click on "Set Date" it opens a Qt Designer Form Class that contains a Calendar Widget.
      If you hit "Okay" it executes an accept();
      If you hit "Cancel" it executes close();

      I have found how to get these 3 values (day, month, year) back to the MainWindow.
      I want these three values to then trigger a signal which is picked up by a slot to populate a few form fields on MainWindow, but then also be sent off other places.
      If no date is selected, then a default date is set for those values in MainWindow instead.

      Just can't quite get my head around it.

      Code below:

      mainwindow.cpp:

      #include "mainwindow.h"
      #include "./ui_mainwindow.h"
      #include "littledate.h"
      #include <QString>
      
      MainWindow::MainWindow(QWidget *parent)
          : QMainWindow(parent)
          , ui(new Ui::MainWindow)
      {
          ui->setupUi(this);
      }
      
      MainWindow::~MainWindow()
      {
          delete ui;
      }
      
      void MainWindow::populateStuff(int thisDay, int thisMonth, int thisYear)
      {
      
          // Need thisDay, thisMonth and thisYear to receive values from a signal/slot
          // If none are received, need the following defaults:
          //int thisDay = 1;
          //int thisMonth = 5;
          //int thisYear = 2021;
      
          ui->Day->setText(QString::number(thisDay));
          ui->Month->setText(QString::number(thisMonth));
          ui->Year->setText(QString::number(thisYear));
      
          // Do some other stuff with values stored in thisDay, thisMonth, thisYear
      
      }
      
      void MainWindow::on_quitButton_clicked()
      {
          close();
      }
      
      void MainWindow::on_pushButton_clicked()
      {
          int day, month, year;
      
          littleDate dateSel;
          dateSel.setModal(true);
          if (dateSel.exec() == QDialog::Accepted)
          {
             day = dateSel.getDay();
             month = dateSel.getMonth();
             year = dateSel.getYear();
          }
      
          // Need day, month, year to trigger a signal/slot that
          // sends values to populatestuff()
      
      
      
      }
      
      

      littledate.cpp:

      #include "littledate.h"
      #include "ui_littledate.h"
      
      littleDate::littleDate(QWidget *parent) :
          QDialog(parent),
          ui(new Ui::littleDate)
      {
          ui->setupUi(this);
      }
      
      littleDate::~littleDate()
      {
          delete ui;
      }
      
      void littleDate::setDay(int thisDay)
      {
          day = thisDay;
      }
      
      void littleDate::setMonth(int thisMonth)
      {
          month = thisMonth;
      }
      
      void littleDate::setYear(int thisYear)
      {
          year = thisYear;
      }
      
      int littleDate::getDay() const
      {
          return day;
      }
      
      int littleDate::getMonth() const
      {
          return month;
      }
      
      int littleDate::getYear() const
      {
          return year;
      }
      
      void littleDate::on_cancelButton_clicked()
      {
          close();
      }
      
      void littleDate::on_okButton_clicked()
      {
          QDate date = ui->calendarWidget->selectedDate();
          setDay(date.day());
          setMonth(date.month());
          setYear(date.year());
          accept();
      
      }
      
      

      Any ideas?

      Many thanks.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @Uberlinc said in Basic Signals and Slots - don't know where to go.:

      // Need day, month, year to trigger a signal/slot that
      // sends values to populatestuff()
      

      No you don't need any such here --- simply call the MainWindow::populateStuff() method with the parameters from here directly:

      populateStuff(day, month, year);
      

      That's it! No need for signals/slots for this action.

      but then also be sent off other places.

      If you really need that for other purposes, and if for whatever reason it needs to be done by a signal rather than just having MainWindow call method(s) elsewhere, you will want to create your own signal for this. Which fortunatey is very easy:

      // in mainwindow.h, in the `MainWindow` class declaration
      signals:
          void dateChanged(int day, int month, int year);    // or maybe change to using a `QDate` type
      
      // in e.g. other modules' `.h` files
      public slots:
          void onDateChanged(int day, int month, int year);
      // and implementation of slot method in `.cpp` file as usual
      
      // in mainwindow.cpp, at suitable place(s) where you have created the other module(s)' instance
      connect(this, &MainWindow::dateChanged, otherObject, &OtherClass::onDateChanged);
      
      // in mainwindow.cpp, at suitable place(s) such as in `on_pushButton_clicked()`
      emit dateChanged(day, month, year);
      
      
      1 Reply Last reply
      2
      • U Offline
        U Offline
        Uberlinc
        wrote on last edited by
        #3

        That's a great help!
        Thank you!

        I wish to go ahead with the Signals & Slots part as I had intended this app to be an exercise to get my head around Signals and Slots. (As you can see, I'm still struggling a little bit.)

        I'll try to implement your changes and be back if I get stuck.

        Many thanks!

        1 Reply Last reply
        0
        • U Offline
          U Offline
          Uberlinc
          wrote on last edited by
          #4

          Okay, so I've played around with it but, much to my dismay, I'm just not getting it.
          I do apologise for asking you to hold my hand, but can someone show me exactly were on my code I need to stick the signals, slots, emitters and collectors?

          I know it's rude to dump a whole lot of code on someone, but this is the simplest example I can come up with.
          (I'm self-taught, part-time in between being a working Dad, so I'm struggling! I do apologise!)

          The aim is to have the date set as a default which can then be used to do other things, unless an event is driven by the change of date.

          Any help is greatly appreciated!

          littledate.h:

          #ifndef LITTLEDATE_H
          #define LITTLEDATE_H
          
          #include <QDialog>
          
          namespace Ui {
          class littleDate;
          }
          
          class littleDate : public QDialog
          {
              Q_OBJECT
          
          public:
              explicit littleDate(QWidget *parent = nullptr); // Constructor
              ~littleDate();                                  // Destructor
              void setDay(int);                               // Mutator function for day value
              void setMonth(int);                             // Mutator function for month value
              void setYear(int);                              // Mutator function for year value
              int getDay() const;                             // Accessor function for day value
              int getMonth() const;                           // Mutator function for month value
              int getYear() const;                            // Mutator function for year value
          
          public slots:
                void onDateChanged(int day, int month, int year);
          
          private slots:
              void on_cancelButton_clicked();
              void on_okButton_clicked();
          
          private:
              Ui::littleDate *ui;
              int day;
              int month;
              int year;
          };
          
          #endif // LITTLEDATE_H
          
          

          littledate.cpp:

          #include "littledate.h"
          #include "ui_littledate.h"
          
          littleDate::littleDate(QWidget *parent) :
              QDialog(parent),
              ui(new Ui::littleDate)
          {
              ui->setupUi(this);
          }
          
          littleDate::~littleDate()
          {
              delete ui;
          }
          
          void littleDate::setDay(int thisDay)
          {
              day = thisDay;
          }
          
          void littleDate::setMonth(int thisMonth)
          {
              month = thisMonth;
          }
          
          void littleDate::setYear(int thisYear)
          {
              year = thisYear;
          }
          
          int littleDate::getDay() const
          {
              return day;
          }
          
          int littleDate::getMonth() const
          {
              return month;
          }
          
          int littleDate::getYear() const
          {
              return year;
          }
          
          void littleDate::on_cancelButton_clicked()
          {
              close();
          }
          
          void littleDate::on_okButton_clicked()
          {
              QDate date = ui->calendarWidget->selectedDate();
              setDay(date.day());
              setMonth(date.month());
              setYear(date.year());
              accept();
          
          }
          

          mainwindow.h:

          #ifndef MAINWINDOW_H
          #define MAINWINDOW_H
          
          #include <QMainWindow>
          
          QT_BEGIN_NAMESPACE
          namespace Ui { class MainWindow; }
          QT_END_NAMESPACE
          
          class MainWindow : public QMainWindow
          {
              Q_OBJECT
          
          public:
              MainWindow(QWidget *parent = nullptr);
              ~MainWindow();
              void populateStuff();                           
          
          signals:
                void dateChanged(int day, int month, int year);               
          
          private slots:
              void on_quitButton_clicked();
              void on_pushButton_clicked();
          
          private:
              Ui::MainWindow *ui;
          };
          #endif // MAINWINDOW_H
          
          

          mainwindow.cpp:

          #include "mainwindow.h"
          #include "./ui_mainwindow.h"
          #include "littledate.h"
          #include <QString>
          
          MainWindow::MainWindow(QWidget *parent)
              : QMainWindow(parent)
              , ui(new Ui::MainWindow)
          {
              ui->setupUi(this);
          }
          
          MainWindow::~MainWindow()
          {
              delete ui;
          }
          
          void MainWindow::populateStuff()
          {
              // Set values for date.
              // Starts with defaults, unless an action is detected, and then uses that value instead
          
              int thisDay = 1;        // default day value if not changed by user
              int thisMonth = 5;      // default month value if not changed by user
              int thisYear = 2021;    // default year value if not changed by user
          
              // Somewhere in here, it looks to see if the date values have been changed by the user.
              
              ui->Day->setText(QString::number(thisDay));
              ui->Month->setText(QString::number(thisMonth));
              ui->Year->setText(QString::number(thisYear));
          
              // Do some other stuff with values stored in thisDay, thisMonth, thisYear 
              // i.e. passed off to another function.
          
          }
          
          void MainWindow::on_quitButton_clicked()
          {
              close();
          }
          
          void MainWindow::on_pushButton_clicked()
          {
              int day, month, year;
          
              littleDate dateSel;
              dateSel.setModal(true);
              connect(this, &MainWindow::dateChanged, dateSel, &littleDate::onDateChanged);
              if (dateSel.exec() == QDialog::Accepted)
              {
                 day = dateSel.getDay();
                 month = dateSel.getMonth();
                 year = dateSel.getYear();
              }
              emit dateChanged(day, month, year);
          
          }
          
          
          JonBJ 1 Reply Last reply
          0
          • U Uberlinc

            Okay, so I've played around with it but, much to my dismay, I'm just not getting it.
            I do apologise for asking you to hold my hand, but can someone show me exactly were on my code I need to stick the signals, slots, emitters and collectors?

            I know it's rude to dump a whole lot of code on someone, but this is the simplest example I can come up with.
            (I'm self-taught, part-time in between being a working Dad, so I'm struggling! I do apologise!)

            The aim is to have the date set as a default which can then be used to do other things, unless an event is driven by the change of date.

            Any help is greatly appreciated!

            littledate.h:

            #ifndef LITTLEDATE_H
            #define LITTLEDATE_H
            
            #include <QDialog>
            
            namespace Ui {
            class littleDate;
            }
            
            class littleDate : public QDialog
            {
                Q_OBJECT
            
            public:
                explicit littleDate(QWidget *parent = nullptr); // Constructor
                ~littleDate();                                  // Destructor
                void setDay(int);                               // Mutator function for day value
                void setMonth(int);                             // Mutator function for month value
                void setYear(int);                              // Mutator function for year value
                int getDay() const;                             // Accessor function for day value
                int getMonth() const;                           // Mutator function for month value
                int getYear() const;                            // Mutator function for year value
            
            public slots:
                  void onDateChanged(int day, int month, int year);
            
            private slots:
                void on_cancelButton_clicked();
                void on_okButton_clicked();
            
            private:
                Ui::littleDate *ui;
                int day;
                int month;
                int year;
            };
            
            #endif // LITTLEDATE_H
            
            

            littledate.cpp:

            #include "littledate.h"
            #include "ui_littledate.h"
            
            littleDate::littleDate(QWidget *parent) :
                QDialog(parent),
                ui(new Ui::littleDate)
            {
                ui->setupUi(this);
            }
            
            littleDate::~littleDate()
            {
                delete ui;
            }
            
            void littleDate::setDay(int thisDay)
            {
                day = thisDay;
            }
            
            void littleDate::setMonth(int thisMonth)
            {
                month = thisMonth;
            }
            
            void littleDate::setYear(int thisYear)
            {
                year = thisYear;
            }
            
            int littleDate::getDay() const
            {
                return day;
            }
            
            int littleDate::getMonth() const
            {
                return month;
            }
            
            int littleDate::getYear() const
            {
                return year;
            }
            
            void littleDate::on_cancelButton_clicked()
            {
                close();
            }
            
            void littleDate::on_okButton_clicked()
            {
                QDate date = ui->calendarWidget->selectedDate();
                setDay(date.day());
                setMonth(date.month());
                setYear(date.year());
                accept();
            
            }
            

            mainwindow.h:

            #ifndef MAINWINDOW_H
            #define MAINWINDOW_H
            
            #include <QMainWindow>
            
            QT_BEGIN_NAMESPACE
            namespace Ui { class MainWindow; }
            QT_END_NAMESPACE
            
            class MainWindow : public QMainWindow
            {
                Q_OBJECT
            
            public:
                MainWindow(QWidget *parent = nullptr);
                ~MainWindow();
                void populateStuff();                           
            
            signals:
                  void dateChanged(int day, int month, int year);               
            
            private slots:
                void on_quitButton_clicked();
                void on_pushButton_clicked();
            
            private:
                Ui::MainWindow *ui;
            };
            #endif // MAINWINDOW_H
            
            

            mainwindow.cpp:

            #include "mainwindow.h"
            #include "./ui_mainwindow.h"
            #include "littledate.h"
            #include <QString>
            
            MainWindow::MainWindow(QWidget *parent)
                : QMainWindow(parent)
                , ui(new Ui::MainWindow)
            {
                ui->setupUi(this);
            }
            
            MainWindow::~MainWindow()
            {
                delete ui;
            }
            
            void MainWindow::populateStuff()
            {
                // Set values for date.
                // Starts with defaults, unless an action is detected, and then uses that value instead
            
                int thisDay = 1;        // default day value if not changed by user
                int thisMonth = 5;      // default month value if not changed by user
                int thisYear = 2021;    // default year value if not changed by user
            
                // Somewhere in here, it looks to see if the date values have been changed by the user.
                
                ui->Day->setText(QString::number(thisDay));
                ui->Month->setText(QString::number(thisMonth));
                ui->Year->setText(QString::number(thisYear));
            
                // Do some other stuff with values stored in thisDay, thisMonth, thisYear 
                // i.e. passed off to another function.
            
            }
            
            void MainWindow::on_quitButton_clicked()
            {
                close();
            }
            
            void MainWindow::on_pushButton_clicked()
            {
                int day, month, year;
            
                littleDate dateSel;
                dateSel.setModal(true);
                connect(this, &MainWindow::dateChanged, dateSel, &littleDate::onDateChanged);
                if (dateSel.exec() == QDialog::Accepted)
                {
                   day = dateSel.getDay();
                   month = dateSel.getMonth();
                   year = dateSel.getYear();
                }
                emit dateChanged(day, month, year);
            
            }
            
            
            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #5

            @Uberlinc said in Basic Signals and Slots - don't know where to go.:

            connect(this, &MainWindow::dateChanged, dateSel, &littleDate::onDateChanged);

            This is wrong. Remove it and so far everything works, the main window gets the new date value from the dialog after the exec(), right?

            If all you want to do is then update some widgets on MainWindow you can do so directly from there without any signals/slots, immediately after the exec() returns.

            Only if as you said originally:

            but then also be sent off other places.

            do you need signals/slots. In that case you have your emit dateChanged(day, month, year); to raise the signal (move it into the if (dateSel.exec() == QDialog::Accepted) block). You do not want any

            public slots:
                  void onDateChanged(int day, int month, int year);
            

            in littleDate class. You only want it in whatever other classes/widgets/windows you have created which you want to be notified that the data has changed. Like:

            // otherwindow.h
            class OtherWindow : public QWidget
            {
            public slots:
                  void onDateChanged(int day, int month, int year);
            }
            
            // otherwindow.cpp
            void OtherWindow::onDateChanged(int day, int month, int year)
            {
                // do whatever in `OtherWindow`
            }
            
            // mainwindow.cpp
            // wherever you create an `OtherWindow` instance
            otherWindow = OtherWindow;
            connect(this, &MainWindow::dateChanged, otherWindow, &OtherWindow::onDateChanged);
            otherWindow.show();
            

            If you really wanted to use a slot in MainWindow to be notified of date changed --- which you should not need because you know that immediately after dateSel.exec() in MainWindow::on_pushButton_clicked() and can call whatever in MainWindow directly from there --- then you would define a MainWindow::onDateChanged slot and

            connect(this, &MainWindow::dateChanged, this, &MainWindow::onDateChanged);
            
            1 Reply Last reply
            0
            • U Offline
              U Offline
              Uberlinc
              wrote on last edited by
              #6

              Thanks.

              I'm still not understanding how the "populatestuff()" function is to be used, then.
              At what point is it called to populate fields in the mainwindow form with defaults, whether or not the CalendarWidget is used (in the second window) to select a new date?

              It should populate the date from the beginning with a default date.
              Then, and only then, if the user clicks on the second window and selects a date, the date values change and the fields in mainwindow are updated.

              Not sure how to achieve this.

              Thanks.

              JonBJ 1 Reply Last reply
              0
              • U Uberlinc

                Thanks.

                I'm still not understanding how the "populatestuff()" function is to be used, then.
                At what point is it called to populate fields in the mainwindow form with defaults, whether or not the CalendarWidget is used (in the second window) to select a new date?

                It should populate the date from the beginning with a default date.
                Then, and only then, if the user clicks on the second window and selects a date, the date values change and the fields in mainwindow are updated.

                Not sure how to achieve this.

                Thanks.

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #7

                @Uberlinc said in Basic Signals and Slots - don't know where to go.:

                It should populate the date from the beginning with a default date.

                So call it from MainWindow::MainWindow() constructor. Move the setting of thisDay/thisMonth/thisYear out of the body of populateStuff() and either pass their desired values in as parameters or make those variables class member variables.

                Then, and only then, if the user clicks on the second window and selects a date, the date values change and the fields in mainwindow are updated.

                So call it from MainWindow::on_pushButton_clicked(), in if (dateSel.exec() == QDialog::Accepted). Either pass the new values as parameters or store them as class member variables, as per whatever you did for constructor call. Or do whatever work there, and you don't need to call populateStuff().

                In both populateStuff() & on_pushButton_clicked() you need to think about whether day/month/year should be local variables or member variables, e.g. at present they do nothing in on_pushButton_clicked() other than get passed to the emit.

                1 Reply Last reply
                0
                • U Offline
                  U Offline
                  Uberlinc
                  wrote on last edited by
                  #8

                  Okay, that worked.

                  I was actually hoping that it might be a good exercise to get my head around Signals and Slots.
                  I guess not.

                  Any recommendations on tutorials or exercises to help me get a good grasp of Signals and Slots?

                  Thanks,

                  JonBJ 1 Reply Last reply
                  0
                  • U Uberlinc

                    Okay, that worked.

                    I was actually hoping that it might be a good exercise to get my head around Signals and Slots.
                    I guess not.

                    Any recommendations on tutorials or exercises to help me get a good grasp of Signals and Slots?

                    Thanks,

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by JonB
                    #9

                    @Uberlinc
                    I wrote earlier:

                    If you really wanted to use a slot in MainWindow to be notified of date changed --- which you should not need because you know that immediately after dateSel.exec() in MainWindow::on_pushButton_clicked() and can call whatever in MainWindow directly from there --- then you would define a MainWindow::onDateChanged slot and
                    connect(this, &MainWindow::dateChanged, this, &MainWindow::onDateChanged);

                    So do that and just emit the signal from on_pushButton_clicked(). Do not change whatever stuff directly from on_pushButton_clicked() (e.g. by calling populateStuff()) after all, do it in a MainWindow::onDateChanged() slot (or make MainWindow::populateStuff() a slot which you connect to the signal) instead.

                    1 Reply Last reply
                    0
                    • U Offline
                      U Offline
                      Uberlinc
                      wrote on last edited by
                      #10

                      Okay.
                      Thanks for your help!

                      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