qml 구현 채 팅 인터페이스

102682 단어 QT 프로 그래 밍
감사합니다. [Qml + Qt] 챗 봇 |http://www.qtcn.org/bbs/read-htm-tid-62920.html제공 하 는 사고방식
자신 이 필요 로 하 는 기능 을 추 가 했 습 니 다. listview 의 delegate 문 자 는 마우스 로 선택 하고 복사 할 수 있 으 며 키보드 ctrl + c 복사, item 의 삭 제 를 받 을 수 있 습 니 다. 마우스 가 맨 위로 미 끄 러 질 때 더 많은 item 을 불 러 오고 상호작용 채 팅 방식 을 지양 하 며 푸 시 에 만 사용 할 수 있 습 니 다. 상기 링크 를 참고 하 는 것 을 권장 합 니 다.
직접 코드 붙 이기:
import QtQuick 2.6
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.0
Rectangle {
    id: root
    color: "#f5f5f5"
    
    
    
    function add_message(timetext,issame,text,who,istip,type,id)
    {
        if(text.length <= 0)
        {
            return;
        }
        
        listView.model.insert(0, {"content": text, "send": who,"msgTime":timetext,"same":issame,"tip":istip,
                                  "send_type": type,"id": id});
        
        //verScrollBar.increase()
        
        //         
        verScrollBar.setPosition(1.0)
        
        
    }
    
    function add_more_message(timetext,issame,text,who,istip,type,id)
    {
        if(text.length <= 0)
        {
            return;
        }
        var count=listView.model.count
        listView.model.insert(count, {"content": text, "send": who,"msgTime":timetext,"same":issame,"tip":istip,
                                  "send_type": type,"id": id});
        
        //verScrollBar.increase()
        //verScrollBar.setPosition(1.0)
    }
    
    function clearListview()
    {
        listView.model.clear()
        
    }
    
    function re_edit_item(index)
    {
        var count=listView.model.count
        if(count>0){
            listView.model.remove(index,1)
        }
    }
    
    property bool showtip: false
    
    function show_tip()
    {
        showtip=true
    }
    
    function hide_tip()
    {
        showtip=false
    }
    
    ColumnLayout {
        id:page
        anchors.fill: parent
        //      focus   true
        focus: true
        
        //  messageText        ,      
        //page   ctrl+c   messagetext copy
        signal ctrl_c()
        
        Keys.onPressed: {
            if((event.modifiers===Qt.ControlModifier) && (event.key===Qt.Key_C)){
                //    
                page.ctrl_c()
            }
            event.accepted=true
        }
        
        
        Rectangle {
            id:tiprect
            width: tiptext.implicitWidth+10
            height: 30
            color: "#f5f5f5"
            anchors.horizontalCenter: parent.horizontalCenter
            visible:showtip
            
            Label {
                id: tiptext
                text: "             "
                verticalAlignment: Text.AlignVCenter
                horizontalAlignment: Text.AlignHCenter
                color: "#1f61ff"
                font.family: "    "
                font.pointSize: 9
                anchors.fill: parent
                anchors.margins:0
                
            }
            
        }
        
        ListView {
            id: listView
            Layout.fillWidth: true
            Layout.fillHeight: true
            Layout.margins:14
            Layout.rightMargin: 0
            displayMarginBeginning: 40
            displayMarginEnd: 40
            verticalLayoutDirection: ListView.BottomToTop
            spacing:14
            
            
            model:ListModel{}
            
            delegate: Column {
                
                anchors.left: parent.left
                spacing: 14
                width: parent.width
                
                property bool sendmessage: send
                property bool sameTime: same
                
                //  
                Rectangle {
                    width: timetext.implicitWidth+10
                    height: timetext.implicitHeight+2
                    color: tip ? "lightgrey" : "#d1cece"
                    anchors.horizontalCenter: parent.horizontalCenter
                    visible: !same
                    Label {
                        id: timetext
                        text: msgTime
                        verticalAlignment: Text.AlignVCenter
                        horizontalAlignment: Text.AlignHCenter
                        color: tip ? "red" : "white"
                        font.family: "    "
                        font.pointSize: 9
                        anchors.fill: parent
                        anchors.margins:0
                        
                    }
                    
                }
                
                //    
                Row {
                    
                    id: messageRow
                    spacing: 6
                    anchors.left: parent.left
                    visible: !tip
                    
                    //  
                    Image {
                        id: avatarLeft
                        height: 36
                        width: height
                        source: "qrc:/image/touxiang.jpg"
                    }
                    
                    //   
                    Rectangle {
                        width: Math.min(messageText.implicitWidth +14, listView.width -98)
                        height: messageText.implicitHeight + 16
                        color:  send ? "#9dea6a" : "#eeeeee"
                        radius: 3
                        
                        TextEdit {
                            id: messageText
                            text: content
                            font.family: "    "
                            //color: "#9dea6a"
                            font.pointSize: 11
                            anchors.fill: parent
                            anchors.topMargin: 9
                            anchors.bottomMargin: 7
                            anchors.rightMargin: 7
                            anchors.leftMargin: 7
                            wrapMode: TextEdit.Wrap
                            enabled: true
                            readOnly: true
                            selectByKeyboard: true
                            selectByMouse: true
                            selectedTextColor: "white"
                            persistentSelection:true
                            selectionColor: "#3396FF"
                            
                            //              listview
                            Drag.active: text_area.drag.active
                            
                        }
                        
                        //    ,             
                        MouseArea{
                            id:text_area
                            width: parent.width
                            height: parent.height
                            acceptedButtons: Qt.LeftButton|Qt.RightButton
                            //           ,     ,              
                            drag.target: messageText
                            hoverEnabled: true
                            
                            
                            property int _startpos: 0
                            property int _endpos: 0
                            property bool canselect: false
                            
                            
                            onClicked: {
                                //  =    ,js  
                                if(mouse.button===Qt.RightButton){
                                    
                                    //                   ,         
                                    if(_startpos<_endpos){
                                        messageText.select(_startpos-1,_endpos)
                                    } else {
                                        if(_startpos>_endpos){
                                            messageText.select(_endpos-1,_startpos)
                                        } else {
                                            messageText.select(_startpos,_endpos)
                                        }
                                    }
                                    //  mainwindow    
                                    mainwindow.listview_item_clicked(index,id,send_type,messageText.selectedText,messageText.text)
                                }
                            }
                            
                            
                            onEntered: {
                                //      ,               
                                page.ctrl_c.connect(message_cpoy)
                            }
                            
                            //  
                            function message_cpoy(){
                                messageText.copy()
                            }
                            
                            //    ,    ,    
                            onExited: {
                                messageText.deselect()
                                _startpos=0
                                _endpos=0
                                page.ctrl_c.disconnect(message_cpoy)
                                
                            }
                            
                            //        
                            onMouseXChanged: {
                                
                                if(canselect){
                                    _endpos=messageText.positionAt(mouseX,mouseY)
                                    
                                    //      1,      
                                    if(_startpos<_endpos){
                                        messageText.select(_startpos-1,_endpos)
                                    } else {
                                        if(_startpos>_endpos){
                                            messageText.select(_endpos-1,_startpos)
                                        } else {
                                            messageText.select(_startpos,_endpos)
                                        }
                                    }
                                }
                            }
                            
                            //              
                            onPressed: {
                                if(mouse.button===Qt.LeftButton){
                                    canselect=true
                                    _startpos=messageText.positionAt(mouseX,mouseY)
                                }
                            }
                            //           
                            onReleased: {
                                if(mouse.button===Qt.LeftButton){
                                    //messageText.copy()
                                    canselect=false
                                }
                                
                            }
                        }
                        
                    }
                }
            }
            
            ScrollBar.vertical: ScrollBar {
                id: verScrollBar
            }
            
            //          
            onContentYChanged: {
                //console.log("contenty:"+contentY)
                //console.log("originy"+originY)
                
                var x=contentY-originY
                if(x==0){
                    mainwindow.load_more_for_chatwidget();
                }
                
                
            }
            
        }
        
        /*  cpp         
        Connections{
            target: mywindows
            onShowmymsg:add_message(arg_1,arg_2,arg_3,arg_4,arg_5)
       }*/
        
    }
    
    
}

