Qt视频直播软件--项目实战(Day6)

第六天项目日记

1、今日总结

完成客户端首页的所有功能
完成客户端加入直播和创建直播的界面设计
增加json打包函数和json解析函数
增加服务器的开播消息和关闭直播的消息

2、设计思路

对于创建直播来说,只需要相应的客户发送开播消息给服务器,然后服务器转发给其他客户端
关闭直播也是如此
另外,在客户端连接之后,要发送当前开播的房间给客户端

对于客户端界面,开播和观看直播的界面不同
开播界面如下(并非最终版本)

在这里插入图片描述
观看直播的画面如下
在这里插入图片描述
开播只需要之间点击开播即可,开播后发送相应的房间号给其他客户端
点击观看时,需要选择房间号进行观看进一步的内容还没有实现

3、代码说明

服务器

服务器都略有修改
在这里插入图片描述

新增json消息打包和解析
在这里插入图片描述
在这里插入图片描述
服务器要解析下面的json,打包上面的json

myjson.h
#ifndef MYJSON_H
#define MYJSON_H

#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonParseError>
#include <QDebug>
#include <QJsonArray>
#include <QByteArray>

class MyJson
{
public:
    MyJson();
    //解析用户名和密码
    QString name_pswd_info(QString message,QString &pswd,QString &name);
    //打包直播刷新消息
    QString  pack_live_flush(QString action,QStringList name_list);
};

#endif // MYJSON_H

myjson.cpp
#include "myjson.h"

MyJson::MyJson()
{

}

QString MyJson::name_pswd_info(QString message, QString &pswd, QString &name)
{
    QByteArray bytes = message.toUtf8();
    QJsonParseError jsonError;
    QJsonDocument doucment = QJsonDocument::fromJson(bytes, &jsonError);
    if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) {  // 解析未发生错误
        if (doucment.isObject()){
            QJsonObject object = doucment.object();  // 转化为对象
            if (object.contains("Name")) {
                QJsonValue value = object.value("Name");
                if (value.isString()) {
                    name = value.toString();
                    qDebug() << "Name : " << name;
                }
            }else{
                return "json_error_no_name";
            }
            if (object.contains("password")) {
                QJsonValue value = object.value("password");
                if (value.isString()) {
                    pswd = value.toString();
                    qDebug() << "pswd : " << pswd;
                }
            }else{
                return "json_error_no_pswd";
            }
        }else{
            return "json is no object";
        }
    }else{
        return "json error";
    }
    return "success";
}

QString MyJson::pack_live_flush(QString action, QStringList name_list)
{
    QJsonObject json;
    json.insert("action",action);
    QJsonArray json_array;
    for (int i = 0; i < name_list.size(); ++i){
        json_array.insert(i,name_list.at(i));
    }
    json.insert("name",json_array);
    QJsonDocument document;
    document.setObject(json);
    QByteArray byteArray = document.toJson(QJsonDocument::Compact);
    QString strJson(byteArray);
    return strJson;
}

tcpsocket.h

在这里插入图片描述

tcpsocket.cpp

精简了解析函数,新增了对接收到消息的处理

#include "tcpsocket.h"

TcpSocket::TcpSocket(QObject *parent):
    QTcpSocket(parent)
{
    mydb = dbhelper::getIntance(NULL);
    mylog = MyLog::getInstance(NULL);
    //本来想要在这里发送连接的信号给服务器的,结果发现在他状态改变的时候还读取不到端口号和ip地址,所以就放在房间socket的地方去发送消息了
    //    connect(this,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(dataconnected()));
    //连接断线函数/读取函数和自定义的槽函数
    connect(this,SIGNAL(disconnected()),this,SLOT(datadisconnected()));
    connect(this,SIGNAL(readyRead()),this,SLOT(dataReceived()));
}

QString TcpSocket::getName()
{
    return name;
}

int TcpSocket::getlive_state()
{
    return live_state;
}

void TcpSocket::setlive_state(int state)
{
    live_state = state;
}

