Qt模仿QQ聊天窗口界面(一)

  • Qt模仿QQ聊天窗口界面(一)

    • 简述
    • 效果图
      • QQ的聊天窗口
      • 我做的效果图
    • 代码篇
      • 结尾

简述

最近利用业余时间,模仿QQ做了一个聊天窗口界面,功能还不全,准备分几个部分做出来,还是看空闲时间了,以及广大网友的支持了。

效果图

QQ的聊天窗口

我做的效果图

代码篇

//TalkWindowShell.cpp
TalkWindowShell::TalkWindowShell(QWidget *parent): BasicWindow(parent)
{ui.setupUi(this);initControl();{TalkWindow* talkwindow1 = new TalkWindow(this);TalkWindowItem* talkwindowItem1 = new TalkWindowItem(talkwindow1);talkwindow1->setWindowName(QStringLiteral("雨田哥-工作号-1号"));talkwindowItem1->setMsgLabelContent(QStringLiteral("雨田哥-1号"));talkwindow1->setWindowSignName(QStringLiteral("欢迎吐槽、雨田哥-工作号-1号"));addTalkWindow(talkwindow1, talkwindowItem1);}{TalkWindow* talkwindow2 = new TalkWindow(this);TalkWindowItem* talkwindowItem2 = new TalkWindowItem(talkwindow2);talkwindow2->setWindowName(QStringLiteral("雨田哥-工作号-2号-2号"));talkwindowItem2->setMsgLabelContent(QStringLiteral("雨田哥-2号"));talkwindow2->setWindowSignName(QStringLiteral("欢迎吐槽、雨田哥-工作号-2号-2号"));addTalkWindow(talkwindow2, talkwindowItem2);}{TalkWindow* talkwindow3 = new TalkWindow(this);TalkWindowItem* talkwindowItem3 = new TalkWindowItem(talkwindow3);talkwindow3->setWindowName(QStringLiteral("雨田哥-工作号-3号-3号-3号"));talkwindowItem3->setMsgLabelContent(QStringLiteral("雨田哥-3号"));talkwindow3->setWindowSignName(QStringLiteral("欢迎吐槽、雨田哥-工作号-3号-3号-3号"));addTalkWindow(talkwindow3, talkwindowItem3);}
}TalkWindowShell::~TalkWindowShell()
{delete m_emotionWindow;m_emotionWindow = nullptr;
}void TalkWindowShell::initControl()
{loadStyleSheet("TalkWindow");m_emotionWindow = new EmotionWindow;m_emotionWindow->hide();QList<int> leftWidgetSize;leftWidgetSize << 154 << width() - 154;ui.splitter->setSizes(leftWidgetSize);ui.listWidget->setStyle(new CustomProxyStyle(this));connect(ui.listWidget, &QListWidget::itemClicked, this, &TalkWindowShell::onTalkWindowItemClicked);connect(m_emotionWindow, SIGNAL(signalEmotionItemClicked(int)), this, SLOT(onEmotionItemClicked(int)));
}void TalkWindowShell::onEmotionBtnClicked(bool)
{m_emotionWindow->setVisible(!m_emotionWindow->isVisible());QPoint emotionPoint = this->mapToGlobal(QPoint(0, 0));emotionPoint.setX(emotionPoint.x() + 170);emotionPoint.setY(emotionPoint.y() + 220);m_emotionWindow->move(emotionPoint);
}void TalkWindowShell::onTalkWindowItemClicked(QListWidgetItem *item)
{QWidget* talkwindowWidget = m_talkwindowItemMap.find(item).value();ui.rightStackedWidget->setCurrentWidget(talkwindowWidget);
}void TalkWindowShell::addTalkWindow(TalkWindow* talkwindow, TalkWindowItem* talkwindowitem)
{ui.rightStackedWidget->addWidget(talkwindow);connect(m_emotionWindow, SIGNAL(signalEmotionWindowHide()), talkwindow, SLOT(onSetEmotionBtnStatus()));QListWidgetItem *aItem = new QListWidgetItem(ui.listWidget);m_talkwindowItemMap.insert(aItem, talkwindow);aItem->setSelected(true);talkwindowitem->setHeadPixmap("");ui.listWidget->addItem(aItem);ui.listWidget->setItemWidget(aItem, talkwindowitem);onTalkWindowItemClicked(aItem);connect(talkwindowitem, &TalkWindowItem::signalCloseClicked, [talkwindowitem, talkwindow, aItem, this](){m_talkwindowItemMap.remove(aItem);talkwindow->close();ui.listWidget->takeItem(ui.listWidget->row(aItem));delete talkwindowitem;ui.rightStackedWidget->removeWidget(talkwindow);if (ui.rightStackedWidget->count() < 1)close();});
}void TalkWindowShell::onEmotionItemClicked(int emotionNum)
{TalkWindow* curTalkWindow = dynamic_cast<TalkWindow*>(ui.rightStackedWidget->currentWidget());if (curTalkWindow){curTalkWindow->addEmotionImage(emotionNum);}
}
TalkWindow.cpp
TalkWindow::TalkWindow(QWidget *parent): QWidget(parent)
{setAttribute(Qt::WA_DeleteOnClose);ui.setupUi(this);initControl();
}TalkWindow::~TalkWindow()
{}void TalkWindow::initControl()
{setSendBtnMenu();QList<int> rightWidgetSize;rightWidgetSize << 600 << 138;ui.bodySpliter->setSizes(rightWidgetSize);connect(ui.sysmin, SIGNAL(clicked(bool)), parent(), SLOT(onShowMin(bool)));connect(ui.sysclose, SIGNAL(clicked(bool)), parent(), SLOT(onShowClose(bool)));connect(ui.closeBtn, SIGNAL(clicked(bool)), parent(), SLOT(onShowClose(bool)));connect(ui.faceBtn, SIGNAL(clicked(bool)), parent(), SLOT(onEmotionBtnClicked(bool)));connect(ui.sendBtn, SIGNAL(clicked(bool)), this, SLOT(onSendBtnClicked(bool)));ui.msgWidget->setShowSkinControl(ui.skinLabel);
}void TalkWindow::onSetEmotionBtnStatus()
{ui.faceBtn->setChecked(false);
}void TalkWindow::setWindowName(const QString& name)
{ui.nameLabel->setText(name);
}void TalkWindow::setWindowSignName(const QString& name)
{ui.signLabel->setText(name);
}void TalkWindow::onSignalWindowclosed()
{close();
}void TalkWindow::onSendBtnClicked(bool)
{ui.textEdit->clear();ui.textEdit->delteAllEmotionImage();MsgWidgetItem* msgItem = new MsgWidgetItem(this);int count = ui.msgLayout->count();ui.msgLayout->insertWidget(count - 1, msgItem);
}void TalkWindow::addEmotionImage(int emotionNum)
{ui.textEdit->setFocus();ui.textEdit->addEmotionUrl(emotionNum);
}void TalkWindow::setSendBtnMenu()
{QMenu* menu = new QMenu(this);menu->setWindowFlags(menu->windowFlags() | Qt::FramelessWindowHint);menu->setAttribute(Qt::WA_TranslucentBackground);menu->setObjectName("senMenu");m_sendAction = menu->addAction(QStringLiteral("按Enter键,发送消息"), this, SLOT(onEnterAction()));m_ctrlSendAction = menu->addAction(QStringLiteral("按Enter+Ctrl键,发送消息"), this, SLOT(onEnterCtrlAction()));QActionGroup* actiongroup = new QActionGroup(this);m_sendAction->setCheckable(true);m_ctrlSendAction->setCheckable(true);m_sendAction->setChecked(true);actiongroup->addAction(m_sendAction);actiongroup->addAction(m_ctrlSendAction);ui.sendBtn->setMenu(menu);
}void TalkWindow::onEnterAction()
{m_sendAction->setChecked(true);}void TalkWindow::onEnterCtrlAction()
{m_ctrlSendAction->setChecked(true);
}
EmotionWindow.cpp
const int emotionColumn = 14;
const int emotionRow = std::ceil(170 / 14);EmotionWindow::EmotionWindow(QWidget *parent): QWidget(parent)
{setWindowFlags(Qt::FramelessWindowHint | Qt::SubWindow);setAttribute(Qt::WA_TranslucentBackground);setAttribute(Qt::WA_DeleteOnClose);ui.setupUi(this);initControl();
}EmotionWindow::~EmotionWindow()
{}void EmotionWindow::initControl()
{CommonUtils::loadStyleSheet(this, "EmotionWindow");for (int row = 0; row < emotionRow; row++){for (int column = 0; column < emotionColumn; column++){EmotionLabelItem* label = new EmotionLabelItem(this);label->setEmotionName(row * emotionColumn + column);connect(label, &EmotionLabelItem::emotionClicked, this, &EmotionWindow::addEmotion);ui.gridLayout->addWidget(label, row, column);}}
}void EmotionWindow::addEmotion(int emotionNum)
{hide();emit signalEmotionWindowHide();emit signalEmotionItemClicked(emotionNum);
}void EmotionWindow::paintEvent(QPaintEvent *event)
{QStyleOption opt;opt.init(this);QPainter p(this);style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);__super::paintEvent(event);
}void EmotionWindow::showEvent(QShowEvent *event)
{setFocus();__super::showEvent(event);
}void EmotionWindow::focusOutEvent(QFocusEvent *event)
{QWidget* widget = qApp->widgetAt(QCursor::pos());if (widget != this && widget != ui.emotionWidget && widget != ui.topWidget){hide();emit signalEmotionWindowHide();}__super::focusOutEvent(event);
}
//QMsgTextEdit.cpp
QMsgTextEdit::QMsgTextEdit(QWidget *parent): QTextEdit(parent)
{}QMsgTextEdit::~QMsgTextEdit()
{delteAllEmotionImage();
}void QMsgTextEdit::delteAllEmotionImage()
{for (auto itor = m_emotionMap.constBegin(); itor != m_emotionMap.constEnd(); ++itor){delete itor.key();}m_emotionMap.clear();
}void QMsgTextEdit::addEmotionUrl(int emotionNum)
{const QString&& imageName = QString(":/TalkWindowShell/Resources/emotion/%1.png").arg(emotionNum);const QString&& flagName = QString("apng-%1-apng").arg(imageName);insertHtml(QString("<img src='%1'/>").arg(flagName));if (m_listEmotionUrl.contains(imageName))return;elsem_listEmotionUrl.append(imageName);QMovie* apngMovie = new QMovie(imageName, "apng", this);apngMovie->setCacheMode(QMovie::CacheNone);m_emotionMap.insert(apngMovie, flagName);connect(apngMovie, SIGNAL(frameChanged(int)), this, SLOT(onEmotionImageFrameChange(int)));apngMovie->start();
}void QMsgTextEdit::onEmotionImageFrameChange(int frame)
{QMovie* movie = qobject_cast<QMovie*>(sender());document()->addResource(QTextDocument::ImageResource, QUrl(m_emotionMap.value(movie)), movie->currentPixmap());setLineWrapColumnOrWidth(lineWrapColumnOrWidth());
}

