qt直播(Qt视频直播软件–项目实战「建议收藏」)

发布时间:2025-12-10 19:11:51 浏览次数:27

Qt视频直播软件–项目实战「建议收藏」-qt直播怎么没了

Qt视频直播软件–项目实战(Day4)「建议收藏」第四天项目日记1、今日总结今天开始写客户端1)先设计登录界面2)然后用线程开启socket3)用线程开的话可以实时获取登录的状态关于TCP我参考了这篇博文2、设计思路写的时候试过在连接的时候用信号来处理连接状态,但是发现在等待连接的过程中,ui的控件不会发生改变,说明ui的控件被阻塞了,所以tcp的连接用线程来写,这样就可以实现在界面中实时显示连接状态。3、代码说明widget.ui界面如图所示这里只用了一个界面,然后设计思路是:在登录之前,只显示上面的界面,登录成功之后,只显示

第四天项目日记

1、今日总结

今天开始写客户端
1)先设计登录界面
2)然后用线程开启socket
3)用线程开的话可以实时获取登录的状态
关于TCP我参考了这篇博文

2、设计思路

写的时候试过在连接的时候用信号来处理连接状态,但是发现在等待连接的过程中,ui的控件不会发生改变,说明ui的控件被阻塞了,所以tcp的连接用线程来写,这样就可以实现在界面中实时显示连接状态。

3、代码说明

widget.ui


界面如图所示
这里只用了一个界面,然后设计思路是:在登录之前,只显示上面的界面,登录成功之后,只显示下面的界面。
输入用户名密码点击登录,先判断服务器在不在线,如果在线的话就发送用户名密码,然后服务器对客户端发过来的用户名和密码进行判断,如果匹配了就会跳到下面的页面,如果没匹配就返回失败原因

注册的话也是先判断有没有连接上,如果连接上了,就发送注册信息给服务器,如果没连接上就显示连接不到服务器。

两个功能均未完全实现;

tcpthread.h (继承自QThread)

#ifndef TCPTHREAD_H#define TCPTHREAD_H#include <QObject>#include <QTcpSocket>#include <QThread>#include <QDebug>class TcpThread : public QThread{        Q_OBJECTpublic:    explicit TcpThread(QObject *parent = 0);    ~TcpThread();    void startThread(const QString& ip, int port);    void stopThread();signals:    void send_tcpmsg(QString);public:    int m_iSendData;    int m_iRecv_TimeOut;    int reconnect_num;private:    QTcpSocket* m_TcpSocket;    bool        m_isThreaStopped;    bool m_isOkConect;    QString m_QStrSocketIp;    int m_nSockPort;    QByteArray m_datagram;protected:    virtual void run();private slots:    void onConnect();    void onDisConnect();    void onReadMsg();    void onSendTcp(QString);public slots:};#endif // TCPTHREAD_H

是否还在为Ide开发工具频繁失效而烦恼,来吧关注以下公众号获取最新激活方式。亲测可用!

为防止网络爬虫,请关注公众号回复”口令”

激活idea 激活CLion DataGrip DataSpell dotCover dotMemory dotTrace GoLand PhpStorm PyCharm ReSharper ReShaC++ Rider RubyMine WebStorm 全家桶 刷新

【正版授权,激活自己账号】:Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】:官方授权 正版激活 自己使用,支持Jetbrains家族下所有IDE…

tcpthread.cpp

