版本 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));
}
}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__<<__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 MyPushButton:public QPushButton{
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,dialog](){
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