如何用Qt4.7.1实现气泡聊天?

我还在迷路 2017-07-11 07:26:22
windows PC端,如何在Qt4.7.1的版本基础上实现类似与QQ的气泡聊天呢?


文字、图片可以选中,选中后可以复制,头像可以点击,
目前是使用的QTextEdit写的非气泡聊天方式,如何在QTextEdit的基础上进行修改可以实现跟QQ差不多的那种气泡聊天呢?


有经验的,可以帮忙提供下具体的思路,还望各位大神不吝指教!
...全文
2447 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
我还在迷路 2019-01-08
  • 打赏
  • 举报
回复
结贴,换公司了
亭台六七座 2018-08-03
  • 打赏
  • 举报
回复
html渲染气泡
Marcelxx 2018-07-09
  • 打赏
  • 举报
回复
我们做过类似的聊天程序,真不太建议用Qt来实现这个,可能后续增加场景发现效率什么的跟不上了。
建议使用QT+CEF试试,气泡什么的都交给html来渲染。
南瓜烛火 2018-06-26
  • 打赏
  • 举报
回复
https://blog.csdn.net/qq_41014441/article/details/80817692
小侠Dolphin 2017-11-25
  • 打赏
  • 举报
回复
我过去用Java Swing开发过一个类似的气泡聊天程序,在iteye发过一篇心得体会,楼主可以参考一下:http://www.iteye.com/topic/1138181
qq_23707589 2017-09-27
  • 打赏
  • 举报
回复
用Qtextedit可以实现啊,把Qtextedit,设置成透明的,气泡写一个label自己绘制,行高可以通过Qtextdocument获得,我就是这么实现的
我还在迷路 2017-07-17
  • 打赏
  • 举报
回复
引用 16 楼 nlstone 的回复:
我之前的项目,这里是用的graphicsview来做,把各个item算好坐标拼在一起就好了,不复杂。 文字聊天是稍微扩展了一下QGraphicsTextItem
请问下,设置好坐标的话,窗口变化的时候,是不是又要重新计算、设置一次呢?
nlstone 2017-07-17
  • 打赏
  • 举报
回复
我之前的项目,这里是用的graphicsview来做,把各个item算好坐标拼在一起就好了,不复杂。 文字聊天是稍微扩展了一下QGraphicsTextItem
我还在迷路 2017-07-15
  • 打赏
  • 举报
回复
引用 14 楼 wn0112 的回复:
这个气泡应该是切图paint的吧,左上,右上,左下,右下,上下左右,各有一张图。 用的TextEdit,缩放不会变形。 用背景图尺寸变化会变形的
九宫格的背景图已经没有问题了,气泡显示分为两块,一是背景图,也就是九宫格 二是block,显示内容的部分 现在显示内容的部分问题就如同上面我说的那样,还不知道如何改进 我是修改QTextDocument内核来实现的
我还在迷路 2017-07-14
  • 打赏
  • 举报
回复
static void adjustBubbleBlockMargin(const QAbstractTextDocumentLayout::PaintContext &context, QTextBlock &bl)
{
    bool ble = bl.blockFormat().hasProperty(QTextFormat::BubbleFormat);
    if(!ble)
        return ;

    QTextCharFormat tcf = bl.charFormat();
	QFontMetrics cfm(tcf.font());
	QString str = bl.text();
	QRect crect = cfm.boundingRect(str);
	int textw = crect.width();
    int texth = crect.height();
    QSizeF s = bl.document()->size();
	QTextCursor tc(bl);
	QTextBlockFormat bf(bl.blockFormat());
	bool friendBle = bl.blockFormat().hasProperty(QTextFormat::FriendBubbleFormat);
    if(friendBle)
    {
        bf.setLeftMargin(50);
        bf.setAlignment(Qt::AlignLeft);
    }
    else
    {
        if(context.clip.width() > 1024)
        {
            bf.setLeftMargin(50);
            bf.setAlignment(Qt::AlignLeft);
        }
        else
        {
            bf.setAlignment(Qt::AlignLeft);
            if(textw > context.clip.width())
            {
                bf.setRightMargin(40);
            }
            else
            {
                bf.setRightMargin(40);
                bf.setLeftMargin(context.clip.width() - textw - 57);
            }
        }
    }

    tc.setBlockFormat(bf);//这句话,如果执行的话,单核CPU会打满,目前还没有找到在哪里修改这个QTextBlockFormat才是合适的
}
我还在迷路 2017-07-14
  • 打赏
  • 举报