void TcpSocket::msgPrase(QString msg_buf)
{
    int item;
    QString buf;
    buf.clear();
    item = msg_buf.section('|',0,0).trimmed().toInt();
    int item_len = QString::number(item).length();
    //    qDebug()<<"len"<<item_len;
    buf = msg_buf.right(msg_buf.length()-item_len-1);
    //    qDebug()<<"item"<<item<<" "<<buf;
    //把它转换成消息发送给server
    MyMessage message((MsgId)item,buf,buf.length());
    if(message.isInEnum()){
        if(message.getmsgid() == MSG_CLIENT_CLOSE || message.getmsgid() == MSG_CLITEN_CONNECT){
            emit messageToServer(message); //发射消息信号
        }else if(message.getmsgid() == MSG_LOGIC){
            QString ret = prase_MSG_LOGIC(message.getmsgbuf());
            message.setmsgbuf(ret);
            qDebug()<<message.toString();
            this->write(message.toString().toLatin1(),message.toString().length()+1);
            this->flush();
            if(ret == "success"){
                emit logicToServer(this->peerName()); //发射消息信号
                qDebug()<<" emit logicToServer(this->peerName())"<<this->peerName();
            }
        }else if(message.getmsgid() == MSG_REGISTER){
            message.setmsgbuf(prase_MSG_REG(message.getmsgbuf()));
            this->write(message.toString().toLatin1(),message.toString().length()+1);
            this->flush();
        }else if(message.getmsgid() == MSG_SHAKE_HAND){//握手信号
            message.setmsgbuf(" ");
            this->write(message.toString().toLatin1(),message.toString().length()+1);
            this->flush();
        }else if(message.getmsgid() == MSG_CREATE_LIVE){//创建直播
            live_state = 1;
            emit messageToServer(message);
        }else if(message.getmsgid() == MSG_CLOSE_LIVE){//关闭直播
            live_state = 0;
            emit messageToServer(message);
        }
    }else{
        qDebug()<<"无效数据";
    }
}

QString TcpSocket::prase_MSG_LOGIC(QString message_buf)
{
    QString name;
    QString pswd;
    QString parse_ret;
    parse_ret = myjson.name_pswd_info(message_buf,pswd,name);
    if(parse_ret != "success"){
        return parse_ret;
    }
    QString ret = mydb->logic_judge(name,pswd);
    if(ret == "success") {
        this->setPeerName(name);
        MyMessage message(MSG_CLITEN_CONNECT,name,name.length());
        QString connectbuf = this->peerName() +" "+this->peerAddress().toString()+" "+QString::number(this->peerPort()) + " connected!!";
        mylog->LogWrite(connectbuf);
        emit messageToServer(message);
    }
    return ret;
}

QString TcpSocket::prase_MSG_REG(QString message_buf)
{
    QString name;
    QString pswd;
    QString parse_ret;
    parse_ret = myjson.name_pswd_info(message_buf,pswd,name);
    if(parse_ret != "success"){
        return parse_ret;
    }
    QString ret;
    ret = mydb->user_reg(name,pswd);
    return ret;
}

void TcpSocket::datadisconnected()
{
    //断开之后会发送-1
    qDebug()<<"emit disconnected("<<this->peerName()<<")";
    emit disconnected(this->peerName());
}

void TcpSocket::dataReceived()
{
    //处理督导的信号
    while(this->bytesAvailable() > 0){
        char buf[1024] = {'\0'};
        int length = bytesAvailable();
        this->read(buf,length);         //读取接收
        msgPrase(buf); //解析收到的数据
    }
}


tcpserver.h
#ifndef TCPSERVER_H
#define TCPSERVER_H

#include <QObject>
#include <QtNetwork>
#include <QTcpServer>
#include "tcpsocket.h"
#include "mylog.h"
#include "myjson.h"

class TcpServer : public QTcpServer
{
    Q_OBJECT
public:
    explicit TcpServer(QObject* parent = 0,int port = 0);
    QList<TcpSocket*> tcpSocketList;//用来存储客户端指针的list容器
    MyLog *mylog;
    MyJson myjson;

protected:
    void incomingConnection(int socketDescriptor);//重写了连接函数

signals:
    void msgToServer(MyMessage);//用来给main发送消息的信号

public slots:
    void msgFromSocket(MyMessage);//用来处理从socket接收到信号的槽函数
    void tcpDisconnected(QString);//用来处理客户端断开的槽函数
    void tcpLogicSuccess(QString);//用来处理登录成功的信号
};

#endif // TCPSERVER_H

tcpserver.cpp
#include "tcpserver.h"

TcpServer::TcpServer(QObject *parent, int port):
    QTcpServer(parent)
{
    mylog = MyLog::getInstance(NULL);
    listen(QHostAddress::AnyIPv4,port); //用来监听ipv4的客户端,port是传进来的
}

