QUdpSocket+QWebEngineView打造简易聊天室

先看下效果图:

 

 

 

核心代码:

1 class msgWebObj:public QObject{
2     Q_OBJECT
3     Q_PROPERTY(QString msgLHtmlTmpl MEMBER m_msgLeftTmpl NOTIFY signalMsgHtml)//动态属性,后面网络通道注册对象会使用到
4     Q_PROPERTY(QString msgRHtmlTmpl MEMBER m_msgRightTmpl NOTIFY signalMsgHtml)
5     ...... 
6 };
1 msgWebView::msgWebView(QWidget*parent):QWebEngineView(parent),m_channel(new QWebChannel(this))
2 {
3     msgWebObj*obj1=new msgWebObj(this);
4     msgWebObj*obj2=new msgWebObj(this);
5     m_channel->registerObject("external0",obj1);//网络通道注册对象
6     m_channel->registerObject("external_10001",obj2);
7     page()->setWebChannel(m_channel);
8     load(QUrl("qrc:/src/msgTmpl.html"));//初始化网页信息
9 }
void msgWebView::appendMsg(QString msg, QString obj)
{
    QJsonObject jsonObj;
    jsonObj.insert("MSG",msg);//以键值对的方式插入值,(MSG:msg)
    QString ret=QJsonDocument(jsonObj).toJson(QJsonDocument::Compact);//紧凑模式,转成字符串
    if(obj==""){
        page()->runJavaScript(QString("appendHtml0(%1)").arg(ret));
    }else{
        page()->runJavaScript(QString("recvHtml_%1(%2)").arg(obj).arg(ret));
    }
}
 以下是js代码
1
var external0 = null; 2 var external_10001 = null; 3 4 String.prototype.format = function() { 5 if(arguments.length == 0) return this; 6 var obj = arguments[0]; 7 var s = this; 8 for(var key in obj) { 9 s = s.replace(new RegExp("{{" + key + "}}", "g"), obj[key]); 10 } 11 return s; 12 // 传过来的是个键值对 13 // (MSG: "hello") 14 // 可以把{{MSG}}直接替换为"hello" 15 } 16 17 new QWebChannel(qt.webChannelTransport, 18 function (channel) { 19 // 使用网络通道里面注册好的对象 20 external0 = channel.objects.external0; 21 external_10001 = channel.objects.external_10001; 22 } 23 ); 24 25 function appendHtml0(msg){ 26 $("#placeholder").append(external0.msgRHtmlTmpl.format(msg)); 27 window.scrollTo(0,document.body.scrollHeight); ; 28 }; 29 30 function recvHtml_10001(msg){ 31 $("#placeholder").append(external_10001.msgLHtmlTmpl.format(msg)); 32 window.scrollTo(0,document.body.scrollHeight); ; 33 };
 1 Widget::Widget(QWidget *parent)
 2     : QWidget(parent)
 3     , ui(new Ui::Widget)
 4 {
 5     ui->setupUi(this);
 6     setWindowFlag(Qt::FramelessWindowHint);
 7     m_sender=new QUdpSocket(this);
 8     m_sender->bind(6666,QUdpSocket::ShareAddress);//绑定端口
 9     connect(m_sender,&QUdpSocket::readyRead,this,&Widget::dealMsg);//对读取到的数据进行处理
10     initControl();
11 }
 1 void Widget::initControl()
 2 {
 3     loadStyleStyle();
 4     connect(ui->closeBtn,&QPushButton::clicked,[this]{
 5         close();
 6     });
 7     connect(ui->sendBtn,&QPushButton::clicked,[this]{
 8         ui->textBrowser->appendMsg(ui->textEdit->document()->toPlainText());//将自己发送的数据显示到网页右侧
 9         m_sender->writeDatagram(ui->textEdit->document()->toPlainText().toUtf8(),QHostAddress::Broadcast,7777);//写入数据到端口7777
10         ui->textEdit->clear();
11     });
12 }
13 
14 void Widget::dealMsg()
15 {
16     QByteArray ret;
17     ret.resize(m_sender->pendingDatagramSize());
18     if(m_sender->hasPendingDatagrams()){
19         m_sender->readDatagram(ret.data(),ret.size());//读取数据
20         ui->textBrowser->appendMsg(ret,"10001");//显示到网页左侧
21     }
22 }

......

如果不懂可以下方评论留言,附上源码码云链接: https://gitee.com/waterkiller/qudp-simple-chat-room.git

posted @ 2021-01-25 18:29  youlj  阅读(173)  评论(0编辑  收藏  举报