Solved 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 displaythis is the first information
immediately, but it don't.m_label
will not displaythis is the first information
until theconnect
return it's value.Why?
Mark : I use the
socket
in ubuntu 18.04. -
@Limer
I presume aftersetText()
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 byQTcpSocket
, e.g. http://doc.qt.io/qt-5/qabstractsocket.html#connectToHost-1 would replace your C::connect()
.