void TcpServer::incomingConnection(int socketDescriptor)
{
    TcpSocket *tcpSocket = new TcpSocket(this);
    tcpSocket->setSocketDescriptor(socketDescriptor);
    connect(tcpSocket, SIGNAL(messageToServer(MyMessage)),
            this, SLOT(msgFromSocket(MyMessage)));
    connect(tcpSocket,SIGNAL(logicToServer(QString)),
            this,SLOT(tcpLogicSuccess(QString)));
    connect(tcpSocket, SIGNAL(disconnected(QString)),
            this, SLOT(tcpDisconnected(QString)));
    //把socket指针放到socketlist中
    tcpSocketList.append(tcpSocket);
}

void TcpServer::msgFromSocket(MyMessage message)
{
    qDebug()<<message.getmsgbuf();
    // (||message.getmsgid() == MSG_CLITEN_CONNECT)
    if(message.getmsgid() == MSG_CLIENT_CLOSE){
        emit msgToServer(message);
        return;
    }else if(message.getmsgid() == MSG_CLITEN_CONNECT){
        emit msgToServer(message);
        //给该客户端发送更新的消息
        return;
    }else if(message.getmsgid() == MSG_CREATE_LIVE){
        emit msgToServer(message);
        //给其他客户端发送开播消息
        for(int i = 0; i < tcpSocketList.count(); i++)
        {
            QTcpSocket *temp = tcpSocketList.at(i);
            if(temp->peerName() != message.getmsgbuf())
            {
                QStringList name_list;
                name_list<<message.getmsgbuf();
                QString buf = myjson.pack_live_flush("on",name_list);
                MyMessage live_message(MSG_LIVE_FLUSH,buf,buf.length()); //开播消息
                temp->write(live_message.toString().toLatin1(), live_message.toString().length()+1);
                temp->flush();
                qDebug()<<live_message.toString()<<" "<<live_message.toString().length();
                continue;
            }
        }
        return;
    }else if(message.getmsgid() == MSG_CLOSE_LIVE){
        emit msgToServer(message);
        //给其他客户端发送下播消息
        for(int i = 0; i < tcpSocketList.count(); i++)
        {
            QTcpSocket *temp = tcpSocketList.at(i);
            if(temp->peerName() != message.getmsgbuf())
            {
                QStringList name_list;
                name_list <<message.getmsgbuf();
                QString buf = myjson.pack_live_flush("off", name_list);
                MyMessage live_message(MSG_LIVE_FLUSH,buf,buf.length()); //开播消息
                temp->write(live_message.toString().toLatin1(), live_message.toString().length()+1);
                temp->flush();
                continue;
            }
        }
        return;
    }

}

void TcpServer::tcpDisconnected(QString name)
{
    QString disconnectbuf;
    //关闭
    for(int i = 0; i < tcpSocketList.count(); i++)
    {
        TcpSocket *temp = tcpSocketList.at(i);
        if(temp->peerName() == name)
        {
            disconnectbuf = temp->peerAddress().toString() + " " + QString::number(temp->peerPort()) + " disconnected!!";
            temp->destroyed();
            tcpSocketList.removeAt(i);
            break;
        }
    }
    //发送该客户端被关闭的消息
    QString msgbuf = name;
    MyMessage message(MSG_CLIENT_CLOSE,msgbuf,msgbuf.length());
    emit msgToServer(message);
    disconnectbuf = name+" "+ disconnectbuf;
    mylog->LogWrite(disconnectbuf);
    return;
}

void TcpServer::tcpLogicSuccess(QString name)
{
    QStringList name_list;
    for(int i = 0; i < tcpSocketList.count(); i++)
    {
        QTcpSocket *temp = tcpSocketList.at(i);
        if(temp->peerName() == name)
        {
            for(int j = 0;j<tcpSocketList.count();j++){
                TcpSocket *other_temp = tcpSocketList.at(j);
                if(other_temp->getlive_state() == 1){
                    name_list<<other_temp->peerName();
                    //                    QString buf = myjson.pack_live_flush("on",other_temp->peerName());
                    //                    MyMessage live_message(MSG_LIVE_FLUSH,buf,buf.length()); //开播消息
                    //                    temp->write(live_message.toString().toLatin1(), live_message.toString().length()+1);
                    //                    temp->waitForBytesWritten(100);
                    //                    temp->flush();
                    //                    qDebug()<<"to "<<temp->peerName()<<live_message.toString()<<" "<<live_message.toString().length();
                }
            }
            QString buf = myjson.pack_live_flush("on",name_list);
            MyMessage live_message(MSG_LIVE_FLUSH,buf,buf.length()); //开播消息
            temp->write(live_message.toString().toLatin1(), live_message.toString().length()+1);
            temp->flush();
            qDebug()<<"to "<<temp->peerName()<<live_message.toString()<<" "<<live_message.toString().length();
            return;
        }
    }
}