/ / cpp 의 함수: (cpp 에서 상하 문 속성 을 설정 한 후 사용 가능)
/ / quickwidget qml 불 러 오기
    QUrl source("qrc:/myqml/1.qml");
    //       c++ qml, qml   c++ Q_INVOKABLE   public    public   
    ui->quickWidget->rootContext()->setContextProperty("mainwindow",this);
    //            
    //qmlRegisterType("io.qt.mainwindow", 1, 0, "Mwindow");
    ui->quickWidget->setSource(source);

/ / 하나 추가
QQuickItem *item=ui->quickWidget->rootObject();
 
  
                QVariant returnVar;
                QString send_time1=QDateTime::fromString(send_time,"yyyyMMddhhmmss").toString("hh:mm");
                QVariant arg1 = send_time1;
                QVariant arg2;
                QVariant arg3 =send_text;
                QVariant arg4 =true;
                QVariant arg5 =false;
                QVariant arg6="no_reedit";
                QVariant arg7=-1;
 
  
                if(send_time1==lastSend_time)
                {
                    arg2= true;
                }
                else
                {
                    arg2=false;
                    lastSend_time=send_time1;
                }
 
  
                QMetaObject::invokeMethod(item, "add_message",
                                          Q_RETURN_ARG(QVariant, returnVar),Q_ARG(QVariant, arg1),Q_ARG(QVariant, arg2),
                                          Q_ARG(QVariant, arg3),Q_ARG(QVariant, arg4),Q_ARG(QVariant, arg5),
                                          Q_ARG(QVariant, arg6),Q_ARG(QVariant, arg7));


