当前位置: 首页 > news >正文

QT--TCP网络通讯工具编写记录

QT–TCP网络通讯工具编写记录


文章目录

  • QT--TCP网络通讯工具编写记录
  • 前言
  • 演示如下:
  • 一、服务端项目文件:
    • 【1.1】server_tcp.h 服务端声明文件
    • 【1.2】thread_1.h 线程处理声明文件
    • 【1.3】main.cpp 执行源文件
    • 【1.4】server_tcp.cpp 服务端逻辑实现源文件
    • 【1.5】thread_1.cpp 线程逻辑控制实现源文件
    • 【1.6】server_tcp.ui 服务端UI设计文件
    • 【1.7】img.qrc 窗口图标文件
  • 二、客户端项目文件:
    • 【2.1】client_tcp.h 客户端声明文件
    • 【2.2】client_tcp.cpp 客户端逻辑控制源文件
    • 【2.2】main.cpp 执行源文件
    • 【2.3】client_tcp.ui 客户端UI设计文件
  • 三、设置项目构建的位置:
  • 四、QT项目不能用于其他电脑的原因:
  • 五、编译程序,使exe执行文件可正常使用:
    • 【5.1】 打开该文件
    • 【5.2】 进入项目构建的文件目录内,输入指令:windeployqt.exe **connect_tcp.exe【这是你自己已构建的exe执行程序】**


前言

功能描述:
1、实现服务端创建;
2、实现客户端创建 ;
3、实现服务端与客户端的通讯连接,包括:连接响应,断连响应等;
4、实现服务端一对多客户端,单发送消息,多发消息,循环发消息;
5、实现一键获取本地IP4地址;


演示如下:

在这里插入图片描述


一、服务端项目文件:

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。


【1.1】server_tcp.h 服务端声明文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include <QDateTime>
#include <QListWidgetItem>
#include <thread_1.h>
#include <QtNetwork/QNetworkInterface>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:Ui::MainWindow *ui;//server用于监听端口,获取新的tcp连接的描述符QTcpServer *tcpServer;QTcpSocket *socket;//TCP通讯的SocketQList<QTcpSocket*> listClient; //创建一个容器QString currentDateTimeString;//声明一个字符串变量QByteArray buffer;int socket_ret =0;int all_select_ret = 0;private:void startServer(QString &,int port);MyThread *thread = new MyThread;private slots:void initNetwork();void onNewConnection();void disconnectinfo();void onSocketReadyRead();void getcurrenttime();void delataitem();void all_slect();void send_write(QString &);void start_send();private slots:void on_pushButton_clicked();void on_pushButton_3_clicked();void on_pushButton_4_clicked();void on_pushButton_2_clicked();void on_listWidget_customContextMenuRequested(const QPoint &pos);void on_pushButton_clear1_clicked();void on_pushButton_fa2_clicked();void on_pushButton_fa1_clicked();void on_pushButton_stop_clicked();void on_pushButton_getip_clicked();void on_pushButton_ontop_clicked();};#endif // MAINWINDOW_H

【1.2】thread_1.h 线程处理声明文件

#ifndef MYTHREAD_H
#define MYTHREAD_H#include <QThread>
#include "QDebug"class MyThread : public QThread
{Q_OBJECTpublic:explicit MyThread(QObject *parent = 0);void stop();void sleeptimeset(int);protected:void run();private:volatile bool stopped;signals:void sendinfo(int);};#endif // MYTHREAD_H

【1.3】main.cpp 执行源文件

#include "server_tcp.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}

【1.4】server_tcp.cpp 服务端逻辑实现源文件