message.h
enum MsgId{
    MSG_START = 0,
    MSG_CLITEN_CONNECT, //连接消息
    MSG_READ_BYTES,   //读取接收到的消息
    MSG_CLIENT_CLOSE,   //客户端关闭的消息
    MSG_LOGIC,  //客户端登录消息
    MSG_REGISTER,//客户端注册消息
    MSG_SHAKE_HAND, //握手
    MSG_CREATE_LIVE,//创建直播
    MSG_LIVE_FLUSH,//直播列表刷新
    MSG_CLOSE_LIVE,//直播间关闭
    MSG_END
}; 
mainwindow.cpp

主要实现主播列表实时更新的功能

客户端

客户端主要是消息的发送,消息的解析 和界面的跳转

在这里插入图片描述

clientjson.h
#ifndef CLIENTJSON_H
#define CLIENTJSON_H


#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonParseError>
#include <QDebug>
#include <QByteArray>

typedef struct live_flush{
    QString action;
    QStringList name;
}Live_Flush_S;

class ClientJson
{
public:
    ClientJson();
    //打包账号密码
    QString pack_name_pswd(QString name,QString pswd);
    //解析直播间刷新消息
    QString live_flush_info(QString message_buf,Live_Flush_S &live_msg);
};

#endif // CLIENTJSON_H

clientjson.cpp
#include "clientjson.h"

ClientJson::ClientJson()
{

}

QString ClientJson::pack_name_pswd(QString name, QString pswd)
{
    QJsonObject json;
    json.insert("Name",name);
    json.insert("password",pswd);
    QJsonDocument document;
    document.setObject(json);
    QByteArray byteArray = document.toJson(QJsonDocument::Compact);
    QString strJson(byteArray);
    return strJson;
}

QString ClientJson::live_flush_info(QString message_buf, Live_Flush_S &live_msg)
{
    QByteArray bytes = message_buf.toUtf8();
    QJsonParseError jsonError;
    QJsonDocument doucment = QJsonDocument::fromJson(bytes, &jsonError);
    if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) {  // 解析未发生错误
        if (doucment.isObject()){
            QJsonObject object = doucment.object();  // 转化为对象
            if (object.contains("action")) {
                QJsonValue value = object.value("action");
                if (value.isString()) {
                    live_msg.action = value.toString();
                    qDebug() << "action : " << live_msg.action;
                }
            }else{
                return "json_error_no_name";
            }
            if (object.contains("name")) {
                QJsonValue value = object.value("name");
                if (value.isArray()) {
                    QJsonArray array = value.toArray();
                    int size = array.size();
                    for (int i = 0; i < size; ++i) {
                        QJsonValue value = array.at(i);
                        if (value.isString()) {
                            live_msg.name<<value.toString();
                        }
                    }
                    qDebug() << "name : " << live_msg.name;
                }else{
                    return "name_json_error";
                }
            }else{
                return "json_error_no_action";
            }
        }else{
            return "json is no object";
        }
    }else{
        return "json error";
    }
    return "success";
}


tcpthread.cpp

主要是用来解析收到的直播刷新消息并且给界面发送信号
在这里插入图片描述

liveroom.cpp room.cpp

只是写了关闭函数,并且重写了关闭事件
在这里插入图片描述

widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QMessageBox>
#include <QDebug>
#include "tcpthread.h"
#include "mymessage.h"
#include "clientjson.h"
#include "room.h"
#include "liveroom.h"

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    void Logic_Init();//登录初始化
    void User_Init();//使用界面初始化
    void connectToServer(); //用连接服务器
    void deleteListRoom(QString);

public slots:
    void connect_state(QString); //用来控制连接状态
    void connect_success(); //用来判断连接状态
    void logic_msg_recv(QString); //用来处理登录消息
    void reg_msg_recv(QString); //用来处理注册消息
    void liveroom_msg_recv(QString);
    void live_flush_recv(QString action,QStringList namelist);//用来处理直播间刷新
    void room_msg_recv(QString); //用来观看直播的消息

