本文主要是介绍QT实现TCP客户端自动连接,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《QT实现TCP客户端自动连接》这篇文章主要为大家详细介绍了QT中一个TCP客户端自动连接的测试模型,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下...
版本 1:没有取消按钮
测试效果

缺陷:
无法手动停止
测试代码
CMakeLists.txt
cmake_minimum_required(VERSION 3.19)
project(AutoConnect LANGUAGES CXX)
find_package(Qt6 6.5 REQUIRED COMPONENTS Core Widgets Network)
qt_standard_project_setup()
qt_add_executable(AutoConnect
WIN32 MACOSX_BUNDLE
main.cpp
widget.h
widget.ui
)
target_link_libraries(AutoConnect
PRIVATE
Qt::Core
Qt::Widgets
Qt6::Network
)
include(GNUInstallDirs)
install(TARGETS AutoConnect
BUNDLE DESTINATION .
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
qt_generate_deploy_app_script(
TARGET AutoConnect
OUTPUT_SCRIPT deploy_script
NO_UNSUPPORTED_PLATFORM_ERROR
)
install(SCRIPT ${deploy_script})
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QTcpSocket> #include <QProgressDialog> #include <QPushButton> #include <QLabel> #include <QHBoxLayout> #include <QvboxLayout> #include <QTextBrowser> #include <QMouseEvent> #include <QLineEdit> #include <QDebug> #include <QMetaObject> #include <QProgressBar> #include <QTimer> class MyTextBrowser:public QTextBrowser { public: MyTextBrowser(QWidget *parent = nullptr) :QTextBrowser(parent) { } // QWidget interface protected: virtual void mouseDoubleClickEvent(QMouseEvent *event) override{ if(event->button() == Qt::LeftButton){ this->clear(); } } }; class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr) : QWidget(parent) { QVBoxLayout *root = new QVBoxLayout(this); QHBoxLayout *iplayout = new QHBoxLayout; QPushButton *button_connect = new QPushButton("connect",this); button_connect->setObjectName("connect"); QLabel *ip_label = new QLabel("ip",this); QLabel *port_label = new QLabel("port",this); iplayout->addwidget(ip_label); iplayout->addWidget(ip_LineEdit); iplayout->addWidget(port_label); iplayout->addWidget(port_LineEdit); iplayout->addWidget(button_connect); iplayout->addStretch(); root->addLayout(iplayout); root->addWidget(console,1); //设置默认的测试网络参数 ip_LineEdit->setText("127.0.0.1"); port_LineEdit->setText("6600"); client->setObjectName("client"); QMetaObject::connectSlotsByName(this); } ~Widget() { } public slots: void auto_connect(){ if(client->state() == QAbstractSocket::ConnectedState){ client->disconnectFromHost(); client->waitForDisconnected(); } //client->waitForConnected(); std::shared_ptr<QProgressDialog> dialog(new QProgressDialog(this)); dialog->setLabelText(""); QProgressBar *bar = new QProgressBar(dialog.get()); bar->setTextVisible(false); dialog->setBar(bar); dialog->setLabelText("connecting ... "); dialog->setRange(0,0); dialog->setCancelButton(nullptr); dialog->setWindowFlag(Qt::FramelessWindowHint); QMetaObject::Connection conn_accept = connect(client, &QTcpSocket::connected, dialog.get(), &QProgressDialog::accept); QMetaObject::Connection conn_rejected = connect(client, &QTcpSocket::stateChanged, dialog.get(),[this,dialog](){ if(this->client->state() == QAbstractSocket::UnconnectedState){ dialog->reject(); } }); bool rtn = false; if(conn_accept&&conn_accept){ QHostAddress ip(ip_LineEdit->text()); int port = port_LineEdit->text().toInt(); show_msg(QString("connect %1:%2 ...").arg(ip.toString()).arg(port)); client->connectToHost(ip,port); rtn = dialog->exec(); qDebug() << "rtn = " << rtn; if(rtn == true){ show_msg(QString("connect %1:%2 success").arg(ip.toString()).arg(port)); }else{ show_msg(QString("connect %1:%2 fail").arg(ip.toString()).arg(port)); }python }else{ qDebug() << "error"; } if(conn_accept){ QObject::disconnect(conn_accept); } if(conn_rejected){ QObject::disconnect(conn_rejected); } if(!rtn){ QTimer::singleShot(10, this, &Widget::auto_connect); } } void on_connect_clicked(){ qDebug() << "clicked"; auto_connect(); } void on_client_connected(){ QTcpSocket *c = (QTcpSocket *)sender(); qDebug() << c->peerAddress() << "-" << c->peerName() << "-" << c->peerPort(); show_msg(QString("connect %1:%2 ok").arg(c->peerAddress().toString()).arg(c->peerPort())); } void on_client_disconnected(){ qDebug() << __func__<<__LINE__; show_msg(QString("disconnected")); QTimer::singleShot(10, this, &Widget::auto_connect); } void on_client_errorOccurred(QAbstractSocket::SocketError socketError){ qDebug() << __func__<<__LINE__ << "socketError:" << socketError; } void on_client_hostFound(){ qDebug() << __func__<<__LINE__; } // void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator) void on_client_stateChanged(QAbstractSocket::SocketState socketState){ qDebug() << __func__<<__LINE__<< "socketState:"<<socketState; } void show_msg(QString msg){ console->append(msg); } void on_client_aboutToClose(){ qDebug() << __func__<<__LINE__; } // void bytesWritten(qint64 bytes) // void channelBytesWritten(int channel, qint64 bytes) void on_client_channelReadyRead(int channel){ qDebug() << __func__<<__LINE__<< "channel:"<<channel; } void on_client_readChannelFinished(){ qDebug() << __func__<<__LINE__; } void on_client_readyRead(){ qDebug() << __func__<www.chinasem.cn<__LINE__; } public: QTcpSocket *client = new QTcpSocket(this); MyTextBrowser *console = new MyTextBrowser; QLineEdit *ip_LineEdit = new QLineEdit; QLineEdit *port_LineEdit = new QLineEdit; private: }; #endif // WIDGET_H
版本 2:有取消按钮
测试效果

点击canel按钮后,就不会自动重连了:

测试代码
CMakeLists.txt
cmake_minimum_required(VERSION 3.19)
project(AutoConnect LANGUAGES CXX)
find_package(Qt6 6.5 REQUIRED COMPONENTS Core Widgets Network)
qt_standard_project_setup()
qt_add_executable(AutoConnect
WIN32 MACOSX_BUNDLE
main.cpp
widget.h
widget.ui
)
target_link_libraries(AutoConnect
PRIVATE
Qt::Core
Qt::Widgets
Qt6::Network
)
include(GNUInstallDirs)
install(TARGETS AutoConnect
BUNDLE DESTINATION .
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
qt_generate_deploy_app_script(
TARGET AutoConnect
OUTPUT_SCRIPT deploy_script
NO_UNSUPPORTED_PLATFORM_ERROR
)
install(SCRIPT ${deploy_script})main.cpp
#include "widget.h"
#include <QApplication>
int MyPushButton::count = 0;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QApplication>
#include <QWidget>
#include <QTcpSocket>
#include <QProgressDialog>
#include <QPushButton>
#include <QLabel>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QTextBrowser>
#include <QMouseEvent>
#include <QLineEdit>
#include <QDebug>
#include <QMetaObject>
#include <QProgressBar>
#include <QTimer>
class MyTextBrowser:public QTextBrowser
{
public:
MyTextBrowser(QWidget *parent = nullptr)
:QTextBrowser(parent)
{
}
// QWidget interface
protected:
virtual void mouseDoubleClickEvent(QMouseEvent *event) override{
if(event->button() == Qt::LeftButton){
this->clear();
}
}
};
class www.chinasem.cnMyPushButton:public QPushButton{China编程
Q_OBJECT
public:
MyPushButton(QWidget *parent = nullptr):
MyPushButton("",parent)
{
}
MyPushButton(const QString &text, QWidget *parent = nullptr)
:QPushButton(text,parent)
{
MyPushButton::count++;
qDebug() << __func__ << __LINE__ << " create MyPushButton:count = " << count;
}
~MyPushButton(){
MyPushButton::count--;
qDebug() << __func__ << __LINE__ << " delete MyPushButton:count = " << count;
}
public:
static int count;
signals:
void user_click();
// QWidget interface
protected:
virtual void mousePressEvent(QMouseEvent *event) override{
if(event->button() == Qt::LeftButton){
qDebug() << __func__ << __LINE__ << "user click";
emit user_click();
}
}
};
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr)
: QWidget(parent)
{
QVBoxLayout *root = new QVBoxLayout(this);
QHBoxLayout *iplayout = new QHBoxLayout;
QPushButton *button_connect = new QPushButton("connect",this);
button_connect->setObjectName("connect");
QLabel *ip_label = new QLabel("ip",this);
QLabel *port_label = new QLabel("port",this);
iplayout->addWidget(ip_label);
iplayout->addWidget(ip_LineEdit);
iplayout->addWidget(port_label);
iplayout->addWidget(port_LineEdit);
//iplayout->addWidget(button_connect);
button_connect->setVisible(false);
iplayout->addStretch();
root->addLayout(iplayout);
root->addWidget(console,1);
//设置默认的测试网络参数
ip_LineEdit->setText("127.0.0.1");
port_LineEdit->setText("6600");
client->setObjectName("client");
QMetaObject::connectSlotsByName(this);
QTimer::singleShot(10, this, &Widget::auto_connect);
// std::shared_ptr<QProgressDialog> dialog(new QProgressDialog(this));
// dialog->setCancelButton(new MyPushButton("hello",this));
// qDebug() << "wait ...";
// dialog.reset();
// qDebug() << "byebye ...";
}
~Widget()
{
}
public slots:
void auto_connect(){
if(client->state() == QAbstractSocket::ConnectedState){
client->disconnectFromHost();
client->waitForDisconnected();
}
//client->waitForConnected();
std::shared_ptr<QProgressDialog> dialog(new QProgressDialog(this));
dialog->setLabelText("");
QProgressBar *bar = new QProgressBar(dialog.get());
bar->setTextVisible(false);
dialog->setBar(bar);
dialog->setLabelText("connecting ... ");
dialog->setRange(0,0);
MyPushButton *cancel_button = new MyPushButton("cancel",dialog.get());
dialog->setCancelButton(cancel_button);
dialog->setWindowFlag(Qt::FramelessWindowHint);
QMetaObject::Connection conn_accept
= connect(client,
&QTcpSocket::connected,
dialog.get(),
&QProgressDialog::accept);
QMetaObject::Connection conn_rejected
= connect(client,
&QTcpSocket::stateChanged,
dialog.get(),[this,dialog](){
if(this->client->state() ==
QAbstractSocket::UnconnectedState){
qDebug() << "connect error";
dialog->reject();
}
});
QMetaObject::Connection conn_cancel
= connect(cancel_button,
&MyPushButton::user_click,
dialog.get(),[this,dialjsog](){
qDebug() << "connect error";
dialog->reject();
this->m_user_cancel = true;
show_msg("user cancel reconnect");
});
bool rtn = false;
if(conn_accept&&conn_accept&&conn_cancel){
QHostAddress ip(ip_LineEdit->text());
int port = port_LineEdit->text().toInt();
show_msg(QString("connect %1:%2 ...").arg(ip.toString()).arg(port));
client->connectToHost(ip,port);
rtn = dialog->exec();
qDebug() << "rtn = " << rtn;
if(rtn == true){
show_msg(QString("connect %1:%2 success").arg(ip.toString()).arg(port));
}else{
show_msg(QString("connect %1:%2 fail").arg(ip.toString()).arg(port));
}
}else{
qDebug() << "error";
}
if(conn_accept){
QObject::disconnect(conn_accept);
}
if(conn_rejected){
QObject::disconnect(conn_rejected);
}
if(conn_rejected){
QObject::disconnect(conn_rejected);
}
if(conn_cancel){
QObject::disconnect(conn_cancel);
}
if(!rtn){
if(this->m_user_cancel == false){
QTimer::singleShot(10, this, &Widget::auto_connect);
}
}
}
void on_connect_clicked(){
qDebug() << "clicked";
auto_connect();
}
void on_client_connected(){
QTcpSocket *c = (QTcpSocket *)sender();
qDebug() << c->peerAddress() << "-" << c->peerName() << "-" << c->peerPort();
show_msg(QString("connect %1:%2 ok").arg(c->peerAddress().toString()).arg(c->peerPort()));
}
void on_client_disconnected(){
qDebug() << __func__<<__LINE__;
show_msg(QString("disconnected"));
QTimer::singleShot(10, this, &Widget::auto_connect);
}
void on_client_errorOccurred(QAbstractSocket::SocketError socketError){
qDebug() << __func__<<__LINE__ << "socketError:" << socketError;
}
void on_client_hostFound(){
qDebug() << __func__<<__LINE__;
}
// void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
void on_client_stateChanged(QAbstractSocket::SocketState socketState){
qDebug() << __func__<<__LINE__<< "socketState:"<<socketState;
}
void show_msg(QString msg){
console->append(msg);
}
void on_client_aboutToClose(){
qDebug() << __func__<<__LINE__;
}
// void bytesWritten(qint64 bytes)
// void channelBytesWritten(int channel, qint64 bytes)
void on_client_channelReadyRead(int channel){
qDebug() << __func__<<__LINE__<< "channel:"<<channel;
}
void on_client_readChannelFinished(){
qDebug() << __func__<<__LINE__;
}
void on_client_readyRead(){
qDebug() << __func__<<__LINE__;
}
public:
bool m_user_cancel = false;
QTcpSocket *client = new QTcpSocket(this);
MyTextBrowser *console = new MyTextBrowser;
QLineEdit *ip_LineEdit = new QLineEdit;
QLineEdit *port_LineEdit = new QLineEdit;
private:
};
#endif // WIDGET_H以上就是QT实现TCP客户端自动连接的详细内容,更多关于QT TCP客户端的资料请关注China编程(www.chinasem.cn)其它相关文章!
这篇关于QT实现TCP客户端自动连接的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!