#include "tcpthread.h"TcpThread::TcpThread(QObject *parent) :QThread(parent){ m_TcpSocket = nullptr ;m_isThreaStopped = false;m_isOkConect = false;reconnect_num = 0;}TcpThread::~TcpThread(){ m_isThreaStopped = true;quit();wait();}void TcpThread::startThread(const QString &ip, int port){ m_QStrSocketIp = ip;m_nSockPort = port;m_isThreaStopped = false;start();}void TcpThread::stopThread(){ reconnect_num = 0;m_isThreaStopped = true;}void TcpThread::run(){ bool b_recv_flag = false;emit send_tcpmsg("connecting");if (!m_TcpSocket){ m_TcpSocket = new QTcpSocket(this);connect(m_TcpSocket, SIGNAL(readyRead()), this, SLOT(onReadMsg()),Qt::DirectConnection);//让接受函数在run子线程中执行(发送者执行)connect(m_TcpSocket, SIGNAL(connected()), this, SLOT(onConnect()));connect(m_TcpSocket, SIGNAL(disconnected()), this, SLOT(onDisConnect()));}while (!m_isThreaStopped){ //检测客户端 socket指针是否为空if(b_recv_flag)msleep(100);if (!m_isOkConect){ // 终止当前连接并重置套接字(立即关闭套接字,丢弃写缓冲区中的任何挂起数据)m_TcpSocket->abort();m_TcpSocket->connectToHost(m_QStrSocketIp, m_nSockPort);//等待连接。。。延时三秒,三秒内连不上返回falsem_isOkConect = m_TcpSocket->waitForConnected(3000);m_iRecv_TimeOut = -1;reconnect_num++;}if (!m_isOkConect){ msleep(1);if(reconnect_num <3){ QString reconnect = "reconnect_"+QString::number(reconnect_num);emit send_tcpmsg(reconnect);continue;}else{ emit send_tcpmsg("overtime");break;}}else{ qDebug()<<"tcp_flag:"<<m_iRecv_TimeOut;onSendTcp("");}b_recv_flag = m_TcpSocket->waitForReadyRead(100);if  (b_recv_flag){ m_iRecv_TimeOut = 0;}else{ m_iRecv_TimeOut++;if(m_iRecv_TimeOut>150) m_iRecv_TimeOut=150;}if(m_iRecv_TimeOut >= 150){ m_iRecv_TimeOut = -1;m_TcpSocket->disconnectFromHost();}}qDebug()<<"exit_5";m_TcpSocket->disconnectFromHost();qDebug()<<"exit_6";}void TcpThread::onConnect(){ reconnect_num = 0;emit send_tcpmsg("connect");}void TcpThread::onDisConnect(){ //socket一旦断开则自动进入这个槽函数//通过把 m_isOkConect 设为false,在socket线程的run函数中将会重新连接主机qDebug()<<"socket is disconnect!"<<endl;m_isOkConect = false;m_iRecv_TimeOut = -1;emit send_tcpmsg("disconnect");}void TcpThread::onReadMsg(){ if(m_TcpSocket->bytesAvailable() <= 0){ // 判定连接失败m_TcpSocket->disconnectFromHost();}while (m_TcpSocket->bytesAvailable() > 0){ // 接收数据m_datagram.clear();m_datagram.resize(m_TcpSocket->bytesAvailable());m_TcpSocket->read(m_datagram.data(), m_datagram.size());QString str_tcp_receive = QString::fromLocal8Bit(m_datagram);qDebug()<<str_tcp_receive;msleep(100);}}void TcpThread::onSendTcp(QString str_info){ if((!m_TcpSocket)||m_TcpSocket->state()!=QAbstractSocket::ConnectedState)return;m_iSendData = m_TcpSocket->write(str_info.toStdString().c_str(), strlen(str_info.toStdString().c_str()));m_TcpSocket->flush();if (m_iSendData < 0){ m_TcpSocket->disconnectFromHost();return;}msleep(1000);}

widget.h

#ifndef WIDGET_H#define WIDGET_H#include <QWidget>#include <QMessageBox>#include <QDebug>#include "tcpthread.h"#include "mymessage.h"namespace Ui { class Widget;}class Widget : public QWidget{ Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();void Logic_Init();//登录初始化void User_Init();//使用界面初始化void connectToServer(); //用连接服务器public slots:void connect_state(QString); //用来控制连接状态void connect_success(); //用来表示连接成功private slots:void on_radioshow_clicked(bool checked); //用来显示密码和隐藏密码void on_pushlogic_clicked();//用来登录void on_pushquit_clicked();//用来退出private:Ui::Widget *ui;TcpThread *tcpThread;//用来启动socket线程// bool status;QString userName; //账号QString passWard; //密码signals:void connect_enable(); //连接};#endif // WIDGET_H

widget.cpp