结尾

其实,看代码篇,有点繁琐,因权限问题,我不能将工程文件上传,需要的,可以加我QQ。需要的可以加我QQ:3246214072。今天我只是先上传已做好的部分,后面看情况,会不断的完善这个聊天窗口界面。感谢广大网友的多多支持~

Qt模仿QQ聊天窗口界面(一)相关推荐

  1. Qt模仿QQ聊天窗口界面(二)

    Qt模仿QQ聊天窗口界面(二) Qt模仿QQ聊天窗口界面(二) 简述 修改 效果图 后期规划 代码 结尾 简述 在上篇我们已经搭好了QQ聊天窗口的框架,这里在原来的基础上叠加功能,以及优化一些控件. ...

  2. Qt模仿QQ聊天窗口界面(三)

    Qt模仿QQ聊天窗口界面(三)- 截图 Qt模仿QQ聊天窗口界面(三)- 截图 简述 效果图 代码篇 后期规划 结尾 简述 此篇在原来的基础上增加了QQ截图功能.在一个大佬的基础上进行了二次开发. 参 ...

  3. Qt模仿QQ聊天窗口(四)

    Qt模仿QQ聊天窗口-气泡聊天消息 Qt模仿QQ聊天窗口-气泡聊天消息 简述 效果图 相关博客 代码 结尾 简述 最近感冒了,头疼,头疼,头疼.好了,进入正题吧,基本的气泡消息展示做好了,支持图文混排 ...

  4. Qt模仿QQ登录界面(一)

    这两天研究qt,练习时做了个仿QQ登录界面,我这次实现的比较简单,先在这里记录一下,以后有空了会继续完善的. (一)效果图 这里使用我的qq号测试的如图: (二)工程文件 (三)代码实现 mainwi ...

  5. Qt模仿QQ聊天窗口合并功能

    模拟qq打开聊天窗口,打开多个聊天窗口时,窗口合并 效果图如下: 实现机制 聊天窗口放在QStackedWidget里管理,聊天条目放在QLIstWidget管理,通过QListWidget的item ...

  6. Qt 之 模仿 QQ登陆界面——功能篇(一)

    一.简述 今天是2017年第一篇技术文章,12月末事情太多,一直没来得及更新博客.今天继 Qt 之 模仿 QQ登陆界面--样式篇 这一篇 来简单地看一下对登录界面做的一些功能,主要是登录用户下拉列表和 ...

  7. pyqt5登录界面设计——模仿qq登录界面,可登录注册(数据库)

    pyqt5登录界面设计--模仿qq登录界面 一.简单易用的可直接登录的界面--账号密码程序写死 1.1.效果图: 1.2.视频效果图 3.代码说明 4.使用示例 5.全部源码见: 二.带数据库的可登录 ...

  8. Qt 之 模仿 QQ登陆界面——旋转窗口篇

    #一.简述 今天是新的一年第一篇博客,有大半个月没有更新博客了.我想是时候,打开电脑.拿起键盘.开始在我的代码之路上披荆斩棘,斩杀恶龙. 今天就继续来分享QQ登录界面的那些事.QQ登录界面的标题栏有一 ...

  9. java代码完全手写模仿qq登录界面

    这是我模仿QQ2015版界面,实现的基本功能有登陆验证,重置等,当然直接复制代码运行是不一样的,还要注意自己插入自己的图片. 结果截图如下所示: import java.awt.BorderLayou ...

