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. QLCDnumber, slots, and my own complete loss of mental function...
Forum Updated to NodeBB v4.3 + New Features

QLCDnumber, slots, and my own complete loss of mental function...

Scheduled Pinned Locked Moved Unsolved General and Desktop
29 Posts 3 Posters 7.2k Views 1 Watching
  • 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.
  • A Offline
    A Offline
    Aesgarth
    wrote on last edited by
    #1

    Further to my previous thread (here: https://forum.qt.io/topic/85055/gui-blocking/25 )

    I've resolved my GUI blocking issues but i'm having real trouble getting and lcdNumber to do what i want it to.

    I can get it to 0 and 1 (the correct outputs) when i press the buttons that they relate to, however, i also want it to increment every cycle of a process when other buttons are pressed... The power cycle and heat cycle buttons should increment once per cycle.

    Here's a youtube video of it in action... i need the lcdNumber to increment once every time the light flashes basically...

    https://youtu.be/pFInTHmJbiY

    Current files: (i think, have added a lot of commenting since last compile)

    mainwindow.cpp

    #include "mainwindow.h"
    #include "relayframe.h"
    #include "ui_mainwindow.h"
    #include <QDebug>
    #include <QVBoxLayout>
    #include <wiringPi.h>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        wiringPiSetup();
    
        QVBoxLayout *lay = new QVBoxLayout(ui->centralWidget);
    
        const int pins[] = {0, 1, 2, 3, 4, 5, 6}; // pins
        for(int i=0; i < 7; i++){
            RelayFrame *relay = new RelayFrame(pins[i], ui->centralWidget);
            lay->addWidget(relay);
        }
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    
    

    relaycontroller.h

    #ifndef RELAYCONTROLLER_H
    #define RELAYCONTROLLER_H
    
    #include <QObject>
    #include <QTimer>
    #include <wiringPi.h>
    #include <QDebug>
    
    class RelayController : public QObject
    {
        Q_OBJECT
    public:
    	//This sets the delay depending on which controller is using it and pin depending on which iteration of relayframe it's in
        explicit RelayController(int pin, int delay, QObject *parent = 0):QObject(parent){
            timer = new QTimer(this);
            state = false;
            timer->setInterval(delay);
            mPin = pin;
    		//
    		//I think i need to declare an integer here for the lcdNumber (initially 0?)
    		// it needs to be zeroed every time the controller is started...
    		//
            connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
            //connect(timer, &QTimer::timeout, this, &RelayController::onTimeout);
            pinMode (mPin, OUTPUT);
            relayLow();
        }
        void start(){
            qDebug()<<"start";
            timer->start();
        }
        void stop(){
            qDebug()<<"stop";
            timer->stop();
        }
    
        void relayLow(){
    		//Relay Off
            digitalWrite (mPin, LOW);
            qDebug()<<"low";
        }
        void relayHigh(){
            //Relay On
            digitalWrite(mPin, HIGH);
            qDebug()<<"high";
        }
    private slots:
    //This switches between on and off
        void onTimeout(){
            if(state)
                relayHigh();
    			//
    			//I think this is where i need to increment the lcdNumber
    			//integer from above, so that it increases by 1 every on/off 
    			//cycle but i'm not sure how to pass it back to the relayframe UI 
    			//and get it to display.. slots are the answer i think but i can't make them work, so far
    			//I've tried changing the lcdNumber from here but that dosen't work..
    			//
            else
                relayLow();
            state = !state;
        }
    private:
        QTimer *timer;
        bool state;
        int mPin;
    };
    
    
    #endif // RELAYCONTROLLER_H
    
    

    relayframe.cpp

    #include "relayframe.h"
    #include "ui_relayframe.h"
    
    #include <QPushButton>
    
    
    //relayframe is a box with buttons and an LCD widget in it,
    //created for each individual output pin. relayframe.ui is an XML
    //file determining layout, code is in relayframe.h
    RelayFrame::RelayFrame(int pin, QWidget *parent) :
        QFrame(parent),
        ui(new Ui::RelayFrame)
    {
        ui->setupUi(this);
        //power cycle controller, 750ms delay
        controller = new RelayController(pin, 750);
        //heat cycle controller, 2 hour (5400000ms) delay
        controller2 = new RelayController(pin,5400000);
    }
    
    RelayFrame::~RelayFrame()
    {
        delete ui;
    }
    // Power cycle button button
    // While clicked controller initialised above, found in relaycontroller.h
    // runs, when unchecked it stops (only one button per frame can be clicked
    // at once, buttons auto toggle on)
    void RelayFrame::on_powerBrtn_toggled(bool checked)
    {
        if(checked)
            controller->start();
    		//I need the lcdNumber to increment once every 
    		//cycle while this is running but obviously 
    		//that happens elsewhere
        else controller->stop();
    }
    // On button - turns on the pin relevant to this frame
    void RelayFrame::on_onBtn_clicked()
    {
        controller->relayHigh();
        //Set LCD to 1 while on... 
    	//THIS WORKS CORRECTLY
        ui->lcdNumber->display(1);
    }
    // Off button - turns off the pin relevant to this frame
    void RelayFrame::on_offBtn_clicked()
    {
        controller->relayLow();
    	//Set LCD to 0 while off... 
    	//THIS WORKS CORRECTLY
        ui->lcdNumber->display(0);
    
    }
    // Heat cycle button
    // While clicked controller2 initialised above, found in relaycontroller.h
    // runs, when unchecked it stops (only one button per frame can be clicked
    // at once, buttons auto toggle on.
    void RelayFrame::on_heatBtn_toggled(bool checked)
    {
        if(checked)
            controller2->start();
    		//I need the lcdNumber to increment once every 
    		//cycle while this is running but obviously 
    		//that happens elsewhere
        else controller2->stop();
    }
    

    relayframe.h

    #ifndef RELAYFRAME_H
    #define RELAYFRAME_H
    
    #include "relaycontroller.h"
    
    #include <QFrame>
    
    namespace Ui {
    class RelayFrame;
    }
    
    class RelayFrame : public QFrame
    {
        Q_OBJECT
    
    public:
        explicit RelayFrame(int pin, QWidget *parent = 0);
        ~RelayFrame();
    
    private slots:
        void on_powerBrtn_toggled(bool checked);
    
        void on_onBtn_clicked();
    
        void on_offBtn_clicked();
    
        void on_heatBtn_toggled(bool checked);
    
        //int lcdNumber();
    	//commented out because it didn't help
    
    private:
        Ui::RelayFrame *ui;
        RelayController *controller;
        RelayController *controller2;
    };
    
    #endif // RELAYFRAME_H
    

    Entire project in a zip file:
    www.aesgarth.co.uk/Project3.zip

    I've kind of got myself in over my head here a bit - the point of the project is supposed to be to make my job easier as otherwise i'd have to do this stuff manually but i'ts ended up being more work than I intended.

    Can someone point me in the right direction?

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Aesgarth said in QLCDnumber, slots, and my own complete loss of mental function...:

      i also want it to increment every cycle of a process when other buttons are pressed...

      What does that mean?

      in timers slot,
      here
      if(state)
      relayHigh();

      what you want to do here ?
      Set mainwind LCD to something?

      A 1 Reply Last reply
      0
      • mrjjM mrjj

        @Aesgarth said in QLCDnumber, slots, and my own complete loss of mental function...:

        i also want it to increment every cycle of a process when other buttons are pressed...

        What does that mean?

        in timers slot,
        here
        if(state)
        relayHigh();

        what you want to do here ?
        Set mainwind LCD to something?

        A Offline
        A Offline
        Aesgarth
        wrote on last edited by
        #3

        @mrjj set relayframe lcdNumber to it's current value +1

        There are 7 iterations of relayframe in the mainwindow - each with its own lcdnumber.

        mrjjM 1 Reply Last reply
        0
        • A Aesgarth

          @mrjj set relayframe lcdNumber to it's current value +1

          There are 7 iterations of relayframe in the mainwindow - each with its own lcdnumber.

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by mrjj
          #4

          @Aesgarth
          Why not make a new signal in RelayController
          like
          void SetLCD(int num)
          signals:
          void RaiseLCD(); // or what ever make sense. im not sure if you 0,1,2 or just 1,0
          and emit
          from RelayController where u need it

          then in
          RelayFrame
          have a slot that sets
          int num = ui->lcdNumber->XX ( get current value)
          num++;
          ui->lcdNumber->display(num);

          and you connect RelayController signal to each of
          the RelayFrame instances slot.
          Looked at code, just connect the new signal to a slot where u create the RelayController
          in RelayFrame

          So so i get it right
          There are X RelayFrame with 2 controllers each?
          When ever RelayController wants it should tell RelayFrame to increase
          the LCD number ?
          There is only one LCD but 2 controllers
          so the new signal should not give the number but simple make RelayFrame increase the current one?

          1 Reply Last reply
          2
          • A Offline
            A Offline
            Aesgarth
            wrote on last edited by
            #5

            I think that's the way to do it but I've been struggling with implementation. Maybe some coffee tomorrow will help me.

            Yes, 2 controllers but only one can operate at once - they do the same thing but with a different delay. So only one would ever be changing lcdNumber. Ideally on the button press it would start at 0 and count up.

            mrjjM 1 Reply Last reply
            0
            • A Aesgarth

              I think that's the way to do it but I've been struggling with implementation. Maybe some coffee tomorrow will help me.

              Yes, 2 controllers but only one can operate at once - they do the same thing but with a different delay. So only one would ever be changing lcdNumber. Ideally on the button press it would start at 0 and count up.

              mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by mrjj
              #6

              @Aesgarth
              Coffee always helps. :)
              Since RelayFrame has the LCD
              it should have
              public slots:
              void IncreaseLCD() { // make sure body is in .cpp
              // get current value, increase, set again to LCDNumber
              }
              void ResetLCD() {
              // setLCDNumber to 0
              }

              RelayController has
              signals:
              void IncreaseLCD(); // signals have no body!

              Then in
              RelayFrame::RelayFrame(int pin, QWidget *parent) : QFrame(parent), ui(new Ui::RelayFrame)
              {
              ui->setupUi(this);
              //power cycle controller, 750ms delay
              controller = new RelayController(pin, 750);
              connect( controller, SIGNAL(IncreaseLCD()), this, SLOT(IncreaseLCD()) );
              //heat cycle controller, 2 hour (5400000ms) delay
              controller2 = new RelayController(pin,5400000);
              connect( controller2, xxx same;
              }

              Then in RelayController
              you can say
              emit IncreaseLCD();
              any where u want and RelayFrame should increase it.
              and you can
              emit ResetLCD(); // to reset to zero

              Disclaimer: hasty typed so tons of typos etc
              Also, you should use the new connection syntax instead of SLOT() SIGNAL()
              https://wiki.qt.io/New_Signal_Slot_Syntax
              (sorry was too lazy;)

              A 1 Reply Last reply
              0
              • mrjjM mrjj

                @Aesgarth
                Coffee always helps. :)
                Since RelayFrame has the LCD
                it should have
                public slots:
                void IncreaseLCD() { // make sure body is in .cpp
                // get current value, increase, set again to LCDNumber
                }
                void ResetLCD() {
                // setLCDNumber to 0
                }

                RelayController has
                signals:
                void IncreaseLCD(); // signals have no body!

                Then in
                RelayFrame::RelayFrame(int pin, QWidget *parent) : QFrame(parent), ui(new Ui::RelayFrame)
                {
                ui->setupUi(this);
                //power cycle controller, 750ms delay
                controller = new RelayController(pin, 750);
                connect( controller, SIGNAL(IncreaseLCD()), this, SLOT(IncreaseLCD()) );
                //heat cycle controller, 2 hour (5400000ms) delay
                controller2 = new RelayController(pin,5400000);
                connect( controller2, xxx same;
                }

                Then in RelayController
                you can say
                emit IncreaseLCD();
                any where u want and RelayFrame should increase it.
                and you can
                emit ResetLCD(); // to reset to zero

                Disclaimer: hasty typed so tons of typos etc
                Also, you should use the new connection syntax instead of SLOT() SIGNAL()
                https://wiki.qt.io/New_Signal_Slot_Syntax
                (sorry was too lazy;)

                A Offline
                A Offline
                Aesgarth
                wrote on last edited by
                #7

                @mrjj
                Coffee isn't helping... I'm quite sure that's the way to do it but so far i'm failing... I can't seem to get it right. I would post the errors but for the fact that i'm compiling on the actual device which is a raspberry pi in a box, and only a 7 inch screen in portrait mode makes everything more difficult. I will persist in trying. already spotted one stupid error that i've made...

                J.HilkJ 1 Reply Last reply
                0
                • A Offline
                  A Offline
                  Aesgarth
                  wrote on last edited by
                  #8

                  simply trying to get it to display something so i know it's working before i add the complication of incrementing numbers....

                  relayframe.cpp:

                  #include "relayframe.h"
                  #include "ui_relayframe.h"
                  
                  #include <QPushButton>
                  
                  
                  //relayframe is a box with buttons and an LCD widget in it,
                  //created for each individual output pin. relayframe.ui is an XML
                  //file determining layout, code is in relayframe.h
                  RelayFrame::RelayFrame(int pin, QWidget *parent) :
                      QFrame(parent),
                      ui(new Ui::RelayFrame)
                  {
                      ui->setupUi(this);
                      //power cycle controller, 750ms delay
                      controller = new RelayController(pin, 750);
                  	connect( controller, SIGNAL(IncreaseLCD()), this, SLOT(IncreaseLCD()) );
                      //heat cycle controller, 2 hour (5400000ms) delay
                      controller2 = new RelayController(pin,5400000);
                  }
                  
                  RelayFrame::~RelayFrame()
                  {
                      delete ui;
                  }
                  // Power cycle button button
                  // While clicked controller initialised above, found in relaycontroller.h
                  // runs, when unchecked it stops (only one button per frame can be clicked
                  // at once, buttons auto toggle on)
                  void RelayFrame::on_powerBrtn_toggled(bool checked)
                  {
                      if(checked)
                          controller->start();
                  		//I need the lcdNumber to increment once every 
                  		//cycle while this is running but obviously 
                  		//that happens elsewhere
                      else controller->stop();
                  }
                  // On button - turns on the pin relevant to this frame
                  void RelayFrame::on_onBtn_clicked()
                  {
                      controller->relayHigh();
                      //Set LCD to 1 while on... 
                  	//THIS WORKS CORRECTLY
                      ui->lcdNumber->display(1);
                  }
                  // Off button - turns off the pin relevant to this frame
                  void RelayFrame::on_offBtn_clicked()
                  {
                      controller->relayLow();
                  	//Set LCD to 0 while off... 
                  	//THIS WORKS CORRECTLY
                      ui->lcdNumber->display(0);
                  
                  }
                  // Heat cycle button
                  // While clicked controller2 initialised above, found in relaycontroller.h
                  // runs, when unchecked it stops (only one button per frame can be clicked
                  // at once, buttons auto toggle on.
                  void RelayFrame::on_heatBtn_toggled(bool checked)
                  {
                      if(checked)
                          controller2->start();
                  		//I need the lcdNumber to increment once every 
                  		//cycle while this is running but obviously 
                  		//that happens elsewhere
                      else controller2->stop();
                  }
                  void IncreaseLCD() 
                  { 
                  	    ui->lcdNumber->display(5); // This line is producing the error....
                  // make sure body is in .cpp
                  // get current value, increase, set again to LCDNumber
                  }
                  

                  i'm getting

                  'ui' was not declared in this scope

                  1 Reply Last reply
                  0
                  • A Aesgarth

                    @mrjj
                    Coffee isn't helping... I'm quite sure that's the way to do it but so far i'm failing... I can't seem to get it right. I would post the errors but for the fact that i'm compiling on the actual device which is a raspberry pi in a box, and only a 7 inch screen in portrait mode makes everything more difficult. I will persist in trying. already spotted one stupid error that i've made...

                    J.HilkJ Offline
                    J.HilkJ Offline
                    J.Hilk
                    Moderators
                    wrote on last edited by
                    #9

                    @Aesgarth Hi,

                    I downloaded the zip file to take a look.

                    From hat I can see to far, you try to access the Mainwindow Ui element from a different class than mainwindow.

                    That is technically possible, but not something you should do.

                    my suggestion: in relaycontroller add a signal

                    signals:
                        void lcdNumber(int number);
                    

                    a private counter

                    private:
                        QTimer *timer;
                        bool state;
                        int mPin;
                        int cntState;
                    

                    it get resetet by start

                    void start(){
                            qDebug()<<"start";
                            timer->start();
                            cntState = 0;
                            emit lcdNumber(0);
                        }
                    

                    and in you slot onTimeout you emit the new cnt

                    private slots:
                        void onTimeout(){
                            if(state){
                                relayHigh();
                                cntState++;
                                emit lcdNumber(cntState);
                            }
                            else
                                relayLow();
                            state = !state;
                        }
                    

                    now you simply connect the signal to your lcd display

                    something like this should do it (in relayFrame),

                    connect(controller2 &RelayController::lcdNumber, this, [=](int number){lcdNumber.display(number);});
                    

                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                    Q: What's that?
                    A: It's blue light.
                    Q: What does it do?
                    A: It turns blue.

                    A 2 Replies Last reply
                    2
                    • J.HilkJ J.Hilk

                      @Aesgarth Hi,

                      I downloaded the zip file to take a look.

                      From hat I can see to far, you try to access the Mainwindow Ui element from a different class than mainwindow.

                      That is technically possible, but not something you should do.

                      my suggestion: in relaycontroller add a signal

                      signals:
                          void lcdNumber(int number);
                      

                      a private counter

                      private:
                          QTimer *timer;
                          bool state;
                          int mPin;
                          int cntState;
                      

                      it get resetet by start

                      void start(){
                              qDebug()<<"start";
                              timer->start();
                              cntState = 0;
                              emit lcdNumber(0);
                          }
                      

                      and in you slot onTimeout you emit the new cnt

                      private slots:
                          void onTimeout(){
                              if(state){
                                  relayHigh();
                                  cntState++;
                                  emit lcdNumber(cntState);
                              }
                              else
                                  relayLow();
                              state = !state;
                          }
                      

                      now you simply connect the signal to your lcd display

                      something like this should do it (in relayFrame),

                      connect(controller2 &RelayController::lcdNumber, this, [=](int number){lcdNumber.display(number);});
                      
                      A Offline
                      A Offline
                      Aesgarth
                      wrote on last edited by
                      #10

                      @J.Hilk

                      apologies - i've just reverted to the files in the zip and they do not work, so reference to lcdNumber from relaycontroller.h has been removed and where "lcdNumber.display" was used in relayframe.cpp that has been replaced with
                      "ui->lcdNumber->display" to get the LCD display working for the on and off buttons.

                      The UI element i'm trying to change is in relayframe rather than mainwindow. I'm now going to have a look at implementing your method.

                      mrjjM 1 Reply Last reply
                      0
                      • A Aesgarth

                        @J.Hilk

                        apologies - i've just reverted to the files in the zip and they do not work, so reference to lcdNumber from relaycontroller.h has been removed and where "lcdNumber.display" was used in relayframe.cpp that has been replaced with
                        "ui->lcdNumber->display" to get the LCD display working for the on and off buttons.

                        The UI element i'm trying to change is in relayframe rather than mainwindow. I'm now going to have a look at implementing your method.

                        mrjjM Offline
                        mrjjM Offline
                        mrjj
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        @Aesgarth

                        in the first code, one error was

                        void IncreaseLCD() {
                        xxx
                        }

                        but should been a member of it
                        RelayFrame::IncreaseLCD {
                        xx
                        }

                        1 Reply Last reply
                        1
                        • J.HilkJ J.Hilk

                          @Aesgarth Hi,

                          I downloaded the zip file to take a look.

                          From hat I can see to far, you try to access the Mainwindow Ui element from a different class than mainwindow.

                          That is technically possible, but not something you should do.

                          my suggestion: in relaycontroller add a signal

                          signals:
                              void lcdNumber(int number);
                          

                          a private counter

                          private:
                              QTimer *timer;
                              bool state;
                              int mPin;
                              int cntState;
                          

                          it get resetet by start

                          void start(){
                                  qDebug()<<"start";
                                  timer->start();
                                  cntState = 0;
                                  emit lcdNumber(0);
                              }
                          

                          and in you slot onTimeout you emit the new cnt

                          private slots:
                              void onTimeout(){
                                  if(state){
                                      relayHigh();
                                      cntState++;
                                      emit lcdNumber(cntState);
                                  }
                                  else
                                      relayLow();
                                  state = !state;
                              }
                          

                          now you simply connect the signal to your lcd display

                          something like this should do it (in relayFrame),

                          connect(controller2 &RelayController::lcdNumber, this, [=](int number){lcdNumber.display(number);});
                          
                          A Offline
                          A Offline
                          Aesgarth
                          wrote on last edited by
                          #12

                          @J.Hilk said in QLCDnumber, slots, and my own complete loss of mental function...:

                          @Aesgarth Hi,

                          I downloaded the zip file to take a look.

                          From hat I can see to far, you try to access the Mainwindow Ui element from a different class than mainwindow.

                          That is technically possible, but not something you should do.

                          my suggestion: in relaycontroller add a signal

                          signals:
                              void lcdNumber(int number);
                          

                          a private counter

                          private:
                              QTimer *timer;
                              bool state;
                              int mPin;
                              int cntState;
                          

                          it get resetet by start

                          void start(){
                                  qDebug()<<"start";
                                  timer->start();
                                  cntState = 0;
                                  emit lcdNumber(0);
                              }
                          

                          and in you slot onTimeout you emit the new cnt

                          private slots:
                              void onTimeout(){
                                  if(state){
                                      relayHigh();
                                      cntState++;
                                      emit lcdNumber(cntState);
                                  }
                                  else
                                      relayLow();
                                  state = !state;
                              }
                          

                          This all works out excellent, and i can get the count to output in qdebug

                          private slots:
                              void onTimeout(){
                                  if(state){
                                      relayHigh();
                          	    cntState++;
                                      emit lcdNumber(cntState);
                          	    qDebug()<<cntState;
                                  }
                                  else
                                      relayLow();
                                  state = !state;
                          

                          now you simply connect the signal to your lcd display

                          something like this should do it (in relayFrame),

                          connect(controller2 &RelayController::lcdNumber, this, [=](int number){lcdNumber.display(number);});
                          

                          However i'm struggling with this bit. I think the error was lcdNumber is protected..., i'll keep trying though and see if i can work it out.

                          J.HilkJ 1 Reply Last reply
                          0
                          • A Aesgarth

                            @J.Hilk said in QLCDnumber, slots, and my own complete loss of mental function...:

                            @Aesgarth Hi,

                            I downloaded the zip file to take a look.

                            From hat I can see to far, you try to access the Mainwindow Ui element from a different class than mainwindow.

                            That is technically possible, but not something you should do.

                            my suggestion: in relaycontroller add a signal

                            signals:
                                void lcdNumber(int number);
                            

                            a private counter

                            private:
                                QTimer *timer;
                                bool state;
                                int mPin;
                                int cntState;
                            

                            it get resetet by start

                            void start(){
                                    qDebug()<<"start";
                                    timer->start();
                                    cntState = 0;
                                    emit lcdNumber(0);
                                }
                            

                            and in you slot onTimeout you emit the new cnt

                            private slots:
                                void onTimeout(){
                                    if(state){
                                        relayHigh();
                                        cntState++;
                                        emit lcdNumber(cntState);
                                    }
                                    else
                                        relayLow();
                                    state = !state;
                                }
                            

                            This all works out excellent, and i can get the count to output in qdebug

                            private slots:
                                void onTimeout(){
                                    if(state){
                                        relayHigh();
                            	    cntState++;
                                        emit lcdNumber(cntState);
                            	    qDebug()<<cntState;
                                    }
                                    else
                                        relayLow();
                                    state = !state;
                            

                            now you simply connect the signal to your lcd display

                            something like this should do it (in relayFrame),

                            connect(controller2 &RelayController::lcdNumber, this, [=](int number){lcdNumber.display(number);});
                            

                            However i'm struggling with this bit. I think the error was lcdNumber is protected..., i'll keep trying though and see if i can work it out.

                            J.HilkJ Offline
                            J.HilkJ Offline
                            J.Hilk
                            Moderators
                            wrote on last edited by
                            #13

                            @Aesgarth

                            mmh,

                            Lcd number is part of the relayframe ui so you should be able to use a normal/but overloaded connect statement

                            
                            RelayFrame::RelayFrame(int pin, QWidget *parent) :
                                QFrame(parent),
                                ui(new Ui::RelayFrame)
                            {
                                ui->setupUi(this);
                                //power cycle controller, 750ms delay
                                controller = new RelayController(pin, 750);
                                //heat cycle controller, 2 hour (5400000ms) delay
                                controller2 = new RelayController(pin,5400000); 
                            
                                connect(controller2 &RelayController::lcdNumber, ui->lcdNumber, QOverload<int>::of(&QLCDNumber::display));
                            }
                            

                            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                            Q: What's that?
                            A: It's blue light.
                            Q: What does it do?
                            A: It turns blue.

                            A 1 Reply Last reply
                            1
                            • J.HilkJ J.Hilk

                              @Aesgarth

                              mmh,

                              Lcd number is part of the relayframe ui so you should be able to use a normal/but overloaded connect statement

                              
                              RelayFrame::RelayFrame(int pin, QWidget *parent) :
                                  QFrame(parent),
                                  ui(new Ui::RelayFrame)
                              {
                                  ui->setupUi(this);
                                  //power cycle controller, 750ms delay
                                  controller = new RelayController(pin, 750);
                                  //heat cycle controller, 2 hour (5400000ms) delay
                                  controller2 = new RelayController(pin,5400000); 
                              
                                  connect(controller2 &RelayController::lcdNumber, ui->lcdNumber, QOverload<int>::of(&QLCDNumber::display));
                              }
                              
                              A Offline
                              A Offline
                              Aesgarth
                              wrote on last edited by
                              #14

                              @J.Hilk
                              getting what appears to be the same error with that.

                              so what i'm currently working with is:

                              relayframe.h

                              #ifndef RELAYFRAME_H
                              #define RELAYFRAME_H
                              
                              #include "relaycontroller.h"
                              
                              #include <QFrame>
                              
                              namespace Ui {
                              class RelayFrame;
                              }
                              
                              class RelayFrame : public QFrame
                              {
                                  Q_OBJECT
                              
                              public:
                                  explicit RelayFrame(int pin, QWidget *parent = 0);
                                  ~RelayFrame();
                              
                              private slots:
                                  void on_powerBrtn_toggled(bool checked);
                              
                                  void on_onBtn_clicked();
                              
                                  void on_offBtn_clicked();
                              
                                  void on_heatBtn_toggled(bool checked);
                              
                              private:
                                  Ui::RelayFrame *ui;
                                  RelayController *controller;
                                  RelayController *controller2;
                              };
                              
                              #endif // RELAYFRAME_H
                              
                              

                              relayframe.cpp

                              #include "relayframe.h"
                              #include "ui_relayframe.h"
                              
                              #include <QPushButton>
                              
                              
                              //relayframe is a box with buttons and an LCD widget in it,
                              //created for each individual output pin. relayframe.ui is an XML
                              //file determining layout, code is in relayframe.h
                              RelayFrame::RelayFrame(int pin, QWidget *parent) :
                                  QFrame(parent),
                                  ui(new Ui::RelayFrame)
                              {
                                  ui->setupUi(this);
                                  //power cycle controller, 750ms delay
                                  controller = new RelayController(pin, 750);
                              	//heat cycle controller, 2 hour (5400000ms) delay
                                  controller2 = new RelayController(pin,5400000);
                              }
                              
                              RelayFrame::~RelayFrame()
                              {
                                  delete ui;
                              }
                              // Power cycle button button
                              // While clicked controller initialised above, found in relaycontroller.h
                              // runs, when unchecked it stops (only one button per frame can be clicked
                              // at once, buttons auto toggle on)
                              void RelayFrame::on_powerBrtn_toggled(bool checked)
                              {
                                  if(checked)
                                      controller->start();
                                  else controller->stop();
                              }
                              // On button - turns on the pin relevant to this frame
                              void RelayFrame::on_onBtn_clicked()
                              {
                                  controller->relayHigh();
                                  //Set LCD to 1 while on...
                              	//this works
                                  ui->lcdNumber->display(1);
                              }
                              // Off button - turns off the pin relevant to this frame
                              void RelayFrame::on_offBtn_clicked()
                              {
                                  controller->relayLow();
                              	//Set LCD to 0 while off...
                              	//this works
                              	ui->lcdNumber->display(0);
                              }
                              // Heat cycle button
                              // While clicked controller2 initialised above, found in relaycontroller.h
                              // runs, when unchecked it stops (only one button per frame can be clicked
                              // at once, buttons auto toggle on.
                              void RelayFrame::on_heatBtn_toggled(bool checked)
                              {
                                  if(checked)
                                      controller2->start();
                                  else controller2->stop();
                              }
                              // Everything currently in here works
                              

                              and relaycontroller.h

                              #ifndef RELAYCONTROLLER_H
                              #define RELAYCONTROLLER_H
                              
                              #include <QObject>
                              #include <QTimer>
                              #include <wiringPi.h>
                              #include <QDebug>
                              
                              class RelayController : public QObject
                              {
                                  Q_OBJECT
                              	
                              signals:
                                  void lcdNumber(int number);
                              	
                              public:
                                  explicit RelayController(int pin, int delay, QObject *parent = 0):QObject(parent){
                                      timer = new QTimer(this);
                                      state = false;
                                      timer->setInterval(delay);
                                      mPin = pin;
                                      connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
                                      pinMode (mPin, OUTPUT);
                              		//Sets relay to off on startup
                                      relayLow();
                                  }
                                  void start(){
                                      //qDebug()<<"start";
                              		//start timer
                                      timer->start();
                              		//sets counter to 0 at start. Works
                                      cntState = 0;
                                      emit lcdNumber(0);
                                  }
                                  void stop(){
                                      //qDebug()<<"stop";
                              		//
                                      timer->stop();
                                  }
                              
                                  void relayLow(){
                              		//Turn off relay
                                      digitalWrite (mPin, LOW);
                                      //qDebug()<<"low";
                                  }
                                  void relayHigh(){
                                      //relay on
                                      digitalWrite(mPin, HIGH);
                                      //qDebug()<<"high";
                                  }
                              private slots:
                                  void onTimeout(){
                                      if(state){
                              			//turn on relay
                                          relayHigh();
                              			//increment counter
                              			cntState++;
                              			//
                                          emit lcdNumber(cntState);
                              			//debug output counter value. works.
                              			qDebug()<<cntState;
                                      }
                                      else
                                          relayLow();
                                      state = !state;
                                  }
                              private:
                                  QTimer *timer;
                                  bool state;
                                  int mPin;
                              	int cntState;
                              };
                              
                              
                              #endif // RELAYCONTROLLER_H
                              
                              

                              Posting this for my own reference point as much as anything else - so if i break it i know where to come back to.

                              1 Reply Last reply
                              0
                              • A Offline
                                A Offline
                                Aesgarth
                                wrote on last edited by
                                #15

                                I think i'm going to have to give up on this for the moment. I can't get it to work, and i don't have time to properly learn what i'm doing wrong as well as doing my actual job. If it wasn't for each compile taking up to 10 minutes i might be in with a chance. that and not being able to copy error codes off the remote device.

                                Really frustrating being this close, however i clearly don't understand what i'm doing... I'm going to have to try to set aside some time to properly learn how to use QT and come back to this.

                                1 Reply Last reply
                                0
                                • mrjjM Offline
                                  mrjjM Offline
                                  mrjj
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #16

                                  Hi
                                  it looks pretty close but hard to say without the actual error and line number :)
                                  Let me know if you need a sample of talking to an LCD from other class.
                                  The basic version is not that complicated, but can be hard the first times.

                                  A 1 Reply Last reply
                                  1
                                  • mrjjM mrjj

                                    Hi
                                    it looks pretty close but hard to say without the actual error and line number :)
                                    Let me know if you need a sample of talking to an LCD from other class.
                                    The basic version is not that complicated, but can be hard the first times.

                                    A Offline
                                    A Offline
                                    Aesgarth
                                    wrote on last edited by
                                    #17

                                    @mrjj

                                    yes please, i'll have a look at a sample and see if i can work it out.

                                    mrjjM 1 Reply Last reply
                                    0
                                    • A Aesgarth

                                      @mrjj

                                      yes please, i'll have a look at a sample and see if i can work it out.

                                      mrjjM Offline
                                      mrjjM Offline
                                      mrjj
                                      Lifetime Qt Champion
                                      wrote on last edited by mrjj
                                      #18

                                      @Aesgarth
                                      Hi
                                      Here is a very basic sample.
                                      I has LCD in mainwindow and pops a dialog where u can enter number to have it display that.
                                      It as basic as it can get as i try to have as little code as possible to focus on the signal and slot thing.

                                      alt text

                                      Test Project
                                      https://www.dropbox.com/s/u94zqx9v9c8xfdf/LCDOtherClass.zip?dl=0

                                      (sorry its c++. I wish i could do python :)

                                      Even its a MainWindow, the concept is 100% the same.
                                      So slot in class that has LCD and signal in controller.

                                      A 1 Reply Last reply
                                      3
                                      • mrjjM mrjj

                                        @Aesgarth
                                        Hi
                                        Here is a very basic sample.
                                        I has LCD in mainwindow and pops a dialog where u can enter number to have it display that.
                                        It as basic as it can get as i try to have as little code as possible to focus on the signal and slot thing.

                                        alt text

                                        Test Project
                                        https://www.dropbox.com/s/u94zqx9v9c8xfdf/LCDOtherClass.zip?dl=0

                                        (sorry its c++. I wish i could do python :)

                                        Even its a MainWindow, the concept is 100% the same.
                                        So slot in class that has LCD and signal in controller.

                                        A Offline
                                        A Offline
                                        Aesgarth
                                        wrote on last edited by Aesgarth
                                        #19

                                        @mrjj
                                        Excellent, that helps... I think i understand what's going on there...
                                        however.... this bit...

                                        void MainWindow::on_pushButton_released()
                                        {
                                            Dialog dia;
                                            connect( &dia, &Dialog::SetLCD, this, &MainWindow::SetLCD  );
                                            dia.exec();
                                        }
                                        

                                        i'm not sure where to put it in my version.

                                        relaycontroller.h is where pretty much everything happens - switching of things and the counter...

                                        #ifndef RELAYCONTROLLER_H
                                        #define RELAYCONTROLLER_H
                                        
                                        #include <QObject>
                                        #include <QTimer>
                                        #include <wiringPi.h>
                                        #include <QDebug>
                                        
                                        class RelayController : public QObject
                                        {
                                            Q_OBJECT
                                        public:
                                            explicit RelayController(int pin, int delay, QObject *parent = 0):QObject(parent){
                                                timer = new QTimer(this);
                                                state = false;
                                                timer->setInterval(delay);
                                                mPin = pin;
                                                //old style
                                                connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
                                                //new style
                                                //connect(timer, &QTimer::timeout, this, &RelayController::onTimeout);
                                                pinMode (mPin, OUTPUT);
                                                relayLow();
                                            }
                                            void start(){
                                                qDebug()<<"start";
                                                timer->start();
                                        		//zero counter
                                        		cntState = 0;
                                        		//send to LCD
                                                emit setLCD(0);
                                            }
                                            void stop(){
                                                qDebug()<<"stop";
                                                timer->stop();
                                            }
                                        
                                            void relayLow(){
                                                digitalWrite (mPin, LOW);
                                                qDebug()<<"low";
                                            }
                                            void relayHigh(){
                                                //code here: relay on
                                                digitalWrite(mPin, HIGH);
                                                qDebug()<<"high";
                                            }
                                        signals:
                                            void setLCD(int number);
                                        	
                                        private slots:
                                            void onTimeout(){
                                                if(state){
                                                    relayHigh();
                                        			//increment counter
                                        			cntState++;
                                        			//send to LCD
                                                    emit setLCD(cntState);
                                        			qDebug()<<cntState;
                                                }
                                                else
                                                    relayLow();
                                                state = !state;
                                            }
                                        private:
                                            QTimer *timer;
                                            bool state;
                                            int mPin;
                                        	int cntState;
                                        };
                                        
                                        
                                        #endif // RELAYCONTROLLER_H
                                        
                                        

                                        and RelayFrame is where the LCD is...

                                        #include "relayframe.h"
                                        #include "ui_relayframe.h"
                                        
                                        #include <QPushButton>
                                        
                                        
                                        //relayframe is a box with buttons and an LCD widget in it,
                                        //created for each individual output pin. relayframe.ui is an XML
                                        //file determining layout, code is in relayframe.h
                                        RelayFrame::RelayFrame(int pin, QWidget *parent) :
                                            QFrame(parent),
                                            ui(new Ui::RelayFrame)
                                        {
                                            ui->setupUi(this);
                                            //power cycle controller, 750ms delay
                                            controller = new RelayController(pin, 750);
                                            //heat cycle controller, 2 hour (5400000ms) delay
                                            controller2 = new RelayController(pin,5400000);
                                        }
                                        
                                        RelayFrame::~RelayFrame()
                                        {
                                            delete ui;
                                        }
                                        // Power cycle button button
                                        // While clicked controller initialised above, found in relaycontroller.h
                                        // runs, when unchecked it stops (only one button per frame can be clicked
                                        // at once, buttons auto toggle on)
                                        void RelayFrame::on_powerBrtn_toggled(bool checked)
                                        {
                                            if(checked)
                                                controller->start();
                                            else controller->stop();
                                        }
                                        // On button - turns on the pin relevant to this frame
                                        void RelayFrame::on_onBtn_clicked()
                                        {
                                            controller->relayHigh();
                                            //Set LCD to 1 while on...
                                            ui->lcdNumber->display(1);
                                        }
                                        // Off button - turns off the pin relevant to this frame
                                        void RelayFrame::on_offBtn_clicked()
                                        {
                                            controller->relayLow();
                                        	ui->lcdNumber->display(0);
                                        }
                                        // Heat cycle button
                                        // While clicked controller2 initialised above, found in relaycontroller.h
                                        // runs, when unchecked it stops (only one button per frame can be clicked
                                        // at once, buttons auto toggle on.
                                        void RelayFrame::on_heatBtn_toggled(bool checked)
                                        {
                                            if(checked)
                                                controller2->start();
                                            else controller2->stop();
                                        }
                                        //
                                        void RelayFrame::SetLCD(int value) 
                                        {
                                          ui->lcdNumber->display( QString::number(value)  );
                                        }
                                        

                                        This compiles and runs - but obviously as setLCD in the 2 places are not connected as yet the LCD number doesn't update...

                                        Edit: there's something odd going on with the indentation when i copy and paste - but it looks ok before i do that, and seems to work. The last few lines of RelayFrame are where the relevant code is...

                                        1 Reply Last reply
                                        0
                                        • mrjjM Offline
                                          mrjjM Offline
                                          mrjj
                                          Lifetime Qt Champion
                                          wrote on last edited by mrjj
                                          #20

                                          Hi

                                          the Dialog is the controller and
                                          mainwindow is relayframe

                                          RelayFrame::RelayFrame(int pin, QWidget *parent) :
                                              QFrame(parent),
                                              ui(new Ui::RelayFrame)
                                          {
                                              ui->setupUi(this);
                                          
                                              controller = new RelayController(pin, 750);
                                          // connect here !
                                          
                                              controller2 = new RelayController(pin,5400000);
                                          // and HERE too
                                          
                                          }
                                          
                                          A 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