private slots:
    void on_radioshow_clicked(bool checked); //用来显示密码和隐藏密码

    void on_pushlogic_clicked();//用来登录

    void on_pushquit_clicked();//用来退出

    void on_pushregister_clicked();

    void on_pushCreate_clicked();

    void on_pushAdd_clicked();

signals:
    void connect_enable(); //连接

private:
    Ui::Widget *ui;
    TcpThread *tcpThread;//用来启动socket线程
//    bool status;
    QString userName; //账号
    QString passWord; //密码
    int Logic_Flag; //用来判断是登录还是注册0注册1登录
    LiveRoom *liveroom;
    ClientJson myjson;
    Room *room;

};

#endif // WIDGET_H

widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QThread>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    tcpThread = nullptr;
    room = nullptr;
    liveroom = nullptr;
    //    status = false;
    Logic_Init();
    QObject::connect(this,SIGNAL(connect_enable()),this,SLOT(connect_success()));
}

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->listRoom->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->listRoom->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)));
        QObject::connect(tcpThread,SIGNAL(send_logic_msg(QString)),this,SLOT(logic_msg_recv(QString)));
        QObject::connect(tcpThread,SIGNAL(send_reg_msg(QString)),this,SLOT(reg_msg_recv(QString)));
        QObject::connect(tcpThread,SIGNAL(send_live_flush_msg(QString,QStringList)),this,SLOT(live_flush_recv(QString,QStringList)));
    }
    tcpThread->startThread(Address_Ip,port);
}

void Widget::deleteListRoom(QString name)
{
    int row = 0;
    QString line;
    while(row < ui->listRoom->count()){
        line=ui->listRoom->item(row)->text();
        if(name==line)
        {
            //qDebug()<<"删除成功";
            ui->listRoom->takeItem(row);
            break;
        }
        row++;
    }
}

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();
        return;
    }else if(message == "disconnect"){
        tcpThread->stopThread();
        return;
    }else if(message == "overtime"){
        QMessageBox::warning(NULL,tr("无法连接"),tr("无法连接请稍后再试"));
        ui->label_connect_state->clear();
        tcpThread->stopThread();
        return;
    }else if(message.left(9) == "reconnect"){
        QString text = "第"+message.right(1)+"次重连中";
        ui->label_connect_state->setText(text);
    }
}

void Widget::connect_success()
{
    QString strJson = myjson.pack_name_pswd(userName,passWord);
    MyMessage mymsg((Logic_Flag?MSG_LOGIC:MSG_REGISTER),strJson,strJson.length());
    qDebug()<<mymsg.toString();
    tcpThread->onSendTcp(mymsg.toString());
}

void Widget::logic_msg_recv(QString message)
{
    if(message == "success"){
        QMessageBox::about(NULL,"登录","登录成功");
        User_Init();
        return;
    }else if(message == "pswd_error"){
        QMessageBox::warning(NULL," 密码错误","密码输入错误请重试");
        tcpThread->stopThread();
        return;
    }
    else if(message == "no_name"){
        QMessageBox::warning(NULL,"未注册","请先注册账号");
        tcpThread->stopThread();
        return;
    }
}

void Widget::reg_msg_recv(QString message)
{
    if(message == "success"){
        QMessageBox::about(NULL,"注册","注册成功");
        tcpThread->stopThread();
        return;
    }else if(message == "rename"){
        QMessageBox::warning(NULL,"用户名重复","请输入其他用户名");
        tcpThread->stopThread();
    }else{
        tcpThread->stopThread();
    }
}


void Widget::liveroom_msg_recv(QString liveroommsg)
{
    if(liveroommsg == "close"){
        this->show();
        liveroom = nullptr;
        MyMessage live_close(MSG_CLOSE_LIVE,userName,userName.length());
        qDebug()<<live_close.toString();
        tcpThread->onSendTcp(live_close.toString());
    }
}

void Widget::live_flush_recv(QString action, QStringList namelist)
{
    if(action == "on"){
        for(int i = 0;i<namelist.count();i++){
            QString name = namelist.at(i);
            ui->listRoom->addItem(name);
        }
    }else if(action == "off"){
        for(int i = 0;i<namelist.count();i++){
            QString name = namelist.at(i);
            deleteListRoom(name);
        }
    }
}