回复
目前采用的方法是改Qt内核,通过修改QTextBlockFFormat来完成,在显示block时,添加背景图片,并根据窗口大小自适应气泡背景的长度 在实现的时候,基本已经实现气泡聊天,只是还存在一个问题,在获取到QTextBlock的QTextBlockFormat并进行修改,重新设置到QTextBlock的时候,CPU存在偏高的问题,但如果不执行set操作,又不能将设置完成的QTextBlockFormat生效,这个现在还摸不到头绪,不知道set之后,他都干了些什么导致的CPU单核打满
王桑的一天 2017-07-14
  • 打赏
  • 举报
回复
这个气泡应该是切图paint的吧,左上,右上,左下,右下,上下左右,各有一张图。 用的TextEdit,缩放不会变形。 用背景图尺寸变化会变形的
  • 打赏
  • 举报
回复
为什么不用qlistwidget呢?一行就是一项,qlistwidget可以支持图片显示,支持编辑,复制,滚动。只要背景图做成气泡模式就可以啦
大卫无限 2017-07-13
  • 打赏
  • 举报
回复
这个问题还在么...用其它控件的方式组合的方法很难, 用lineedit,不能多行, 用listwidget不能很好的调整单元的高度.包括多选复杂问题,也很难解决. 再来说下我说的绘制方式,就是把textedit弄成透明的,然后在后面放一个widget之类的.,把气泡绘制到widget上.这个完全可行. 和楼上说的一个意思, 但这个之前我已经说过了,楼主并示采用, 我估计楼主想选择组合控件的方法,估计是因为觉得绘制的方法很麻烦. 但是不得不说绘制的这个方法虽然麻烦,但是基本最可行的. 完全可以尝试一下,Qt提供的视图之类的来重写一个基于视图的,但是遇到文字粘贴等问题,我估计,也不太可行. 绘制的问题最核心的麻烦就是你得确定文字的位置,然后再背景上绘制气泡,因为textedit如果有滚动条,那么就会涉及到计算文字位置. 就需要动态计算出这些位置,然后在背景上绘制气泡. 我们都知道,文字不可能只有一行,其中还可能有图片,高度还可能不固定.这样计算起来就更麻烦. 方法估计很容易想到,但是实现起来是需要很深的功底. 所以我一开始建议直接自己写一个控件. 话说回来这是很也不是一个简单的事.
nlstone 2017-07-13
  • 打赏
  • 举报
回复
没有完全理解到,你在后面放一个气泡的背景不就可以了? 随便说说,譬如后面基础是一个widget,放一个气泡图作背景,再把textedit放上去。。。
大卫无限 2017-07-12
  • 打赏
  • 举报
回复
这个问题挺复杂的呀,我只能提供思路,实现只能靠你自己. 不能用lineedit嵌进去,它只有一行.
我还在迷路 2017-07-12
  • 打赏
  • 举报