最新文章

  1. uber_这就是我本可以免费骑Uber的方式
  2. spark重要参数调优建议:spark.default.parallelism设置每个stage默认的task数量
  3. jenkins 新手入门安装失败_树莓派安装jenkins,安安静静做个持续集成打包机
  4. 前端用sql 还是mysql_前端小白安装MySQL的踩坑路
  5. 接facebook广告_Facebook广告分析
  6. Visual C++ 时尚编程百例016(字体)
  7. linux笔记索引 QQFF-200305
  8. 获取和设置消息队列的属性msgctl,删除消息队列
  9. linux-centos使用 wget命令获取jdk
  10. 阿里云云计算 36 PolarDB MySQL的管理步骤
  11. 用IDM快速下载百度云文件
  12. 几种常用App原型设计工具详解
  13. 基于Pytorch实现的声音分类
  14. matlab 脉冲频域压缩,大作业-雷达线性调频脉冲压缩的原理及其MATLAB仿真.doc
  15. 阿里云国际版控制台使用海外云服务器教程详解
  16. COOC2.0一键做邻接表(多元组)+共现矩阵+相异矩阵+频次统计
  17. 对啊英语音标---四、双元音常见的字母发音组合有哪些
  18. 【MXNet学习16】在MXNet中使用Dropout
  19. 如何制作京东自提点地图?
  20. ubuntu18 百度云盘

热门文章

  1. iperf for linux 使用方法
  2. Python——类(class)的定义及使用
  3. halcon变量,图像与C++的一些转换(未完待续)
  4. 关于长尾应用的一些思考
  5. 开源项目SMSS发开指南(三)——protobuf协议设计
  6. STM32的硬件I2C与AT24C16
  7. c语言常见表达式汇总(赋值表达式,条件表达式,关系表达式,算数表达式......)
  8. 实用,一键生成数据库文档
  9. 多种方法进行去基线处理
  10. 遗传算法GA算法思路及其C++实现