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

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

简述

在上篇我们已经搭好了QQ聊天窗口的框架,这里在原来的基础上叠加功能,以及优化一些控件。

修改

1.优化表情窗口
2.优化聊天窗口右侧边栏按钮显示问题。
3.优化聊天窗口滚动条样式问题。
4.增加消息编辑框功能
5.增加聊天窗口字体设置,包括颜色,大小,加粗,斜体,下划线。
6.增加了,模仿QQ来消息时,滚动条下侧按钮闪烁功能。

效果图

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

后期规划

Qt模仿QQ聊天窗口界面(三)
1.增加QQ截图功能

Qt模仿QQ聊天窗口界面(四)
1.增加聊天窗口气泡消息功能

代码

#include "talkwindow.h"

#include <QTextCursor>
#include <QMovie>
#include <QImage>
#include <QScrollBar>
#include <QMenu>
#include <QPainter>
#include <QTimer>
#include <QDebug>
#include <QFontDatabase>
#include <QColorDialog> 

TalkWindow::TalkWindow(QWidget *parent)
    : QWidget(parent)
    , m_bshowbox(false)
{
    setAttribute(Qt::WA_DeleteOnClose);
    ui.setupUi(this);
    initControl();
    initFontWidget();
}

TalkWindow::~TalkWindow()
{

}

void TalkWindow::initControl()
{
    setSendBtnMenu();
    QList<int> rightWidgetSize;
    rightWidgetSize << 600 << 138;
    ui.bodySpliter->setSizes(rightWidgetSize);

    m_updateDownArrowtimer = new QTimer(this);
    connect(m_updateDownArrowtimer, SIGNAL(timeout()), this, SLOT(onUpdateDownArrowtimer()));
    m_updateDownArrowtimer->setInterval(500);

    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.fontBtn, SIGNAL(clicked(bool)), this, SLOT(onFontBtnClicked(bool)));
    connect(ui.faceBtn, SIGNAL(clicked(bool)), parent(), SLOT(onEmotionBtnClicked(bool)));
    connect(ui.sendBtn, SIGNAL(clicked(bool)), this, SLOT(onSendBtnClicked(bool)));

    ui.fontWidget->setVisible(false);
    ui.scrollArea->setShowSkinControl(ui.skinLabel);
    ui.skinLabel->setSpliterButton(ui.scrollArea->getTalkWindowSpliterButton());
}

void TalkWindow::initFontWidget()
{
    QFontDatabase database;
    foreach(const QString &family, database.families())
    {
        ui.fontfamilyCombox->addItem(family);
    }

    for (int fontsize = 9; fontsize < 22; fontsize++)
    {
        ui.fontsizeCombox->addItem(QString::number(fontsize));
    }

    connect(ui.fontfamilyCombox, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(onFontFamilycurrentIndexChanged(const QString &)));
    connect(ui.fontsizeCombox, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(onFontSizecurrentIndexChanged(const QString &)));
    connect(ui.boldBtn, SIGNAL(clicked(bool)), this, SLOT(onBoldBtnCLicked(bool)));
    connect(ui.italBtn, SIGNAL(clicked(bool)), this, SLOT(onItalBtnCLicked(bool)));
    connect(ui.underBtn, SIGNAL(clicked(bool)), this, SLOT(onUnderBtnCLicked(bool)));
    connect(ui.colorBtn, SIGNAL(clicked(bool)), this, SLOT(onColorBtnCLicked(bool)));
    connect(ui.textEdit, &QTextEdit::currentCharFormatChanged, this, &TalkWindow::currentCharFormatChanged);
}

void TalkWindow::onFontFamilycurrentIndexChanged(const QString &family)
{
    m_font.family = family;
    QTextCharFormat fmt;
    fmt.setFontFamily(family);
    mergeFormatOnWordOrSelection(fmt);
    ui.textEdit->setFontFamily(family);
    ui.textEdit->setFocus();
}

void TalkWindow::onFontSizecurrentIndexChanged(const QString &size)
{
    m_font.fontsize = size.toInt();
    QTextCharFormat fmt;
    fmt.setFontPointSize(size.toInt());
    mergeFormatOnWordOrSelection(fmt);
    ui.textEdit->setFontPointSize(size.toInt());
    ui.textEdit->setFocus();
}

void TalkWindow::onBoldBtnCLicked(bool)
{
    QTextCharFormat fmt;
    if (ui.textEdit->fontWeight() == QFont::Bold)
    {
        m_font.bold = QFont::Normal;
        fmt.setFontWeight(QFont::Normal);
        ui.textEdit->setFontWeight(QFont::Normal);
    }
    else
    {
        m_font.bold = QFont::Bold;
        fmt.setFontWeight(QFont::Bold);
        ui.textEdit->setFontWeight(QFont::Bold);
    }
    mergeFormatOnWordOrSelection(fmt);
    ui.textEdit->setFocus();
}