回复
引用 5 楼 n7zj0x8 的回复:
[quote=引用 3 楼 liuhengxiao 的回复:] [quote=引用 1 楼 n7zj0x8 的回复:] ....
你的意思我大概明白了,是用QPainter进行绘制图片、文字、背景,这种方式也考虑过,绘制出来的图片和文字不能选中操作,如果实现选中操作的话,是相当复杂的过程,头像的点击事件也是如此 如果改内核的话,不知道应该从哪个方面入手,头大[/quote] 如果你需要自己实现控件,那么文字选中复制,当然也可以实现了,无非就是画一个蓝色的背景,不过确实自己实现的成本非常高 再说QTextDocument的绘制, QTextDocument *QTextEdit::document() const 我看了一下文档,QTextDocument 它并没有提供绘制的相关接口, 但是我却发现QTextEdit可以设置背景透明,但是文字还显示出来的, 有了这个,就简单很多了. 算出行的位置,在背景控件上面绘制气泡.初步判断是可以实现的并且效率应该比较高. 再说一下上面那个同仁说的组合控件的问题,貌似也是可以解决问题的.但是麻烦程度和我提到的方法,难度一样. 首先是不可能每一条记录一个控件,这样会很卡.那么就只能是显示部分有控件, 没有显示的部分,没有控件,这就得在滚动条移动的时候去调整控件的位置. [/quote] 组合控件的话,比如说继承QLineedit嵌入到QTextedit中,这个嵌入话,怎么做才合适呢?如果不介意的话,是否可以私信你,留个联系方式,方便沟通
大卫无限 2017-07-12
  • 打赏
  • 举报
回复
引用 3 楼 liuhengxiao 的回复:
[quote=引用 1 楼 n7zj0x8 的回复:] ....
你的意思我大概明白了,是用QPainter进行绘制图片、文字、背景,这种方式也考虑过,绘制出来的图片和文字不能选中操作,如果实现选中操作的话,是相当复杂的过程,头像的点击事件也是如此 如果改内核的话,不知道应该从哪个方面入手,头大[/quote] 如果你需要自己实现控件,那么文字选中复制,当然也可以实现了,无非就是画一个蓝色的背景,不过确实自己实现的成本非常高 再说QTextDocument的绘制, QTextDocument *QTextEdit::document() const 我看了一下文档,QTextDocument 它并没有提供绘制的相关接口, 但是我却发现QTextEdit可以设置背景透明,但是文字还显示出来的, 有了这个,就简单很多了. 算出行的位置,在背景控件上面绘制气泡.初步判断是可以实现的并且效率应该比较高. 再说一下上面那个同仁说的组合控件的问题,貌似也是可以解决问题的.但是麻烦程度和我提到的方法,难度一样. 首先是不可能每一条记录一个控件,这样会很卡.那么就只能是显示部分有控件, 没有显示的部分,没有控件,这就得在滚动条移动的时候去调整控件的位置.
我还在迷路 2017-07-12
  • 打赏
  • 举报
回复
引用 2 楼 qqwangfan 的回复:
从qlineedit继承下来,将qlineedit的背景图作成气泡模式,这样文字可以选择,复制。每一行的聊天就是一个这样的控件显示。
把QLineedit嵌入到QTextedit里面去?
我还在迷路 2017-07-12
  • 打赏
  • 举报
回复
引用 1 楼 n7zj0x8 的回复:
我介意你自己写一个这样的控件,这样可扩展性更大,大概是采用绘制的方式,这样效率高. 如果你要用TextEdit来做,我觉得难度很高,只提供思路,估计你实现起来的时候会有很多细节问题.. 首先肯定不能使用html的背景图片的方式来做,因为TextEdit支持的排版格式并不多,很难做到对齐之类的. 再说自己绘制这样的一个图片,那么关键就是,在什么位置上绘制.这个当然是有办法知道的. 道先Text每一行是一个QTextBlock,可以知道它高度,可以知道当前行,那么就可以求出某一行的位置. 然后在文字位置进行绘制气泡.绘制好了.再调用父类的绘制函数,绘制对应的文字.这样气泡可以完美的达到效果. 不过看了这么多,你可能会觉得很懵,因为这个方法涉及到很多QTextEdit细节的操作,如果你对它不了解,做起来很困难. 比如至少要知道,TextEdit上面是一个QTextDocument.然后Document上面又是QTextBlock,然Block怎么获取,怎么调整...挺麻烦的. 最好的办法就是自己重写一个这样的控件.
你的意思我大概明白了,是用QPainter进行绘制图片、文字、背景,这种方式也考虑过,绘制出来的图片和文字不能选中操作,如果实现选中操作的话,是相当复杂的过程,头像的点击事件也是如此 如果改内核的话,不知道应该从哪个方面入手,头大
加载更多回复(3)

16,239

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