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

QLabel can't display it's text real-time after it is setText successfully



  • #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include <QPushButton>
    #include <QLabel>
    #include <QVBoxLayout>
    #include <stdio.h>
    #include <stdlib.h>
    
    /* ubuntu 18.04 */
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <errno.h>
    #include <unistd.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    /* ubuntu 18.04 */
    
    class Widget: public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget* parent = 0) : QWidget(parent)
        {
            m_label = new QLabel;
            m_label->setStyleSheet("border-width: 1px;"
                                   "border-style: dashed;"
                                   "border-color: black;");
            m_btn = new QPushButton("Start");
            connect(m_btn, SIGNAL(clicked()), this, SLOT(connectToServer()));
            QVBoxLayout* layout = new QVBoxLayout(this);
            layout->addWidget(m_btn);
            layout->addWidget(m_label);
    
            this->resize(500, 200);
        }
    
    private slots:
        void connectToServer()
        {
            m_label->setText("this is the first information\n");
    
            memset(&m_client_addr, 0, sizeof(m_client_addr));
            m_client_addr.sin_family      = AF_INET;
            m_client_addr.sin_port        = htons(5000);
            m_client_addr.sin_addr.s_addr = inet_addr("192.168.70.8");
    
            if ((m_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
            {
                m_label->setText(m_label->text() + QString("socket failed\n"));
                return;
            }
    
            // assume the ip "192.168.70.8" is not existed, so connect function below will block
            if (::connect(m_fd, (sockaddr*)&m_client_addr, sizeof(m_client_addr)) < 0)
            {
                m_label->setText(m_label->text() + QString("connect failed\n"));
                return;
            }
    
            m_label->setText(m_label->text() + QString("connect to server successfully\n"));
        }
    
    private:
        sockaddr_in  m_client_addr;
        int          m_fd;
        QLabel*      m_label;
        QPushButton* m_btn;
    };
    
    #endif // WIDGET_H
    
    

    When I click the pushbutton, the m_label should display this is the first information immediately, but it don't.

    m_label will not display this is the first information until the connect return it's value.

    Why?

    Mark : I use the socket in ubuntu 18.04.



  • @Limer
    I presume after setText() Qt needs the event loop to spin to re-paint the label. Your code goes straight into the ::connect() without doing so. If you want to do it this way (using all the C socket stuff), try a http://doc.qt.io/qt-5/qcoreapplication.html#processEvents immediately after setting the text and see if that updates?



  • @JonB You are right, it success. Thanks .



  • @Limer
    Before you go any farther with your code:

    You are using the C level socket calls. Given that you are writing a Qt app, you should consider whether you wouldn't be better using Qt's own http://doc.qt.io/qt-5/qtcpsocket.html for all this instead. Among other things, it will work in a more event-driven fashion (signals/slots) than the C calls, which will fit in more naturally with Qt's way of doing things, e.g. you wouldn't have to spin that event loop for refreshes, as you'd write it differently.



  • @JonB Thanks for your wram reminding. The server is made by my colleague, so I have to do it with the c socket.



  • @Limer
    No, you don't. Regardless of how the server is written (C, C++, socket, whatever), it's a server with TCP sockets. You are writing a client to connect to that server. In your client you use whatever is most suitable for that. In this case, being a Qt application, your client would be much better off using the Qt classes & methods. http://doc.qt.io/qt-5/qabstractsocket.html lists all the methods inherited by QTcpSocket, e.g. http://doc.qt.io/qt-5/qabstractsocket.html#connectToHost-1 would replace your C ::connect().


Log in to reply