Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

GUI change with signal and slot



  • HI, I have a question. I'm confusing with change GUI with signal and slot. I'm making TCP/IP connect App. I want to make if TCP/IP connect with another device, the user let know connection with GUI. I confirmed that slot function get the value. but GUI is not changed. Slot Function code In UI cpp file ,
    if ( x == 0)
    {
    qDebug() << "connected"
    ui->firstToggle->setVisible(true)
    }
    I checked debug log "connected" but next code not working.

    Is there need another thread or someting?
    Please let me know how to change GUI .


  • Lifetime Qt Champion

    @duckrae said in GUI change with signal and slot:

    Is there need another thread or someting?

    No

    It is really unclear what you did so far. You posted a small piece of code without any context.
    Are you blocking the event loop somewhere (endless loops for example)? Please provide more information/code.



  • @jsulm application.h

    #ifndef APPLICATION_H
    #define APPLICATION_H
    
    #include <QWidget>
    #include <QObject>
    #include <menu.h>
    #include <QTcpServer>
    #include "myserver.h"
    #include "mythread.h"
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class application; }
    QT_END_NAMESPACE
    
    class application : public QWidget
    {
    Q_OBJECT
    
    public:
    application(QWidget *parent = nullptr);
    ~application();
    
    private slots:
    void on_menuBt_clicked();
    void menuBackBtClicked();
    void showApp(QString strValue);
    
    private:
    Ui::application *ui;
    menu menuPage;
    
    };
    
    #endif // APPLICATION_H
    
    

    application.cpp

    #include "application.h"
    #include "ui_application.h"
    #include "myserver.h"
    #include "mythread.h"
    
    application::application(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::application)
    {
    ui->setupUi(this);
    
    // Myserver *myserver = new Myserver();
    
    ui->firstToggle->setVisible(false);
    ui->secondToggle->setVisible(false);
    ui->thirdToggle->setVisible(false);
    ui->forthToggle->setVisible(false);
    ui->stackedWidget->addWidget(&menuPage);
    
    ui->stackedWidget->insertWidget(1, &menuPage);
    
    connect(&menuPage, SIGNAL(menuBackClick()), this, SLOT(menuBackBtClicked()));
    connect(myserver, SIGNAL(sendApp(QString)), this, SLOT(showApp(QString)));
    
    
    setWindowFlags(Qt::FramelessWindowHint);
    }
    
    application::~application()
    {
    delete ui;
    }
    
    void application::on_menuBt_clicked()
    {
    ui->stackedWidget->setCurrentIndex(1); //menuLayout
    }
    
    void application::menuBackBtClicked()
    {
    ui->stackedWidget->setCurrentIndex(0);
    }
    
    void application::showApp(QString strValue) {
    QString compare = "13";
    int x = QString::compare(strValue,compare, Qt::CaseInsensitive);
    if(x == 0) {
    qDebug() << "connected"
    ui->firstToggle->setVisible(true);
    }
    }
    

    myserver.h

    #ifndef MYSERVER_H
    #define MYSERVER_H
    
    #include <QObject>
    #include <QTcpServer>
    #include "mythread.h"
    #include "application.h"
    
    class Myserver : public QTcpServer
    {
    Q_OBJECT
    
    public:
    explicit Myserver(QObject *parent = 0);
    void startServer();
    signals:
    void sendApp(QString strValue);
    
    private slots:
    void showValue(QString strValue);
    
    protected:
    void incomingConnection(qintptr socketDescriptor);
    
    private:
    MyThread *mythread;
    
    };
    
    #endif // MYSERVER_H
    

    myserver.cpp

    #include "myserver.h"
    #include "mythread.h"
    #include "application.h"
    
    Myserver::Myserver(QObject *parent) :
    QTcpServer(parent)
    {
    }
    
    void Myserver::startServer()
    {
    int port = 3333;
    
    if(!this->listen(QHostAddress::Any,port))
    {
        qDebug() << "Could not start server";
    }
    else
    {
        qDebug() << "Listening to port " << port << "...";
    }
    }
    
    void Myserver::incomingConnection(qintptr socketDescriptor)
    {
    // We have a new connection
    qDebug() << socketDescriptor << " Connecting...";
    
    MyThread *thread = new MyThread(socketDescriptor, this);
    
    // connect signal/slot
    // once a thread is not needed, it will be beleted later
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    connect(thread, SIGNAL(sendValue(QString)), this, SLOT(showValue(QString)));
    
    thread->start();
    }
    void Myserver::showValue(QString strValue){
    emit sendApp(strValue);
    }
    
    

    mythread.h

    #ifndef MYTHREAD_H
    #define MYTHREAD_H
    
    #include <QObject>
    #include <QTcpSocket>
    #include <QThread>
    #include <QDebug>
    
    class MyThread : public QThread
    {
    Q_OBJECT
    public:
    explicit MyThread(qintptr ID, QObject *parent = 0);
    void run();
    
    signals:
    void error(QTcpSocket::SocketError socketerror);
    void sendValue(QString strValue);
    
    private slots:
    void readyRead();
    void disconnected();
    
    private:
    QTcpSocket *socket;
    qintptr socketDescriptor;
    
    };
    
    #endif // MYTHREAD_H
    

    mythread.cpp

    #include "mythread.h"
    
    #include <QThread>
    
    MyThread::MyThread(qintptr ID, QObject *parent) :
    QThread(parent)
    {
    this->socketDescriptor = ID;
    }
    
    int count = 0;
    
    void MyThread::run()
    {
    // thread starts here
    qDebug() << " Thread started";
    
    socket = new QTcpSocket();
    
    // set the ID
    if(!socket->setSocketDescriptor(this->socketDescriptor))
    {
        // something's wrong, we just emit a signal
        emit error(socket->error());
        return;
    }
    
    // connect socket and signal
    // note - Qt::DirectConnection is used because it's multithreaded
    //        This makes the slot to be invoked immediately, when the signal is emitted.
    
    connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
    connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
    
    // We'll have multiple clients, we want to know which is which
    qDebug() << socketDescriptor << "Client connected";
    
    QString strValue = QString::number(socketDescriptor);
    
    emit sendValue(strValue);
    
    // make this thread a loop,
    // thread will stay alive so that signal/slot to function properly
    // not dropped out in the middle when thread dies
    
    exec();
    }
    
    void MyThread::readyRead()
    {
    // get the information
    QByteArray Data = socket->readAll();
    
    // will write on server side window
    qDebug() << socketDescriptor << " Data in: " << Data;
    
    socket->write(Data);
    }
    
    void MyThread::disconnected()
    {
    qDebug() << socketDescriptor << " Disconnected";
    
    socket->deleteLater();
    exit(0);
    }
    

    I want to change GUI in application.cpp
    I'm so sorry my code is poor, this is my first time for develope with qt
    Could you help me?



  • @duckrae please format your code, use the "code" tools.


  • Lifetime Qt Champion

    @duckrae Why do you use threads? There is no need for threads. And it is very important to know that ONLY UI thread (main thread where the event loop is running) is allowed to change UI!



  • @jsulm oh i thought i need thread for tcp/ip . It will run with raspberry pi like TCP/IP Server. So if i run like tcp/ip server, i thought it have to listening using thread for tcp/ip client. and second answer, ui change only main thread means like android, right?


  • Lifetime Qt Champion

    @duckrae Qt is assynchronous, so usually no need for threads.



  • @jsulm If i have to use this code, what would i change ?


  • Lifetime Qt Champion

    @duckrae First remove all that thread stuff