/ / cpp 의 함수
void mainwindow::listview_item_clicked(const int index, const int id, const QString sendtype,
                                       const QString selectedtext,const QString itemtext)
{
    qml_id=id;
    qml_index=index;
    qml_sendtype=sendtype;
    qml_selected_text=selectedtext;
    qml_item_text=itemtext;
    //qDebug()<
    //qDebug()<
    ui->quickWidget->customContextMenuRequested(QPoint(0,0));
}

qml 의 값 을 개인 변수 에 부여 하면 복사 및 방향 취소 기능 을 실현 할 수 있 습 니 다.
     //취소
    QQuickItem *item=ui->quickWidget->rootObject();
    QVariant returnVar;
    QVariant arg1 = qml_item_index;
    QMetaObject::invokeMethod(item, "re_edit_item",
                              Q_RETURN_ARG(QVariant, returnVar),Q_ARG(QVariant, arg1));
    label_who *label_w1 = (label_who *)(ui->label_2->userData(Qt::UserRole));
    //QString send_type=label_w1->send_type;
    QString send_who=label_w1->send_who;

/ / 선택 한 텍스트 를 복사 합 니 다. qml 파일 에서 선택 한 후 ctrl + c 를 누 르 면 직접 복사 할 수 있 습 니 다.
void mainwindow::copy_content()
{
     QClipboard *clipboard=QApplication::clipboard();
     clipboard->setText(qml_selected_text,QClipboard::Clipboard);
}

void mainwindow::load_more_for_chatwidget()
{
   if(last_query_number<5){ //    5 
   QQuickItem *item=ui->quickWidget->rootObject();
   QString current_to_usr_name=ui->listWidget->currentItem()->data(Qt::UserRole+1).toString();
   QString item_type=ui->listWidget->currentItem()->data(Qt::UserRole).toString();
   QString item_mail=ui->listWidget->currentItem()->data(Qt::UserRole+2).toString();
   //      
   QSqlQuery sql_query;
   QString select_his_content;
   if(item_type=="user")
   {
       int last_number=last_query_number*10;
       //limit       ...
       select_his_content="select send_time,send_text from his_tousr "
                          "where tousrmail=:mail "
                          "order by send_time desc "
                          "limit 10 offset :last_number";
       sql_query.prepare(select_his_content);
       sql_query.bindValue(":mail",item_mail);
       sql_query.bindValue(":last_number",last_number);
   }
   else
   {
       if(item_type=="group")
       {
           int last_number=last_query_number*10;
           select_his_content="select send_time,send_text from his_group "
                              "where usrgroupname=:groupname "
                              "order by send_time desc "
                              "limit 10 offset :last_number";
           sql_query.prepare(select_his_content);
           sql_query.bindValue(":groupname",current_to_usr_name);
           sql_query.bindValue(":last_number",last_number);
       }
   }
   if(sql_query.exec())
   {
       while(sql_query.next())
       {
           QString send_time=sql_query.value(0).toString();
           QString his_content=sql_query.value(1).toString();
           //           ,       
           QString yestoday_date=QDateTime::currentDateTime().addDays(-1).toString("yyyyMMdd");
           QString today_date=QDateTime::currentDateTime().toString("yyyyMMdd");
           if(send_time.left(8)==today_date)
           {
               send_time=(send_time.mid(8,2)+":"+send_time.mid(10,2));
           }
           else {
               if(send_time.left(8)==yestoday_date)
               {
                   send_time="   "+send_time.mid(8,2)+":"+send_time.mid(10,2);
               }
               else
               {
                   if(send_time.left(4)==today_date.left(4))
                   {
                       QDateTime send_time1=QDateTime::fromString(send_time,"yyyyMMddhhmmss");
                       send_time=send_time1.toString("M dd  hh:mm");
                   }
                   else
                   {
                       QDateTime send_time1=QDateTime::fromString(send_time,"yyyyMMddhhmmss");
                       send_time=send_time1.toString("yyyy M dd  hh:mm");
                   }
               }
           }
           QVariant returnVar;
           QVariant arg1 = send_time;
           QVariant arg2;
           QVariant arg3 =his_content;
           QVariant arg4 =true;
           QVariant arg5 =false;
           QVariant arg6="no_reedit";
           QVariant arg7=-1;
           if(send_time==lastSend_time)
           {
               arg2= true;
           }
           else
           {
               arg2=false;
               lastSend_time=send_time;
           }
           QMetaObject::invokeMethod(item, "add_more_message",
                                     Q_RETURN_ARG(QVariant, returnVar),Q_ARG(QVariant, arg1),Q_ARG(QVariant, arg2),
                                     Q_ARG(QVariant, arg3),Q_ARG(QVariant, arg4),Q_ARG(QVariant, arg5),
                                     Q_ARG(QVariant, arg6),Q_ARG(QVariant, arg7));
           ui->quickWidget->repaint();
       }
        last_query_number++;
   }
   else{
       qDebug()<<sql_query.lastError();
   }
   } else {
       qDebug()<<"nidaye";
       QQuickItem *item=ui->quickWidget->rootObject();
       QMetaObject::invokeMethod(item,"show_tip");
   }
}

/ / 기록 해 주세요.

좋은 웹페이지 즐겨찾기