#include "widget.h"#include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget){ connect(this,SIGNAL(connect_enable()),this,SLOT(connect_success()));ui->setupUi(this);tcpThread = nullptr;// status = false;Logic_Init();}Widget::~Widget(){ delete ui;}void Widget::Logic_Init(){ this->setWindowTitle("登录/注册");ui->linepswd->show();ui->lineUser->show();ui->radioshow->show();ui->pushlogic->show();ui->pushregister->show();ui->linepswd->setEchoMode(QLineEdit::Password);ui->pushAdd->hide();ui->pushCreate->hide();ui->listView->hide();ui->pushquit->hide();}void Widget::User_Init(){ this->setWindowTitle("云木直播平台");ui->linepswd->hide();ui->lineUser->hide();ui->radioshow->hide();ui->pushlogic->hide();ui->pushregister->hide();ui->label->hide();ui->label_2->hide();ui->label_3->hide();ui->pushAdd->show();ui->pushCreate->show();ui->listView->show();ui->pushquit->show();}void Widget::connectToServer(){ QString Address_Ip = "127.0.0.1";int port = 8010;if(!tcpThread){ tcpThread = new TcpThread;QObject::connect(tcpThread,SIGNAL(send_tcpmsg(QString)),this,SLOT(connect_state(QString)));}tcpThread->startThread(Address_Ip,port);}void Widget::connect_state(QString message){ qDebug()<<message;if(message == "connecting") { ui->label_connect_state->setText("连接中...");}else if(message == "connect"){ ui->label_connect_state->clear();emit connect_enable();}else if(message == "disconnect"){ tcpThread->stopThread();}else if(message == "overtime"){ QMessageBox::warning(NULL,tr("无法连接"),tr("无法连接请稍后再试"));ui->label_connect_state->clear();tcpThread->stopThread();}else if(message.left(9) == "reconnect"){ QString text = "第"+message.right(1)+"次重连中";ui->label_connect_state->setText(text);}}void Widget::connect_success(){ QString msgbuf = userName+" "+ passWard;MyMessage mymsg(MSG_LOGIC,msgbuf,msgbuf.length());qDebug()<<mymsg.toString();tcpThread->send_tcpmsg(mymsg.toString());User_Init();}void Widget::on_radioshow_clicked(bool checked){ if(checked){ ui->linepswd->setEchoMode(QLineEdit::Normal);}else{ ui->linepswd->setEchoMode(QLineEdit::Password);}}void Widget::on_pushlogic_clicked(){ if(ui->lineUser->text().isEmpty()){ QMessageBox::warning(NULL,tr("输入错误"),tr("账号不能为空"));return;}if(ui->linepswd->text().isEmpty()){ QMessageBox::warning(NULL,tr("输入错误"),tr("密码不能为空"));return;}userName = ui->lineUser->text();passWard = ui->linepswd->text();//连接connectToServer();}void Widget::on_pushquit_clicked(){ tcpThread->stopThread();QMessageBox::about(NULL,tr("退出"),tr("点击退出"));this->close();}

mymessage.h

#ifndef MYMESSAGE_H#define MYMESSAGE_H#include <QString>enum MsgId{ MSG_CLITEN_CONNECT = 0, //连接消息MSG_READ_BYTES,   //读取接收到的消息MSG_CLIENT_CLOSE,   //客户端关闭的消息MSG_LOGIC,  //客户端登录消息};class MyMessage{ enum MsgId msgid;QString msgbuf;int length;public:MyMessage();MyMessage(MsgId msgid,QString msgbuf,int length);void setmsgid(MsgId msgid);void setmsgbuf(QString msgbuf);void setlength(int length);int getmsgid();QString getmsgbuf();int getlength();QString toString();};#endif // MYMESSAGE_H

mymessage.cpp

#include "mymessage.h"MyMessage::MyMessage(){ }MyMessage::MyMessage(MsgId msgid, QString msgbuf, int length){ this->msgid = msgid;this->msgbuf = msgbuf;this->length = length;}void MyMessage::setmsgid(MsgId msgid){ this->msgid = msgid;}void MyMessage::setmsgbuf(QString msgbuf){ this->msgbuf = msgbuf;}void MyMessage::setlength(int length){ this->length = length;}int MyMessage::getmsgid(){ return msgid;}QString MyMessage::getmsgbuf(){ return msgbuf;}int MyMessage::getlength(){ return length;}QString MyMessage::toString(){ QString send_msg = QString::number(msgid)+"|"+msgbuf;return send_msg;}

4、项目文件

源代码链接接.

5、效果展示

测试如下

1、先测试账号密码不输入的情况下,提示信息
然后测试密码显示和隐藏
2、测试不开启服务器的情况下登录超时的情况
连接次数三次,每次超时时间为3s,三次结束之后提示连接不到服务器
连接过程中有提示,点击确定之后情况提示

3、测试连接过程中开启服务器,自动连接成功(密码验证还没有写)
只测试界面跳转,跳转之后点击退出,客户端退出 退出之后服务器显示的在线列表自动会清掉

6、每日总结

今日学会使用 QThread里面创建 QTcpSocket
为了让连接过程中显示连接状态,真的是废了很大的功夫。。。
就这样慢慢成长吧。

另外,要考虑在消息传递的过程中使用 json 格式进行封装一下,所以可能要调研一下 QJson

坚持就是胜利!!!!!!

需要做网站?需要网络推广?欢迎咨询客户经理 13272073477