void Widget::room_msg_recv(QString roommsg)
{
    if(roommsg == "close"){
        this->show();
        room = nullptr;
    }
}




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();
    passWord = ui->linepswd->text();
    Logic_Flag = 1;
    //连接
    connectToServer();
}

void Widget::on_pushquit_clicked()
{
    tcpThread->stopThread();
    QMessageBox::about(NULL,tr("退出"),tr("点击退出"));
    this->close();
}


void Widget::on_pushregister_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();
    passWord = ui->linepswd->text();
    Logic_Flag = 0;
    //连接
    connectToServer();
}

void Widget::on_pushCreate_clicked()
{

    MyMessage message(MSG_CREATE_LIVE,userName,userName.length());
    tcpThread->onSendTcp(message.toString());
    if(liveroom == NULL){
        qDebug()<<"new";
        liveroom = new LiveRoom;
        connect(liveroom,SIGNAL(sendlivemsg(QString)),this,SLOT(liveroom_msg_recv(QString)));
        liveroom->show();
        QString room_name = userName + "的直播间";
        liveroom->setWindowTitle(room_name);
        this->hide();
    }else{
        liveroom->show();
    }
    return;
}

void Widget::on_pushAdd_clicked()
{
    if(ui->listRoom->count() == 0){
        QMessageBox::warning(NULL,tr("无法加入"),tr("没有主播"));
        return;
    }
    if(ui->listRoom->currentItem() == NULL){
        QMessageBox::warning(NULL,tr("没有选择"),tr("请选择要加入的直播间"));
        return;
    }else{
        if(room == NULL){
            qDebug()<<"new";
            room = new Room();
            connect(room,SIGNAL(roommsg(QString)),this,SLOT(room_msg_recv(QString)));
            room->show();
            QString liver = ui->listRoom->currentItem()->text();
            QString room_name = liver + "的直播间";
            room->setWindowTitle(room_name);
            this->hide();
        }else{
            room->show();
        }
    }
}

4、项目文件

源代码.

5、效果展示

1、测试开播下播时服务器的反应
请添加图片描述
2、测试开播时其他客户端能否正常刷新
请添加图片描述
3、测试其他客户端已经开播,用户登录后直播间信息是否正常刷新
请添加图片描述
4、测试没有人直播时无法加入直播间,已经已经有人直播之后加入直播间
请添加图片描述

6、小结

今天对界面的跳转,界面的自动释放,以及QWidgetList的使用有了一定的了解,并且使用了一下

日日行,不怕千万里;常常做,不怕千万事。 !!!!!!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QT中编译arm-linux-gnueabihf项目需要进行以下几个步骤: 1. 安装交叉编译工具链 在Linux系统中使用以下命令安装交叉编译工具链: ``` sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf ``` 2. 在QT中设置交叉编译工具链 打开QT Creator,在菜单栏中选择“工具”->“选项”->“设备”->“添加”,然后选择“通用 Linux 设备”并点击“下一步”。 在“设备类型”下拉列表中选择“通用 Linux 设备”,在“设备名称”中输入你的设备名称,比如“Raspberry Pi”。 在“SSH”选项卡中输入你的设备IP地址和用户名,并选择“密码”或“密钥”进行身份验证。 在“工具链”选项卡中选择“添加”,然后选择“GCC”并点击“下一步”。 在“工具链名称”中输入你的工具链名称,比如“arm-linux-gnueabihf-gcc”,在“工具链路径”中输入你的交叉编译工具链路径,比如“/usr/bin/arm-linux-gnueabihf-gcc”。 3. 配置QT项目QT Creator中打开你的项目,然后在左侧窗口中选择“项目”->“构建设置”->“构建环境”。 在“构建工具”下拉列表中选择“Desktop Qt <版本> <编译器>”,在“设备”下拉列表中选择你的设备名称,比如“Raspberry Pi”。 在“构建步骤”选项卡中选择“自定义步骤”并添加以下命令: ``` make -j4 scp -r <本地路径> <远程路径> ``` 其中“-j4”表示使用4个线程进行编译,“<本地路径>”为你的本地项目路径,“<远程路径>”为你的设备上的路径。 4. 编译和部署项目QT Creator中点击“构建”按钮进行编译,然后点击“部署”按钮将项目部署到你的设备上。 注意:在编译和部署过程中可能会出现一些问题,需要根据具体情况进行解决。同时,还需要保证你的设备已经正确连接到网络并且已经安装了必要的库和依赖项。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值