[SOLVED] Using Signals and Slots to control UI



  • Hi there,

    I've recently started developing in QT and have run into an issue recently. Any insight would be appreciated.

    To provide some background:

    I have a Database that is constantly receiving values through modbus. The GUI should display some of these values and update periodically. As I have multiple forms being used, I'm using one class to handle the GUI elements. This class has a signal that is emitted based on a timer timeout, connected to a slot in one of the form's source. This slot should then change a ui element. However, while the function attached to the slot seems to run, it doesn't actually update the UI. I've created a push button with identical code that, when pressed, does update the UI.

    Attached is a snippet from the UI source and the header file.

    void EC_Saloon::update_ecs_values()
    {
        int buffer;
        buffer = senddatatoGUI(ENVIRONMENTAL_CONTROL,SALOON,REGISTERS,(REG_HUMIDITY));
        ui->lcd_humidity->display(buffer);
    }
    
    void EC_Saloon::on_pushButton_2_released()
    {
        int buffer;
        buffer = senddatatoGUI(ENVIRONMENTAL_CONTROL,SALOON,REGISTERS,(REG_HUMIDITY));
        ui->lcd_humidity->display(buffer);
    }
    

    And the header file.

    #define EC_SALOON_H
    
    #include <QDialog>
    namespace Ui {
    class EC_Saloon;
    }
    
    class EC_Saloon : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit EC_Saloon(QWidget *parent = 0);
        ~EC_Saloon();
    public slots:
        void update_ecs_values();
    private slots:
        void on_pushButton_released();
        void on_pushButton_2_released();
    
    private:
        Ui::EC_Saloon *ui;
    };
    
    
    #endif // EC_SALOON_H
    

    Just to note, the buffer line isn't the cause as I've commented it out in the past and hardcoded a value to pass to the UI but it still doesn't function.

    Many Thanks.

    EDIT: Solution Found. I was creating a new instance of a class that handles the signals and slots for the GUI. I'm now ensuring that all other sources refer to the same instance.



  • hihihiihihihih



  • better use on_pushButton_triggered()


  • Qt Champions 2016

    @Yuichi_C said:
    Hi and welcome

    Are you 100% sure that your slot
    void EC_Saloon::update_ecs_values()
    is called ?

    if you place a
    qDebug() << "in EC_Saloon::update_ecs_value";

    You can see that its called as expected ?

    Can you post your connect line ?
    You might need to use the queued connection type.



  • @mrjj

    Hi mrjj,

    I'm certain it's being called. I've added the debug line to the function and it appears in my application output.

    Here's the source

    void guihandler::initialise(){
        QTimer *timer = new QTimer();
        timer->setInterval(5000);
        QObject::connect(
                    timer, SIGNAL(timeout()),
                    this, SLOT(updateGUI()));
        timer->start();
    
        // Create connection from signals to slots
        EC_Saloon *ecshandler = new EC_Saloon();
        QObject::connect(
                    this, SIGNAL(requestupdate()),
                    ecshandler,SLOT(update_ecs_values()));
    
    }
    void guihandler::updateGUI(){
    
       //Connect this signal to slots for updating on each screen
        emit this->requestupdate();
    }
    

    I've just noticed now that I'm creating a new instance of EC_Saloon when creating the connection. That would explain a lot I think.

    Do I need to create the connection between the signal and slot on the creation of each dialog window?

    Many Thanks.


  • Qt Champions 2016

    Hi
    Ok. had to be sure. :)

    Yes the signal / slot connection is pr instance
    so you must hook up all new objects (also)

    If you only call guihandler::initialise() ONCE
    it seems fine but hard to guess about. :)

    If you can, use the new connect syntax as its type safe.
    https://wiki.qt.io/New_Signal_Slot_Syntax

    QObject::connect(this, &guihandler::requestupdate, ecshandler,&EC_Saloon ::update_ecs_values);
    


  • @Yuichi_C

    You can make a list of saloons and each time you create one, you append it to this list.

    Then create one slot where you update all saloons contained in the list.

    So you will need to make just one connection signal/slot



  • @mrjj

    Thanks, I've updated the syntax now.

    I've corrected the code now and everything seems to be working. I'm now creating one instance of the guihandler class and referencing the one instance now.

    @theshadowx

    I only want to have one instance of saloon at a time, however I do have other ui classes that use the same database. I hasn't thought about updating all classes simultaneously, think it'll come in handy. Thanks for your advice.

    Thank you all for your responses. Consider this one solved.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.