您当前的位置: 首页 > 

龚建波

暂无认证

  • 2浏览

    0关注

    313博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

QML做一个聊天框

龚建波 发布时间:2021-04-03 00:59:49 ,浏览量:2

用QML做聊天界面的思路一般都是用ListView来展示聊天记录。我也做了一个简易的聊天框,效果如下:

虽然思路很简单,但是实现时遇到不少QML的Bug,比如滚动时图片闪烁、拉伸时位置/宽度绑定错误(所以我放弃了Layout)等,可能在别的版本还会有其他QML渲染上的Bug。

代码链接:https://github.com/gongjianbo/MyTestCode/tree/master/Qml/TalkList

不同类型的消息我用了不同的delegate,因为要动态选择delegate又使用了Loader进行加载。为了在Loader的sourceComponent里像一般的ListView delegate那样访问model数据,需要把Component声明到Loader里。

    delegate: Loader{
        sourceComponent: {
            switch(model.type){
            case TalkData.Text:

                return text_comp;
            case TalkData.Audio:
                return audio_comp;
            }
            return none_comp;
        }

        //放到delegate才能attach model
        Component{
            id: text_comp
            TalkItemText{ }
        }
        Component{
            id: audio_comp
            TalkItemAudio{ }
        }
        Component{
            id: none_comp
            Item{ }
        }
    }

Text不能选中文本,所以我用TextEdit来展示消息。不过这样也只能选中一个Label里的文本,不能全选。

下面贴两个主体代码,即文本行delegate的代码(完整代码请在上面的github连接下):

code 1.delegate item 基类

import QtQuick 2.12
import QtQuick.Layouts 1.12

//信息delegate的基类
//龚建波 2021-3-29
Item {
    id: control

    width: parent.ListView.view.width
    height: Math.max(profileHeight,
                     content_item.height)

    //profile picture头像
    property int profileHeight: 48
    property int messageHeight: 48

    property int leftWidth: 110
    property int rightWidth: 110
    property int contentWidth: Math.max(10,control.width-control.leftWidth-control.rightWidth)
    property bool isUser: (model.user===model.sender)
    property color messageBgColor: control.isUser?"#98E892":"#FFFFFF"

    default property alias contentItems: content_item.children

    Item{
        id: left_item
        height: control.height
        width: control.leftWidth
        //目前头像为固定,动态值可以放model
        Image {
            visible: !control.isUser
            width: control.profileHeight
            height: control.profileHeight
            anchors.horizontalCenter: parent.horizontalCenter
            source: "qrc:/Image/profile_48_gray.png"
            //fillMode: Image.PreserveAspectFit
        }
    }

    Column{
        id: content_item
        x: control.leftWidth
        width: control.contentWidth
        spacing: 6
        //layoutDirection: control.isUser?Qt.RightToLeft:Qt.LeftToRight
    }
    Item {
        id: right_item
        height: control.height
        width: control.rightWidth
        anchors.right: parent.right
        //头像没必要放两个,可以动态锚定
        //但是区分开后可以写一些差异化的操作
        Image {
            visible: control.isUser
            width: control.profileHeight
            height: control.profileHeight
            anchors.horizontalCenter: parent.horizontalCenter
            source: "qrc:/Image/profile_48_gray.png"
            //fillMode: Image.PreserveAspectFit
        }
    }

    //Component.onCompleted: {
    //    console.log('init',index);
    //}
    //Component.onDestruction: {
    //    console.log('free',index);
    //}
}

code 2.delegate text

import QtQuick 2.12

//文本信息delegate
//龚建波 2021-3-29
TalkItemBase {
    id: control

    //ColumnLayout在拉伸时计算有问题,暂时用Column+Row
    Row{
        width: control.contentWidth
        layoutDirection: control.isUser?Qt.RightToLeft:Qt.LeftToRight
        Rectangle{
            id: wrap_item
            radius: 4
            width: text_item.width
            height: text_item.height
            color: control.messageBgColor

            //指向发言人小三角
            Rectangle{
                width: 10
                height: 10
                y: control.messageHeight/2-10
                anchors.horizontalCenter: control.isUser?parent.right:parent.left
                rotation: 45
                color: control.messageBgColor
            }

            TalkLabel{
                id: text_item
                text: model.text_text
                width: Math.min(control.contentWidth,textWidth)
            }
        }
    }

    Row{
        width: control.contentWidth
        layoutDirection: control.isUser?Qt.RightToLeft:Qt.LeftToRight
        TalkLabel{
            text: model.datetime
            padding: 0
        }
    }
}

关注
打赏
1655829268
查看更多评论
立即登录/注册

微信扫码登录

0.0573s