QT TCP通信
1.QT TCP通信,查找信号,信号连接,单播,广播发送信息。
2.FormChat对话,发送文字,图片文件
轻映录屏 2022-09-16 14-08-03
目前实现了:
FormChat的一部分功能,根据文字宽高设置气泡宽高,新发消息后旧的对话会上移一定的距离,记录所有聊天信息。每间隔四条消息显示一次当前时间,最后一条消息显示当前日期+时间并保存为TXT格式。
发送的图片保存的时候保存文件位置,双击图片显示图片,点击上一张下一张轮回查看。
右侧列表显示朋友名称和头像,最后一条消息,最后一条消息时间,单击右侧朋友列表,左侧刷新对话信息。
以下为FormChat的UI界面设计
以下为成果展示:
- 一,创建scene
QGraphicScene(场景):可以管理多个图形项
QGraphicsItem(图形项):也就是图元,支持鼠标事件响应。
QGraphicsView(视图):关联场景可以让场景中的所有图形项可视化
Graphics View绘图架构,它是一种基于图形项(Graphics Item)的模型/视图模式,这种方式可以在一个场景中绘制大量图元项,且每个图元项都是可选择、可交互的,从QGraphicsView 类继承定义一个图形视图类 QWGraphicsView 。
我是使用QGraphicsView—>右键—>promote to将Classs变为QWGraphicsView
创建QGraphicsScene,new QGraphicsScene(x,y, width, height) ,我设置的是new QGraphicsScene(-300,-200,600,20000);
实现鼠标滚轮上下移动,所有item上下移动
考虑到成果图里面不需要滚动条,可以关闭滚动条显示ui->View->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff),
滚动条显示最下面的item可以设置ui->View->centerOn(0,20000)滚动条显示在最下方
右侧朋友列表ui->View2->centerOn(0,0)滚动条显示在最上方
以下为代码
ui->View->setScene(scene); //与view关联
ui->View2->setScene(scene2); //与view关联
//ui->View->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//关闭滚动条的显示
//ui->View->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//关闭滚动条的显示
// ui->View->setDragMode(QGraphicsView::RubberBandDrag);//全局视图
//QCursor cursor; //创建光标对象
//cursor.setShape(Qt::OpenHandCursor);//设置光标形状(小手)
//setCursor(cursor); //使用光标
ui->View->centerOn(0,20000);//滚动条显示在最下方
//ui->View->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//关闭滚动条的显示
//ui->View->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//关闭滚动条的显示
ui->View->setCursor(Qt::CrossCursor); //设置鼠标
ui->View->setMouseTracking(true); //
ui->View->setDragMode(QGraphicsView::RubberBandDrag);
- 二,显示气泡框,文字,图片
气泡框,文字,图片作为item显示在scene中先确定要输入的文字总长宽,再设置气泡框长宽。
1.文字设置
用QGraphicsTextItem显示文字,QGraphicsTextItem *itemT=new QGraphicsTextItem(要显示的文字);
strW = itemT->boundingRect().width()文字宽度,设置气泡窗宽度,itemT->setDefaultTextColor(QColor(255, 255, 255));//设置默认文本颜色
itemT->setTextWidth(350)限制显示文字的宽度,否则文字会过宽。但是这里这个方式设置高度的时候,由于限制宽度了会自动换行,就与boundingRect().height()的高度不一样,这个问题我是一次次试验的根据不同高度再增加比例,发现还是有问题如图,应该有更好的方法可以解决。
2.气泡框设置
用QGraphicsPolygonItem画气泡框的每一个点,连接起来其中加上文字的宽高,以此设置气泡宽高。
3.图片设置
先建立一个QPixmap pix,再根据图片的文件位置LEFT_curPix1字符串pix.load(LEFT_curPix1),再建立QGraphicsPixmapItem将图片放进去。
setScale(0.05)将item图片缩小。
4.上移所有item
当新增对话的时候需要所有的item上移,计算所有 item数量,将每个item的Y坐标减少一定值,实现item遍历上移。
以下为代码
for(int i=0;i<paocount*3+3+Time_num_tip;i++)
{
QGraphicsItem *item=scene->items().at(i);
item->setY(-1*MoveUPDown+item->y());
}
5.保存聊天信息
以TXT文件保存方便每次显示,记录信息。
三,朋友列表设置
同样建一个scene2,根据保存的TXT文件,查找到对应的人,以绘图方式绘制矩形框,放入文字,图片,显示最近聊天信息,最近聊天时间。
根据鼠标移动点击的点的坐标,确定点击到的是列表的哪一项,以此找到对应的文件TXT文件打开。
以下为代码
void MainWindow::on_mouseMovePoint(QPoint point)
{//鼠标移动事件,point是 GraphicsView的坐标,物理坐标
labViewCord->setText(QString::asprintf("View2 坐标:%d,%d",point.x(),point.y()));
QPointF pointScene2=ui->View2->mapToScene(point); //转换到Scene坐标
labSceneCord->setText(QString::asprintf("Scene2 坐标:%.0f,%.0f",pointScene2.x(),pointScene2.y()));
Mousepos_nametext=pointScene2.y()+190;
Mousepos_X_round=pointScene2.x();
}
void MainWindow::on_mouseClicked(QPoint point)
{//鼠标单击事件
QPointF pointScene=ui->View->mapToScene(point); //转换到Scene坐标
QGraphicsItem *item=NULL;
item=scene->itemAt(pointScene,ui->View->transform()); //获取光标下的绘图项
if (item2 == NULL) //没有绘图项
return;
switch (item2->type()) //绘图项的类型
{
case QGraphicsPolygonItem::Type:
{
// ui->radioher->is
ui->textEdit->clear();
IFTimeV=IFTimeV+1;
if(movepao2!=movepao)//当对话气泡上移,更新保存聊天文件
{
QDateTime curDateTime1=QDateTime::currentDateTime();
QString timeDAY=curDateTime1.toString("yyyy.MM.dd hh:mm");//转换为字符串显示
ui->textEditDevice->append("%**%"+timeDAY);
actSave_AtoB();
}
if(IFTimeV>1)
{ ui->textEditDevice->clear();
on_actEdit_Delete_triggered();
}
for(int i=0;i<LeftfrontZ;i++)
{
i=i+4;
QGraphicsItem *item23=scene2->items().at(i);
QGraphicsPolygonItem *theItem23=qgraphicsitem_cast<QGraphicsPolygonItem*>(item23);
theItem23->setBrush(QBrush(QColor(85, 170, 127,255)));//红,绿,蓝
}
QGraphicsPolygonItem *theItem=qgraphicsitem_cast<QGraphicsPolygonItem*>(item2);//鼠标下的当前项,转换为QGraphicsPolygonItem
theItem->setBrush(QBrush(QColor(141, 211, 163,255)));//红,绿,蓝
if(Mousepos_X_round<=103)//本想鼠标只是点击列表部分得到坐标Y的值,无用
{
Group_turn1=Mousepos_nametext/70;//鼠标点击的位置获得,第几个左侧列表的Group
}
}
当每次点击下一项的时候,保存上一项内容,并且在聊天信息增加的部分新增一个当前日期时间的输出。
当每次点击下一项的时候,删除所有scene上面的item。
//删除所有选中的绘图项
/*int cnt=scene->selectedItems().count();
ui->textEdit->append(QString::number(cnt));
if (cnt>0)
for (int i=0;i<cnt;i++)
{
QGraphicsItem* item=scene->selectedItems().at(0);
scene->removeItem(item); //删除绘图项
}*/
//获得指定矩形区域内的元素的指针列表
QList<QGraphicsItem *> item_list_p = scene->items(QRectF(-316,-199,1000,20000), Qt::IntersectsItemShape);
//删除元素
for(int i=0; i<item_list_p.size(); i++){
scene->removeItem(item_list_p[i]); //从scene移除
delete item_list_p[i]; //释放内存
}
seqNum=0;
movepao=0;
Time_num_tip=0;
paocount=0;
- 四,双击打开图片
鼠标双击图片根据图片位置打开原图片。展示图片的时候新弹出一个窗口formDoc。将图片位置以QStringList传递给新窗口,点击“上一张”,“下一张”,来实现图片来回切换
微信模拟程序框架已经搭建完成,花了近一个月时间完成了聊天部分内容,期间由于工作原因断断续续些这个程序,其他待完成内容:
轻映录屏 2022-09-16 14-05-14
还在更新中,敬请期待!
本人QT写出来的程序还有很多欠缺的地方,感谢指教!!!