void TalkWindow::onItalBtnCLicked(bool)
{
    bool ital = ui.textEdit->fontItalic();
    m_font.ital = !ital;
    QTextCharFormat fmt;
    fmt.setFontItalic(!ital);
    mergeFormatOnWordOrSelection(fmt);
    ui.textEdit->setFontItalic(!ital);
    ui.textEdit->setFocus();
}

void TalkWindow::onUnderBtnCLicked(bool)
{
    bool underline = ui.textEdit->fontUnderline();
    m_font.underline = !underline;
    QTextCharFormat fmt;
    fmt.setFontUnderline(!underline);
    mergeFormatOnWordOrSelection(fmt);
    ui.textEdit->setFontUnderline(!underline);
    ui.textEdit->setFocus();
}

void TalkWindow::onColorBtnCLicked(bool)
{
    QColorDialog colorDialog;
    QColor color = colorDialog.getColor(ui.textEdit->textColor(), this, QStringLiteral("选择字体颜色"));
    m_font.color = color;
    QTextCharFormat fmt;
    fmt.setForeground(color);
    mergeFormatOnWordOrSelection(fmt);
    ui.textEdit->setTextColor(color);
    ui.textEdit->setFocus();
}

void TalkWindow::mergeFormatOnWordOrSelection(const QTextCharFormat &format)
{
    QTextCursor cursor = ui.textEdit->textCursor();
    if (!cursor.hasSelection())
        cursor.select(QTextCursor::Document);
    cursor.mergeCharFormat(format);
    ui.textEdit->mergeCurrentCharFormat(format);
}

void TalkWindow::currentCharFormatChanged(const QTextCharFormat &format)
{
    ui.textEdit->setFontFamily(m_font.family);
    ui.textEdit->setFontPointSize(m_font.fontsize);
    ui.textEdit->setFontWeight(m_font.bold);
    ui.textEdit->setFontItalic(m_font.ital);
    ui.textEdit->setFontUnderline(m_font.underline);
    ui.textEdit->setTextColor(m_font.color);
}

void TalkWindow::onFontBtnClicked(bool)
{
    if (ui.fontWidget->isVisible())
    {
        ui.fontWidget->setVisible(false);
        ui.fontBtn->setChecked(false);
    }
    else
    {
        ui.fontWidget->setVisible(true);
        ui.fontBtn->setChecked(true);
    }
    update();
}

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)
{
    QTextDocument* document = ui.textEdit->document();
    ui.scrollArea->scrollToBottom(ui.msgWidget);

    ui.textEdit->clear();
    ui.textEdit->delteAllEmotionImage();
    m_updateDownArrowtimer->start();
}

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);
}

void TalkWindow::onUpdateDownArrowtimer()
{
    m_bshowbox = !m_bshowbox;
    update();
}

void TalkWindow::paintEvent(QPaintEvent *event)
{
    __super::paintEvent(event);
    QPainter painer(this);
    painer.setRenderHint(QPainter::SmoothPixmapTransform, this);
    painer.setPen(Qt::NoPen);
    int fotWidget = 0;
    if (ui.fontWidget->isVisible())
        fotWidget = ui.fontWidget->height();
    painer.drawPixmap(ui.bodyWidget->width() - 13, ui.titleWidget->height() + 2, QPixmap(":/TalkWindowShell/Resources/scrollbar_top_normal.gft.png"));
    painer.drawPixmap(ui.bodyWidget->width() - 13, ui.bodyWidget->height() + ui.titleWidget->height() - 14 - fotWidget, QPixmap(":/TalkWindowShell/Resources/scrollbar_down_normal.gft.png"));
    if (m_updateDownArrowtimer->isActive())
    {
        if (m_bshowbox)
        {
            painer.setPen(QColor(174, 193, 191));
            painer.drawRect(ui.bodyWidget->width() - 13, ui.bodyWidget->height() + ui.titleWidget->height() - 14 - fotWidget, 11, 11);
        }
    }
}

结尾

觉得博主写了这么多项目中,不错,还可以的。打赏下博主吧。博主写了这么久代码,脑细胞死了不少。得喝喝六个核桃补补,后期才能更好的为大家开源更多精彩的内容~对不对,嘿嘿~

这里写图片描述
这里写图片描述

关键部分
觉得代码篇不满足你需求的,可以大胆的加博主QQ:3246214072,提供完整的工程文件供你使用。有什么问题,欢迎咨询博主QQ。

评论 3 您还未登录,请先 登录 后发表或查看评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:技术黑板 设计师:CSDN官方博客 返回首页

打赏作者

雨田哥

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值