#include "server_tcp.h"
#include "ui_server_tcp.h"
#include "QDebug"
#include <QHostAddress>
#include <QThread>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);this->setWindowTitle("服务端");//窗口打开位置设置this->move(568,250);this->setWindowIcon(QIcon(":/server.ico"));initNetwork();ui->pushButton_2->setDisabled(true);ui->pushButton_fa1->setDisabled(true); //禁用发送按钮ui->pushButton_fa2->setDisabled(true);ui->pushButton_stop->setDisabled(true);//设置所选项的背景颜色为深绿色ui->listWidget->setStyleSheet("QListWidget::item:selected{background-color: #009900}");//连接线程函数//连接信号和槽函数connect(thread,SIGNAL(sendinfo(int)), this, SLOT(start_send()));}//初始化网络
void MainWindow::initNetwork()
{tcpServer=new QTcpServer(this);connect(tcpServer,SIGNAL(newConnection()),this,SLOT(onNewConnection()));   //绑定槽函数,当有新的连接请求就会调用该函数}//连接按钮点击
void MainWindow::on_pushButton_clicked()
{//获取地址和端口QString addres = ui->lineEdit->text();QString port = ui->comboBox->currentText();int port_ = port.toInt();//服务端监听地址startServer(addres,port_);}//服务端启动
void MainWindow::startServer(QString &addres,int port)
{qDebug() << "=============";QString ret = ui->pushButton->text();if (ret == "监听"){if (!tcpServer->listen(QHostAddress(addres), port)){qDebug() << "Server could not start!";ui->textBrowser->append(QString("<font color=\"#FF0000\">Server could not start!</font> "));} else {qDebug() << "Server started!";ui->pushButton->setStyleSheet("background-color: green");ui->pushButton->setText("断连");}} else if(ret == "断连"){if(socket_ret == 1){for (int h = listClient.count(); h <= listClient.count(); h--){if (h==0){break;}int s= listClient.count();qDebug() << "断连控制:" << s << h;listClient.at(h-1)->disconnectFromHost();}}tcpServer->close();qDebug() << "Server close!";ui->pushButton->setStyleSheet("background-color: ");ui->pushButton->setText("监听");}
}//客户端连接
void MainWindow::onNewConnection(){ui->pushButton_2->setDisabled(false);ui->pushButton_fa1->setDisabled(false);ui->pushButton_fa2->setDisabled(false);qDebug() << "客户端连接...";socket_ret = 1;socket = tcpServer->nextPendingConnection(); //创建sockitlistClient.append(socket);                   //将生成的socket添加到容器里connect(socket, SIGNAL(disconnected()), this,SLOT(disconnectinfo()));   //绑定槽函数,当客户端连接断掉后,触发disconnected信号,请求就会调用该函数connect(socket,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));     //绑定槽函数,当接收到客户端的信息后,触发readyRead信号,请求就会调用该函数//发送信息至客户端socket->write("Hello from TCP Server!");//获取对方的IP和端口QString ip = socket->peerAddress().toString();int port = socket->peerPort(); //该函数返回一个16位整数,表示连接到的远程主机的端口号QString temp = QString("%1:%2").arg(ip).arg(port);getcurrenttime();//获取当期时间ui->textBrowser->append(QString("<font color=\"#0000FF\">%1: </font> ""<font color=\"#3D9140\">%2====成功连接</font>").arg(currentDateTimeString,temp));//添加连接至listwidgetui->listWidget->addItem(temp);}//客户端断连后,调用该函数
void MainWindow::disconnectinfo()
{qDebug() << listClient.count();//监听是那个客户端断连QTcpSocket* clientSocket = qobject_cast<QTcpSocket*>(sender());int port =0;QString address;//利用for循环循环列表中的每一个连接进来的客户端,判断是哪一个客户端发的数据for (int i = 0; i < listClient.count(); i++){socket = listClient.at(i);if (socket == clientSocket) {// 找到该客户端,进行处理address = socket->peerAddress().toString();;port = socket->peerPort();qDebug() << "Client " << address << ":" << port << " disconnected.";break; //结束循环}}QString temp = QString("%1:%2").arg(address).arg(port);//    qDebug() << temp;getcurrenttime();//获取当期时间ui->textBrowser->append(QString("<font color=\"#0000FF\">%1:</font> ""<font color=\"#FF0000\">%2:客户端断连成功!</font>").arg(currentDateTimeString,temp));qDebug() << "客户端断连!";for(int i=0; i<ui->listWidget->count(); i++){QListWidgetItem *item = ui->listWidget->item(i); // 获取第i行的项QString text = item->text(); // 获取第i行的文本// 处理获取到的数据if (text == temp){delete ui->listWidget->takeItem(i);//删除对应的客户端IPlistClient.removeAt(i);//与客户端断连socket->close();if (all_select_ret == 0){//不选择所有项,设置QT ListWidget中的所有项都未选中ui->listWidget->setCurrentItem(nullptr);}}}//判断是否还有客户端连接服务端int connect_count = listClient.count();if (connect_count == 0){ui->pushButton_fa1->setDisabled(true); //禁用发送按钮ui->pushButton_fa2->setDisabled(true);ui->pushButton_2->setDisabled(true);}
}//读取数据
void MainWindow::onSocketReadyRead()
{qDebug() << "读取数据:";//监听是那个客户端断连QTcpSocket* clientSocket = qobject_cast<QTcpSocket*>(sender());//利用for循环循环列表中的每一个连接进来的客户端,判断是哪一个客户端发的数据for (int i = 0; i < listClient.count(); i++){socket = listClient.at(i);if (socket == clientSocket){// 获取端口int ports = socket->peerPort();// 找到该客户端,进行处理QByteArray msg = socket->readAll();QString str = QString::fromUtf8(msg);  // 使用UTF-8编码getcurrenttime();//获取当期时间ui->textBrowser->append(QString("<font color=\"#0000FF\">%1 </font> ""服务端《======客户端%2: %3").arg(currentDateTimeString).arg(ports).arg(str));break; //结束循环}}}//发送按钮
void MainWindow::on_pushButton_2_clicked()
{QString info1;try {//获取发送数据QString shuju = ui->textEdit->toPlainText();//判断数据长度是否大于0if (shuju.length() > 0){//获取当前选中行int selectedRow = ui->listWidget->currentRow();if(selectedRow == -1){//没有选中任何项getcurrenttime();//获取当期时间ui->textBrowser->append(QString("<font color=\"#0000FF\">%1:</font> ""<font color=\"#FF0000\">没有选中任何客户端</font>").arg(currentDateTimeString));return;}else{//获取选中多少行QList<QListWidgetItem*> selectedItems = ui->listWidget->selectedItems();foreach(QListWidgetItem* item, selectedItems){// 获取当前项目QString info1 = item->text();//qDebug() << "获取选中项:" << info1;//判断当前项目的文本if (info1 != ""){//利用for循环循环列表中的每一个连接进来的客户端,判断是哪一个客户端发的数据for (int i = 0; i < listClient.count(); i++){socket = listClient.at(i);// 找到该客户端,进行处理QString address = socket->peerAddress().toString();;int port = socket->peerPort();QString ports = QString::number(port);QString temp = QString("%1:%2").arg(address).arg(port);if (temp == info1){//判断连接状态是否正常if (socket->state()== QAbstractSocket::ConnectedState){//给对方发送数据, 使用套接字是tcpSocket 服务端到客户端socket->write(shuju.toUtf8().data());//getcurrenttime();//获取当期时间ui->textBrowser->append(QString("<font color=\"#0000FF\">%1 服务端=====>>>客户端【%2】: </font> %3").arg(currentDateTimeString,ports,shuju));}}}} else{ui->textBrowser->append(QString("<font color=\"#FF0000\">未选择客户端!</font> "));return;}}}} else{ui->textBrowser->append(QString("<font color=\"#FF0000\">未填写发送数据!</font> "));}}catch(std::exception& e){// 捕获并处理异常qDebug() << "Exception caught: " << e.what();}}//发送数据的函数
void MainWindow::send_write(QString &shuju)
{QString shujus;//判断数据长度是否大于0if (shuju.length() > 0){int selectedRow = ui->listWidget->currentRow();if(selectedRow == -1){//没有选中任何项getcurrenttime();//获取当期时间ui->textBrowser->append(QString("<font color=\"#0000FF\">%1:</font> ""<font color=\"#FF0000\">没有选中任何客户端</font>").arg(currentDateTimeString));return;} else{//获取选中多少行QList<QListWidgetItem*> selectedItems = ui->listWidget->selectedItems();foreach(QListWidgetItem* item, selectedItems) {//获取当前项目QString shujus = item->text();//qDebug() << "获取选中项:" << shujus;//判断当前项目的文本if (shujus.length() > 0){//qDebug() << shujus;//利用for循环循环列表中的每一个连接进来的客户端,判断是哪一个客户端发的数据for (int i = 0; i < listClient.count(); i++){socket = listClient.at(i);// 找到该客户端,进行处理QString address = socket->peerAddress().toString();;int port = socket->peerPort();QString ports = QString::number(port);QString temp = QString("%1:%2").arg(address).arg(port);if (temp == shujus){//判断连接状态是否正常if (socket->state()== QAbstractSocket::ConnectedState){//给对方发送数据, 使用套接字是tcpSocket 服务端到客户端socket->write(shuju.toUtf8().data());//getcurrenttime();//获取当期时间ui->textBrowser->append(QString("<font color=\"#0000FF\">%1 服务端=====>>>客户端【%2】: </font> %3").arg(currentDateTimeString,ports,shuju));}}}} else{ui->textBrowser->append(QString("<font color=\"#FF0000\">未选择客户端!</font> "));return;}}}} else{ui->textBrowser->append(QString("<font color=\"#FF0000\">未填写发送数据!</font> "));}}//获取当前时间模块
void MainWindow::getcurrenttime()
{QDateTime currentDateTime = QDateTime::currentDateTime();currentDateTimeString = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
//    qDebug() << "当前时间:" << currentDateTimeString;
}MainWindow::~MainWindow()
{delete ui;
}//清空按钮1
void MainWindow::on_pushButton_4_clicked()
{ui->textEdit->clear();
}//清空按钮2
void MainWindow::on_pushButton_3_clicked()
{ui->textBrowser->clear();
}//listWidget中创建右键菜单
void MainWindow::on_listWidget_customContextMenuRequested(const QPoint &pos)
{QListWidgetItem* curItem = ui->listWidget->itemAt( pos );if( curItem == NULL )return;QMenu *popMenu = new QMenu( this );QAction *Menu1 = new QAction(tr("删除"), this);QAction *Menu2 = new QAction(tr("全选"), this);popMenu->addAction( Menu1 );popMenu->addAction( Menu2 );connect( Menu1, SIGNAL(triggered() ), this, SLOT( delataitem()));connect( Menu2, SIGNAL(triggered() ), this, SLOT( all_slect()));popMenu->exec( QCursor::pos() );
}//删除选择客户端
void MainWindow::delataitem()
{//获取当前项目QString ip_port = ui->listWidget->currentItem()->text();qDebug() << ip_port;//移除当前客户端连接//利用for循环循环列表中的每一个连接进来的客户端,判断是哪一个客户端发的数据for (int i = 0; i < listClient.count(); i++){socket = listClient.at(i);// 找到该客户端,进行处理QString address = socket->peerAddress().toString();;int port = socket->peerPort();QString temp = QString("%1:%2").arg(address).arg(port);if (temp == ip_port){qDebug() << "Client " << address << ":" << port << " disconnected.";//删除对应的客户端IPlistClient.removeAt(i);socket->close();delete ui->listWidget->takeItem(i);break; //结束循环}}
}//右键菜单选择所有项目
void MainWindow::all_slect()
{//选择所有项目qDebug() << "选择所有项目";//设置为多选模式ui->listWidget->setSelectionMode(QAbstractItemView::MultiSelection);ui->listWidget->selectAll();all_select_ret = 1;
}//清空按钮
void MainWindow::on_pushButton_clear1_clicked()
{ui->lineEdit_fasong1->clear();
}//循环发送信息按钮
void MainWindow::on_pushButton_fa2_clicked()
{thread->start();//启用禁止按钮ui->pushButton_stop->setDisabled(false);ui->pushButton_fa2->setDisabled(true);
}//循环函数
void MainWindow::start_send()
{qDebug() << "执行...";QString shujus;//获取数据QString shuju = ui->lineEdit_fasong2->text();if (shuju.length() > 0){int selectedRow = ui->listWidget->currentRow();if(selectedRow == -1){//没有选中任何项getcurrenttime();//获取当期时间ui->textBrowser->append(QString("<font color=\"#0000FF\">%1:</font> ""<font color=\"#FF0000\">未连接任何客户端</font>").arg(currentDateTimeString));on_pushButton_stop_clicked();return;}else{//获取选中多少行QList<QListWidgetItem*> selectedItems = ui->listWidget->selectedItems();foreach(QListWidgetItem* item, selectedItems){// 获取当前项目QString shujus = item->text();
//                qDebug() << "获取选中多少行" << shujus;//服务端发送数据到客户端//获取当前项目if (shujus.length() > 0){//利用for循环循环列表中的每一个连接进来的客户端,判断是哪一个客户端发的数据for (int i = 0; i < listClient.count(); i++){socket = listClient.at(i);// 找到该客户端,进行处理QString address = socket->peerAddress().toString();;int port = socket->peerPort();QString ports = QString::number(port);QString temp = QString("%1:%2").arg(address).arg(port);if (temp == shujus){//判断连接状态是否正常if (socket->state()== QAbstractSocket::ConnectedState){//给对方发送数据, 使用套接字是tcpSocket 服务端到客户端socket->write(shuju.toUtf8().data());//getcurrenttime();//获取当期时间ui->textBrowser->append(QString("<font color=\"#0000FF\">%1 服务端=====>>>客户端【%2】: </font> %3").arg(currentDateTimeString,ports,shuju));}}}} else{ui->textBrowser->append(QString("<font color=\"#FF0000\">未选择客户端!</font> "));on_pushButton_stop_clicked();return;}}}} else{ui->textBrowser->append(QString("<font color=\"#FF0000\">未填写发送数据!</font> "));on_pushButton_stop_clicked();}}//发送按钮2
void MainWindow::on_pushButton_fa1_clicked()
{//获取发送数据QString shuju = ui->lineEdit_fasong1->text();send_write(shuju);}//停止循环按钮
void MainWindow::on_pushButton_stop_clicked()
{thread->stop();ui->pushButton_fa2->setDisabled(false);ui->pushButton_stop->setDisabled(true);
}//获取本机IP4地址
void MainWindow::on_pushButton_getip_clicked()
{getcurrenttime();//获取当期时间// 获取IP4地址QList<QHostAddress> list = QNetworkInterface::allAddresses();foreach (QHostAddress address, list){if (address.protocol() == QAbstractSocket::IPv4Protocol && !address.isLoopback()){
//            qDebug() << "IP Address: " << address.toString();ui->textBrowser->append(QString("<font color=\"#0000FF\">%1 IP4 Address : </font> %2").arg(currentDateTimeString,address.toString()));}}}//窗口置顶
void MainWindow::on_pushButton_ontop_clicked()
{QString shuju = ui->pushButton_ontop->text();if(shuju == "窗口置顶"){this->setWindowFlags(Qt::WindowStaysOnTopHint);ui->pushButton_ontop->setText("取消置顶");this->show();}else if (shuju == "取消置顶"){// 获取窗口原有属性Qt::WindowFlags flags = windowFlags();// 修改窗口属性,去掉置顶属性flags &= ~Qt::WindowStaysOnTopHint;// 更新窗口属性this->setWindowFlags(flags);ui->pushButton_ontop->setText("窗口置顶");this->show();}}

【1.5】thread_1.cpp 线程逻辑控制实现源文件

#include "thread_1.h"int timeset = 1000;MyThread::MyThread(QObject *parent) :QThread(parent)
{stopped = false;}void MyThread::run()
{qDebug() << "线程启动成功======";stopped = false;int shuju = 1;while (!stopped) {QThread::msleep(timeset);  // 休眠1000毫秒,即1秒;emit sendinfo(shuju);}
}void MyThread::stop()
{stopped = true;
}void MyThread::sleeptimeset(int value=200)
{timeset = value;
}

【1.6】server_tcp.ui 服务端UI设计文件

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>MainWindow</class><widget class="QMainWindow" name="MainWindow"><property name="geometry"><rect><x>0</x><y>0</y><width>705</width><height>373</height></rect></property><property name="windowTitle"><string>MainWindow</string></property><widget class="QWidget" name="centralwidget"><layout class="QGridLayout" name="gridLayout"><item row="0" column="1"><widget class="QLineEdit" name="lineEdit"><property name="minimumSize"><size><width>0</width><height>25</height></size></property><property name="maximumSize"><size><width>115</width><height>16777215</height></size></property><property name="text"><string>192.168.1.200</string></property></widget></item><item row="5" column="3"><widget class="QGroupBox" name="groupBox_2"><property name="title"><string>接收</string></property><layout class="QGridLayout" name="gridLayout_3"><item row="2" column="0"><spacer name="horizontalSpacer_2"><property name="orientation"><enum>Qt::Horizontal</enum></property><property name="sizeHint" stdset="0"><size><width>40</width><height>20</height></size></property></spacer></item><item row="2" column="2"><widget class="QPushButton" name="pushButton_3"><property name="minimumSize"><size><width>0</width><height>25</height></size></property><property name="text"><string>清空</string></property></widget></item><item row="0" column="0" colspan="3"><widget class="QTextBrowser" name="textBrowser"/></item><item row="2" column="1"><widget class="QPushButton" name="pushButton_ontop"><property name="minimumSize"><size><width>0</width><height>25</height></size></property><property name="text"><string>窗口置顶</string></property><property name="checkable"><bool>false</bool></property></widget></item></layout></widget></item><item row="0" column="0"><widget class="QLabel" name="label"><property name="minimumSize"><size><width>100</width><height>25</height></size></property><property name="maximumSize"><size><width>100</width><height>16777215</height></size></property><property name="frameShape"><enum>QFrame::WinPanel</enum></property><property name="frameShadow"><enum>QFrame::Raised</enum></property><property name="text"><string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;地址:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string></property></widget></item><item row="1" column="1"><widget class="QComboBox" name="comboBox"><property name="minimumSize"><size><width>0</width><height>25</height></size></property><item><property name="text"><string>1314</string></property></item><item><property name="text"><string>2000</string></property></item></widget></item><item row="1" column="0"><widget class="QLabel" name="label_2"><property name="minimumSize"><size><width>0</width><height>25</height></size></property><property name="frameShape"><enum>QFrame::WinPanel</enum></property><property name="frameShadow"><enum>QFrame::Raised</enum></property><property name="text"><string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;端口:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string></property></widget></item><item row="2" column="1"><widget class="QPushButton" name="pushButton"><property name="minimumSize"><size><width>0</width><height>25</height></size></property><property name="text"><string>监听</string></property></widget></item><item row="0" column="3" rowspan="4"><widget class="QGroupBox" name="groupBox"><property name="title"><string>发送</string></property><layout class="QGridLayout" name="gridLayout_2"><item row="0" column="4"><widget class="QPushButton" name="pushButton_4"><property name="minimumSize"><size><width>0</width><height>25</height></size></property><property name="text"><string>清空</string></property></widget></item><item row="0" column="0" colspan="3"><widget class="QTextEdit" name="textEdit"><property name="minimumSize"><size><width>0</width><height>25</height></size></property><property name="maximumSize"><size><width>16777215</width><height>25</height></size></property></widget></item><item row="0" column="3"><widget class="QPushButton" name="pushButton_2"><property name="minimumSize"><size><width>0</width><height>25</height></size></property><property name="text"><string>发送</string></property></widget></item><item row="1" column="3"><widget class="QPushButton" name="pushButton_fa1"><property name="minimumSize"><size><width>0</width><height>25</height></size></property><property name="text"><string>发送</string></property></widget></item><item row="1" column="0" colspan="3"><widget class="QLineEdit" name="lineEdit_fasong1"><property name="minimumSize"><size><width>0</width><height>25</height></size></property><property name="maximumSize"><size><width>16777215</width><height>16777215</height></size></property></widget></item><item row="1" column="4"><widget class="QPushButton" name="pushButton_clear1"><property name="minimumSize"><size><width>0</width><height>25</height></size></property><property name="text"><string>清空</string></property></widget></item><item row="2" column="3"><widget class="QPushButton" name="pushButton_fa2"><property name="minimumSize"><size><width>0</width><height>25</height></size></property><property name="text"><string>循环发送</string></property></widget></item><item row="2" column="0" colspan="3"><widget class="QLineEdit" name="lineEdit_fasong2"><property name="minimumSize"><size><width>0</width><height>25</height></size></property></widget></item><item row="2" column="4"><widget class="QPushButton" name="pushButton_stop"><property name="minimumSize"><size><width>0</width><height>25</height></size></property><property name="text"><string>停止</string></property></widget></item></layout></widget></item><item row="3" column="0" rowspan="3" colspan="2"><widget class="QGroupBox" name="groupBox_3"><property name="title"><string>客户端连接</string></property><layout class="QGridLayout" name="gridLayout_4"><item row="0" column="0"><widget class="QListWidget" name="listWidget"><property name="contextMenuPolicy"><enum>Qt::CustomContextMenu</enum></property></widget></item></layout></widget></item><item row="2" column="0"><widget class="QPushButton" name="pushButton_getip"><property name="minimumSize"><size><width>0</width><height>25</height></size></property><property name="text"><string>获取本地IP</string></property></widget></item></layout></widget><widget class="QMenuBar" name="menubar"><property name="geometry"><rect><x>0</x><y>0</y><width>705</width><height>23</height></rect></property></widget><widget class="QStatusBar" name="statusbar"/></widget><resources/><connections/>
</ui>

【1.7】img.qrc 窗口图标文件


二、客户端项目文件:

在这里插入图片描述


【2.1】client_tcp.h 客户端声明文件

#ifndef CLIENT_TCP_H
#define CLIENT_TCP_H#include <QWidget>
#include <QTcpSocket>
#include <QDateTime>namespace Ui {
class client_tcp;
}class client_tcp : public QWidget
{Q_OBJECTpublic:explicit client_tcp(QWidget *parent = nullptr);~client_tcp();private slots:void on_pushButton_clicked();void onConnected();void onDisconnected();void readdate();void on_pushButton_2_clicked();void getcurrenttime();void on_pushButton_5_clicked();void on_pushButton_3_clicked();void on_pushButton_4_clicked();void on_pushButton_6_clicked();private:Ui::client_tcp *ci;QTcpSocket *tcpClient;QString currentDateTimeString;};#endif // CLIENT_TCP_H

【2.2】client_tcp.cpp 客户端逻辑控制源文件

#include "client_tcp.h"
#include "ui_client_tcp.h"
#include <QHostAddress>
#include "QDebug"client_tcp::client_tcp(QWidget *parent) :QWidget(parent),ci(new Ui::client_tcp)
{ci->setupUi(this);this->setWindowTitle("客户端");//窗口打开位置设置this->move(1268,250);//设置图标this->setWindowIcon(QIcon(":/client.ico"));//先禁用发送按钮ci->pushButton_2->setDisabled(true);ci->pushButton_3->setDisabled(true);ci->pushButton_4->setDisabled(true);
}client_tcp::~client_tcp()
{delete ci;
}//点击连接按钮
void client_tcp::on_pushButton_clicked()
{//获取地址和端口QString ip = ci->lineEdit->text();QString port = ci->comboBox->currentText();int port_ = port.toInt();QString ret_  = ci->pushButton->text();if (ret_ == "连接"){tcpClient =new QTcpSocket(this); //tcpClientconnect(tcpClient,SIGNAL(connected()),this,SLOT(onConnected()));        //当客户端与服务端建立连接关系后,触发该信号connect(tcpClient,SIGNAL(disconnected()),this,SLOT(onDisconnected()));  //当客户端与服务端断连后,触发该信号connect(tcpClient,SIGNAL(readyRead()),this,SLOT(readdate()));//客户端连接服务端tcpClient->connectToHost(QHostAddress(ip),port_);//判断客户端是否连接成功if (tcpClient->waitForConnected(100)) {qDebug() << "Connected to server!";//设置字体为绿色getcurrenttime();//获取时间模块ci->textBrowser->append(QString("<font color=\"#0000FF\">%1:</font>""<font color=\"#00FF00\">Connected to server Success!</font>").arg(currentDateTimeString));ci->pushButton->setText("断开"); //设置按钮文本ci->pushButton->setStyleSheet("background-color: green");//设置按钮背景颜色//启用发送按钮ci->pushButton_2->setDisabled(false);ci->pushButton_3->setDisabled(false);ci->pushButton_4->setDisabled(false);// tcpClient->write("客户端连接成功!"); //发送信息到服务端} else {// qDebug() << "Could not connect to server!";getcurrenttime();//获取时间模块//设置字体为红色ci->textBrowser->append(QString("<font color=\"#0000FF\">%1</font>""<font color=\"#FF0000\">:Could not connect to serve</font> ").arg(currentDateTimeString));}}else if(ret_ == "断开"){tcpClient->close();ci->pushButton->setText("连接");ci->pushButton->setStyleSheet("background-color: ");ci->pushButton_2->setDisabled(true);ci->pushButton_3->setDisabled(true);ci->pushButton_4->setDisabled(true);}}//连接触发该函数
void client_tcp::onConnected()
{qDebug() << "***客户端已连接到服务器***";
}//断连触发该函数
void client_tcp::onDisconnected()
{qDebug() << "***已断连***";tcpClient->close();ci->pushButton->setText("连接");ci->pushButton->setStyleSheet("background-color: ");}//读取服务端发送过来的数据
void client_tcp::readdate()
{QByteArray msg = tcpClient->readAll();QString str(msg);getcurrenttime();//获取时间模块ci->textBrowser->append(QString("<font color=\"#0000FF\"> %1 </font>""客户端《======服务端 %2").arg(currentDateTimeString,msg));}//获取当前时间模块
void client_tcp::getcurrenttime()
{QDateTime currentDateTime = QDateTime::currentDateTime();currentDateTimeString = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
//    qDebug() << "当前时间:" << currentDateTimeString;
}//清空按钮
void client_tcp::on_pushButton_5_clicked()
{ci->textBrowser->clear();
}//发送按钮1
void client_tcp::on_pushButton_2_clicked()
{//读取文本框内的数据QString shuju1 = ci->lineEdit_2->text();if (shuju1.length()> 0){//判断连接状态是否正常if (tcpClient->state()== QAbstractSocket::ConnectedState){//给对方发送数据, 使用套接字是tcpSocket 客户端到服务端tcpClient->write(shuju1.toUtf8().data());//getcurrenttime();//获取时间模块ci->textBrowser->append(QString("<font color=\"#0000FF\">%1 客户端=====>>>服务端: </font>""%2").arg(currentDateTimeString,shuju1));}}
}//发送按钮2
void client_tcp::on_pushButton_3_clicked()
{//读取文本框内的数据QString shuju1 = ci->lineEdit_3->text();if (shuju1.length()> 0){//判断连接状态是否正常if (tcpClient->state()== QAbstractSocket::ConnectedState){//给对方发送数据, 使用套接字是tcpSocket 客户端到服务端tcpClient->write(shuju1.toUtf8().data());//getcurrenttime();//获取时间模块ci->textBrowser->append(QString("<font color=\"#0000FF\">%1 客户端=====>>>服务端: </font>""%2").arg(currentDateTimeString,shuju1));}}
}//发送按钮3
void client_tcp::on_pushButton_4_clicked()
{//读取文本框内的数据QString shuju1 = ci->lineEdit_4->text();if (shuju1.length()> 0){//判断连接状态是否正常if (tcpClient->state()== QAbstractSocket::ConnectedState){//给对方发送数据, 使用套接字是tcpSocket 客户端到服务端tcpClient->write(shuju1.toUtf8().data());//getcurrenttime();//获取时间模块ci->textBrowser->append(QString("<font color=\"#0000FF\">%1 客户端=====>>>服务端: </font>""%2").arg(currentDateTimeString,shuju1));}}
}//窗口置顶
void client_tcp::on_pushButton_6_clicked()
{QString shuju = ci->pushButton_6->text();if(shuju == "窗口置顶"){this->setWindowFlags(Qt::WindowStaysOnTopHint);ci->pushButton_6->setText("取消置顶");this->show();}else if (shuju == "取消置顶"){// 获取窗口原有属性Qt::WindowFlags flags = windowFlags();// 修改窗口属性,去掉置顶属性flags &= ~Qt::WindowStaysOnTopHint;// 更新窗口属性this->setWindowFlags(flags);ci->pushButton_6->setText("窗口置顶");this->show();}
}

【2.2】main.cpp 执行源文件

#include "client_tcp.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);client_tcp w;w.show();return a.exec();
}

【2.3】client_tcp.ui 客户端UI设计文件

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>client_tcp</class><widget class="QWidget" name="client_tcp"><property name="geometry"><rect><x>0</x><y>0</y><width>602</width><height>432</height></rect></property><property name="windowTitle"><string>Form</string></property><layout class="QGridLayout" name="gridLayout"><item row="0" column="1"><widget class="QLineEdit" name="lineEdit"><property name="minimumSize"><size><width>0</width><height>28</height></size></property><property name="maximumSize"><size><width>300</width><height>16777215</height></size></property><property name="text"><string>192.168.1.200</string></property></widget></item><item row="1" column="0" colspan="2"><widget class="QGroupBox" name="groupBox"><property name="maximumSize"><size><width>400</width><height>16777215</height></size></property><property name="title"><string>发送</string></property><layout class="QGridLayout" name="gridLayout_2"><item row="1" column="1"><widget class="QPushButton" name="pushButton_3"><property name="minimumSize"><size><width>0</width><height>28</height></size></property><property name="text"><string>发送2</string></property></widget></item><item row="2" column="1"><widget class="QPushButton" name="pushButton_4"><property name="minimumSize"><size><width>0</width><height>28</height></size></property><property name="text"><string>发送3</string></property></widget></item><item row="2" column="0"><widget class="QLineEdit" name="lineEdit_4"><property name="minimumSize"><size><width>0</width><height>28</height></size></property></widget></item><item row="0" column="1"><widget class="QPushButton" name="pushButton_2"><property name="minimumSize"><size><width>0</width><height>28</height></size></property><property name="text"><string>发送1</string></property></widget></item><item row="0" column="0"><widget class="QLineEdit" name="lineEdit_2"><property name="minimumSize"><size><width>0</width><height>28</height></size></property></widget></item><item row="1" column="0"><widget class="QLineEdit" name="lineEdit_3"><property name="minimumSize"><size><width>0</width><height>28</height></size></property></widget></item><item row="3" column="0"><spacer name="verticalSpacer"><property name="orientation"><enum>Qt::Vertical</enum></property><property name="sizeHint" stdset="0"><size><width>20</width><height>40</height></size></property></spacer></item></layout></widget></item><item row="0" column="2"><widget class="QLabel" name="label_2"><property name="minimumSize"><size><width>0</width><height>28</height></size></property><property name="maximumSize"><size><width>60</width><height>16777215</height></size></property><property name="frameShape"><enum>QFrame::WinPanel</enum></property><property name="frameShadow"><enum>QFrame::Raised</enum></property><property name="text"><string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;端口:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string></property></widget></item><item row="1" column="2" colspan="3"><widget class="QGroupBox" name="groupBox_2"><property name="title"><string>接收</string></property><layout class="QGridLayout" name="gridLayout_3"><item row="1" column="0"><spacer name="horizontalSpacer"><property name="orientation"><enum>Qt::Horizontal</enum></property><property name="sizeHint" stdset="0"><size><width>40</width><height>20</height></size></property></spacer></item><item row="1" column="2"><widget class="QPushButton" name="pushButton_5"><property name="minimumSize"><size><width>0</width><height>28</height></size></property><property name="text"><string>清空</string></property></widget></item><item row="0" column="0" colspan="3"><widget class="QTextBrowser" name="textBrowser"/></item><item row="1" column="1"><widget class="QPushButton" name="pushButton_6"><property name="minimumSize"><size><width>0</width><height>25</height></size></property><property name="text"><string>窗口置顶</string></property></widget></item></layout></widget></item><item row="0" column="4"><widget class="QPushButton" name="pushButton"><property name="minimumSize"><size><width>0</width><height>28</height></size></property><property name="text"><string>连接</string></property></widget></item><item row="0" column="0"><widget class="QLabel" name="label"><property name="minimumSize"><size><width>0</width><height>28</height></size></property><property name="maximumSize"><size><width>100</width><height>16777215</height></size></property><property name="frameShape"><enum>QFrame::WinPanel</enum></property><property name="frameShadow"><enum>QFrame::Raised</enum></property><property name="text"><string>地址:</string></property></widget></item><item row="0" column="3"><widget class="QComboBox" name="comboBox"><property name="minimumSize"><size><width>0</width><height>28</height></size></property><item><property name="text"><string>1314</string></property></item><item><property name="text"><string>2000</string></property></item></widget></item></layout></widget><resources/><connections/>
</ui>

三、设置项目构建的位置:

在这里插入图片描述
在这里插入图片描述

四、QT项目不能用于其他电脑的原因:

删除该用户记录文件,其他电脑上的QT都可打开同一个项目;
在这里插入图片描述

五、编译程序,使exe执行文件可正常使用:

【5.1】 打开该文件

在这里插入图片描述

【5.2】 进入项目构建的文件目录内,输入指令:windeployqt.exe connect_tcp.exe【这是你自己已构建的exe执行程序】

如下图所示:直接运行exe程序,会报错,缺少需要的文件。
在这里插入图片描述

输入指令后,会自动生成exe执行所需要的文件
在这里插入图片描述

再次点击exe执行文件,软件正常打开使用

在这里插入图片描述

相关文章:

QT--TCP网络通讯工具编写记录

QT–TCP网络通讯工具编写记录 文章目录 QT--TCP网络通讯工具编写记录前言演示如下&#xff1a;一、服务端项目文件&#xff1a;【1.1】server_tcp.h 服务端声明文件【1.2】thread_1.h 线程处理声明文件【1.3】main.cpp 执行源文件【1.4】server_tcp.cpp 服务端逻辑实现源文件【…...

如何解决爬虫的IP地址受限问题?

使用代理IP池、采用动态IP更换策略、设置合理的爬取时间间隔和模拟正常用户行为&#xff0c;是解决爬虫IP地址受限问题的主要策略。代理IP池是通过集合多个代理IP来分配爬虫任务&#xff0c;从而避免相同的IP地址对目标网站进行高频次访问&#xff0c;减少被目标网站封禁的风险…...

harmony 文件上传

图片上传 1&#xff0c; 获取文件&#xff0c;这里指的是图片 在鸿蒙内部有一个API pick选择器&#xff0c;实现文件保存和文件选择的功能&#xff0c; 使用pick对象创建PhotoViewPicker实例 传入必要的参数&#xff0c;如选择图片的数量&#xff0c;和弹出窗口的位置&#xf…...

什么是安全左移如何实现安全左移

文章目录 一、传统软件开发面临的安全挑战二、什么是安全左移四、安全左移与安全开发生命周期&#xff08;SDL&#xff09;三、安全左移对开发的挑战五、从DevOps到DevSecOps六、SDL与DevSecOps 一、传统软件开发面临的安全挑战 传统软件开发面临的安全挑战主要包括以下几个方…...

将PCD点云投影到BEV平面得到图片

前言 点云数据作为一种丰富的三维空间信息表达方式&#xff0c;通常用于自动驾驶、机器人导航和三维建模等领域。然而&#xff0c;点云数据的直观性不如二维图像&#xff0c;这限制了它在一些需要快速视觉反馈的应用场景中的使用。本文将探讨如何将点云数据转换为二维图像&…...

计算机笔记14(续20个)

230.色彩的种类就是色相 饱和度就是彩度除以明度 231.RISC是精简指令集&#xff0c;CISC是复杂指令集 232.世界上第一台数字计算机&#xff0c;奠定了至今仍在使用计算机体系结构 233.数据传输中&#xff0c;电路交换的传输延迟最小 234.定点整数的小数点约定在最低…...

docker 使用桥接网

在Docker中使用桥接网络&#xff0c;你可以创建一个新的桥接网络或者使用默认的桥接网络&#xff08;如果已经存在的话&#xff09;。以下是创建新桥接网络和连接容器到这个网络的示例命令&#xff1a; 1.创建一个新的桥接网络&#xff08;如果你想创建一个新的&#xff09;&a…...

1金融风控相关业务介绍

金融风控相关业务介绍 学习目标 知道常见信贷风险知道机器学习风控模型的优势知道信贷领域常用术语含义1 信贷&风控介绍 信贷业务,就是贷款业务,是商业银行和互联网金融公司最重要的资产业务和主要赢利手段 通过放款收回本金和利息,扣除成本后获得利润。贷款平台预测有…...

521源码-免费教程-经常用到的Vue.js的Vue@Cli入门指导

更多网站源码学习教程&#xff0c;请点击&#x1f449;-521源码-&#x1f448;获取最新资源&#xff1a;521源码-网站源码-资源素材-免费下载 Vue.js是一款流行的JavaScript框架&#xff0c;它使得构建交互式的Web界面变得简单和快捷。VueCli是Vue.js官方提供的脚手架工具&…...

大数据技术原理(二):搭建hadoop伪分布式集群这一篇就够了

&#xff08;实验一 搭建hadoop伪分布式&#xff09; -------------------------------------------------------------------------------------------------------------------------------- 一、实验目的 1.理解Hadoop伪分布式的安装过程 实验内容涉及Hadoop平台的搭建和…...

中间件是什么?信创中间件有哪些牌子?哪家好用?

当今社会&#xff0c;中间件的重要性日益凸显&#xff0c;尤其是在信创背景下&#xff0c;选择适合的中间件产品对于推动企业数字化转型和升级具有重要意义。今天我们就来聊聊中间件是什么&#xff1f;信创中间件有哪些牌子&#xff1f;哪家好用&#xff1f;仅供参考哈&#xf…...

python实现520表白图案

今天是520哦&#xff0c;作为程序员有必要通过自己的专业知识来向你的爱人表达下你的爱意。那么python中怎么实现绘制520表白图案呢&#xff1f;这里给出方法&#xff1a; 1、使用图形库&#xff08;如turtle&#xff09; 使用turtle模块&#xff0c;你可以绘制各种形状和图案…...

【Linux】-Flink分布式内存计算集群部署[21]

注意&#xff1a; 本节的操作&#xff0c;需要前置准备好Hadoop生态集群&#xff0c;请先部署好Hadoop环境 简介 Flink同spark一样&#xff0c;是一款分布式内存计算引擎&#xff0c;可以支撑海量数据的分布式计算 Flink在大数据体系同样是明星产品&#xff0c;作为新一代的…...

《python程序语言设计》2018版第5章第44题利用python循环进行十进制变十六进制,依然是44题的旧问题。倒着打出来的16进制

它似乎也有上一道题同样道问题。就是结果可能是倒着的。我还不能用超纲的办法。似乎上一个问题的难点又传到了下面 note: 我建立了一个method_a的变量干脆把整数除16的第一次放到循环外。 这样是不是可以解决呢&#xff1f; 我感觉还是在整除和除于的概念中&#xff0c;没有解脱…...

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(九)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 16 节&#xff09; P16《15.ArkUI-状态管理-任务统计案例》 1、实现任务进度卡片 怎么让进度条和进度展示文本堆叠展示&#xff1…...

海山数据库(He3DB)数据仓库发展历史与架构演进:(一)传统数仓

从1990年代Bill Inmon提出数据仓库概念后经过四十多的发展&#xff0c;经历了早期的PC时代、互联网时代、移动互联网时代再到当前的云计算时代&#xff0c;但是数据仓库的构建目标基本没有变化&#xff0c;都是为了支持企业或者用户的决策分析&#xff0c;包括运营报表、企业营…...

简单快捷的图片格式转换工具:认识webp2jpg-online

经常写博客或记笔记的朋友们可能会碰到图床不支持的图片格式或图片太大需要压缩的情况。通常&#xff0c;我们会在浏览器中搜索在线图片格式转换器&#xff0c;但这些转换器往往伴有烦人的广告或要求登录&#xff0c;并且支持的转换格式有限。最近&#xff0c;我在浏览 GitHub …...

iptablese防火墙【SNAT和DNAT】

目录 1.SNAT策略及应用 1.1SNAT原理与应用 1.2 SNAT策略的工作原理 1.3 实验操练 2.DNAT策略 2.1 DNAT策略的概述 2.2 DNAT原理与应用 2.3 实验操练 1.SNAT策略及应用 1.1SNAT原理与应用 SNAT 应用环境&#xff1a;局域网主机共享单个公网IP地址接入Internet&#xf…...

IT行业现状与未来趋势

随着技术的不断进步&#xff0c;IT行业已成为推动全球经济和社会发展的关键力量。从云计算、大数据、人工智能到物联网、5G通信和区块链&#xff0c;这些技术正在重塑我们的生活和工作方式。你眼中IT行业的现状及未来发展趋势是怎么样的&#xff1f;无论您是行业领袖、技术专家…...

Snowy2.x 版本使用 Yaml

代码&#xff1a;https://gitee.com/xiaonuobase/snowy/tree/Snowy2.5.2/ 直接将 properties 转换成 yaml 那么你大概率会遇到下面报错&#xff1a; 然后你上网搜索&#xff0c;发现是 snakeyaml 版本的问题&#xff0c;1.x 版本的 snakeyaml 有安全隐患&#xff0c;要升级到…...

鸿蒙 DevEcoStudio:通知栏通知实现

【使用notificationManager实现通知栏功能】 【普通通知、长文本通知、多行通知、图片通知】 import notificationManager from ohos.notificationManager import image from ohos.multimedia.image Entry Component struct Index {State message: string Hello World// 将图…...

什么是网关鉴权及其在Spring Cloud Gateway中的实现

在现代微服务架构中&#xff0c;网关扮演着非常重要的角色&#xff0c;它是系统和外部世界之间的入口&#xff0c;负责路由请求、流量控制以及安全保护等任务。其中&#xff0c;网关鉴权是保障系统安全的重要环节之一。本文将深入介绍什么是网关鉴权&#xff0c;以及如何通过过…...

【机器学习与实现】支持向量机SVM

目录 一、SVM (Support Vector Machine) 概述&#xff08;一&#xff09;支持向量机SVM的主要特点&#xff08;二&#xff09;支持向量与间隔最大化&#xff08;三&#xff09;线性可分/不可分&#xff08;四&#xff09;软间隔 (soft margin) 与核技巧 (kernel trick)&#xf…...

当代人工智能三教父——深度学习三巨头

文章目录 引言 人物介绍 突出贡献 专业名词解释 引言 今天下午闲来无事翻阅了一下csdn首页的头条文章——《27 岁天才创始人 Joel Hellermark 分享了自己和“AI 教父” Geoffery Hinton 的最新采访》 感觉挺有意思&#xff0c;就从头到尾的看了一遍&#xff0c;里面有很多…...

Django项目从创建到开发以及数据库连接的主要步骤,精简实用

1、项目创建 安装命令&#xff1a;pip install django3 -i <https://pypi.tuna.tsinghua.edu.cn/simple>上述命令是使用清华镜像&#xff0c;安装django3在项目的创建目录执行命令&#xff1a;django-admin startproject 项目名称&#xff08;英文&#xff09;就可以在指…...

linux 命令 grep 排除 No such file or directory

du -sh * 2>&1 | grep -v "proc" command 2>&1 | grep -v "No such file or directory" 这里的 2>&1 是将错误输出重定向到标准输出&#xff0c;然后 grep -v "No such file or directory" 会过滤掉包含 &qu…...

Unity 滑动条(Slider)拖拽开始和结束、点击等事件的拓展功能

目录 前言 一、关于slider的监听事件 二、方案一 &#xff08;无脚本版&#xff09; 三、方案二 &#xff08;继承slider脚本进行拓展&#xff09; 四、方案三&#xff08;外部脚本添加&#xff09; 前言 前一段时间在使用这个功能&#xff0c;发现搜索出来的文章和脚本&…...

Linux 学习知识 (简单易懂 )持续更新 Linux输出重定向 Linux通配符 Linux正则表达式 持续更新....

一.输出重定向 标准输出&#xff1a;是将信息输出在终端 标准错误输出&#xff1a;在执行命令的过程中所产生错误信息也是输出在终端标准输入&#xff1a;从键盘输入 1.1标准输出重定向 作用&#xff1a;将本来要显示在终端上的信息重定向到一个文件中 实现方法&#xff1a…...

前端vue用el-table如何实现表头内容过长换行处理,实现换行效果

前端vue用el-table如何实现表头内容过长换行处理&#xff0c;实现换行效果 这是效果图 有两种方法&#xff0c;一种简易版本&#xff0c;一种万能方法,都是el-table&#xff0c;先看文档 表头标题是可以自定义的 方法一 label的解释写在代码里面了&#xff0c;这里会自动形成换…...

15:00面试,15:08出来,面试问的有点变态。。。。

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天…...