三尺非寒 发表于 2024-7-20 06:17:52

qml 实现一个listview

主要通过qml实现listvie功能,主要包括右键菜单,滚动条,拖动改变内容等,c++ 与 qml之间的变量和函数的调用。
main.cpp
#include <QQuickItem>
#include <QQmlContext>
#include "testlistmodel.h"
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    qmlRegisterType<TestListModel>("TestListModel", 1, 0, "TestListModel");
    engine.load(QUrl(QStringLiteral("qrc:/ui1.qml")));
    QObject* root = engine.rootObjects().first();
    QString retVal;
    QVariant message = "Hello from c++";
    QVariant returnedValue;
    QQmlProperty(root,"testmsg").write("hello,world");
    qDebug()<<"Cpp get qml property height222"<<root->property("msg");
    bool ret =QMetaObject::invokeMethod(root,"setSignalB",
                              Q_RETURN_ARG(QVariant,returnedValue),
                              Q_ARG(QVariant,message),
                              Q_ARG(QVariant,8));
    qDebug()<<"returnedValue"<<returnedValue<<root<<ret;
    return app.exec();
} listview 的model 代码
TestListModel.h
#ifndef TESTLISTMODEL_H
#define TESTLISTMODEL_H

#include <QAbstractListModel>
typedef struct Student
{
    int   id;
    QString name;
    QString sex;
}pStudent;

class TestListModel : public QAbstractListModel
{
    Q_OBJECT
public:
    explicit TestListModel(QObject *parent = nullptr);
    int rowCount(const QModelIndex &parent) const;

    QVariant data(const QModelIndex &index, int role) const;
    virtual QHash<int, QByteArray> roleNames() const;
    Qt::ItemFlags flags(const QModelIndex &index) const override;
    Q_INVOKABLE void modifyItemText(int row1,int row2);
    Q_INVOKABLE void add();

    enum MyType{
      ID=Qt::UserRole+1,
      Name,
      Sex
    };
private:
   QVector<Student>m_studentList;

signals:
   void    layoutChanged();
};

#endif // TESTLISTMODEL_H
TestListModel.cpp
#include "testlistmodel.h"
#include <QDebug>

TestListModel::TestListModel(QObject *parent)
    : QAbstractListModel{parent}
{
    for(int i=0;i<20;i++)
    {
      Student oneData;
      oneData.id = i;
      oneData.name= QString("张三%1").arg(i);
      if(i%2==0)
      {
            oneData.sex = "female" ;
      }
      else
      {
            oneData.sex = "male" ;
      }
      //qDebug()<<"TestListModel"<<m_studentList.size();
      m_studentList.append(oneData);
    }   

}

int TestListModel::rowCount(const QModelIndex &parent) const
{
    //qDebug()<<"rowCount"<<m_studentList.size();
    return m_studentList.size();
}
QVariant TestListModel::data(const QModelIndex &index, int role) const
{
   // qDebug()<<"TestListModel::data11111111111"<<index.isValid();

    QVariant var;
    if ( !index.isValid() )
    {
      return QVariant();
    }
    int nRow    = index.row();
    int nColumn = index.column();
    if(Qt::UserRole+1 == role)
    {
      var = QVariant::fromValue(m_studentList.at(nRow).id);
    }
    else if(Qt::UserRole+2 == role)
    {
      var = QVariant::fromValue(m_studentList.at(nRow).name);
      // qDebug()<<"m_listData.at(nRow).name"<<m_listData.at(nRow).name;
    }
    else if(Qt::UserRole+3 == role)
    {
      var = QVariant::fromValue(m_studentList.at(nRow).sex);
      // qDebug()<<"m_listData.at(nRow).name"<<m_listData.at(nRow).name;
    }
    return var;
}

QHash<int, QByteArray> TestListModel::roleNames() const
{
    QHash<int, QByteArray> d;
    d="id";
    d="name";
    d="sex";
    qDebug()<<"d .size"<<d.size();
    return d;
}
Qt::ItemFlags TestListModel::flags(const QModelIndex &index) const
{
    Q_UNUSED(index)
    // if(index.column() ==1)
    // {
    //   qDebug()<<"UserInfoModel::flags1111";
    //   return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
    // }
    qDebug()<<"TestListModel::flags";
    return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
}

void TestListModel::modifyItemText(int row1, int row2)
{
    m_studentList.swapItemsAt(row1,row2);
    beginResetModel();
    endResetModel();
}

void TestListModel::add()
{
    Student student;
    student.id   = 123;
    student.name = "love";
    student.sex= "man";
    m_studentList.push_back(student);
    beginResetModel();
    endResetModel();
    emit layoutChanged();

}
ui.qml
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Layouts 1.2
import TestListModel 1.0


import QtQuick 2.12

import QtQuick 2.2
import QtQml.Models 2.2
//import QtQuick.Controls 2.12
//QtQuick.Controls 2.12和QtQuick.Controls.Styles 1.4不匹配
import QtQuick.Controls.Styles 1.4
import QtQuick.Controls 1.4
import QtQuick.Controls 2.12
import QtLocation 5.15
//import "CustomMenuItem.qml"
// import QtQuick.Controls 2.15

//import QtQuick.Controls 2.5


Window {
    id:window
    //anchors.centerIn: parent
    width: 650;
    height: 457
    visible: true
    flags: Qt.FramelessWindowHint | Qt.Dialog
    property string testmsg: "GongJianBo1992"
    Rectangle{
      id:rect1;
      anchors.fill: parent;
      border.width: 1;
      color: "transparent";
      border.color: "red";
      clip:true//这一属性设置表示如果他的子类超出了范围,那么就剪切掉,不让他显示和起作用
    }
    //无边框移动
    MouseArea {
      id: dragRegion
      anchors.fill: parent
      property point clickPos: "0,0"
      onPressed: {
            clickPos = Qt.point(mouse.x,mouse.y)
      }
      onReleased: {
            clickPos = Qt.point(0,0)
      }
      onPositionChanged: {
            //鼠标偏移量
            var delta = Qt.point(mouse.x-clickPos.x, mouse.y-clickPos.y)
            //如果mainwindow继承自QWidget,用setPos
            window.setX(window.x+delta.x)
            window.setY(window.y+delta.y)
      }
    }
    Menu {
      id: contextMenu
      background: Rectangle {// @disable-check M16
            anchors.fill:parent
            implicitWidth: 200
            implicitHeight: 30
            color: "lightblue"
      }
      Action{
            id:no1
            text:"123"
            onTriggered:
            {
                console.log("选项一被点击")
                tableView.selectAllItem()
            }
            // @disable-check M16
      }
      Menu{
            background: Rectangle {// @disable-check M16
                anchors.fill:parent
                implicitWidth: 200
                implicitHeight: 30
                color: "lightblue"
            }
            title:"love"
            Action{
                id:no4
                text:"789"
                onTriggered:
                {
                  console.log("选项六被点击")
                  tableView.selectAllItem()
                }
            }
      }
      Action {
            id:no2
            text:"234"
            onTriggered:
            {
                console.log("选项二被点击")
                tableView.disselectAllItem()
            }
      }
      MenuSeparator {
            contentItem: Rectangle {// @disable-check M16
                implicitWidth: 200
                implicitHeight: 1
                color: "#21be2b"
            }
      }
      Action {
            id:no3
            text:"345"
            onTriggered: console.log("选项三被点击")
      }
      delegate: MenuItem {// @disable-check M16
            id: menuItem
            height: 40// @disable-check M16
             contentItem: Text{// @disable-check M16
            text:menuItem.text
            color: menuItem.highlighted? "gary": "blue"
            }
            background: Rectangle{// @disable-check M16
                implicitWidth: 200
                implicitHeight: 30
                color: menuItem.highlighted? "purple":"lightblue"
            }
            arrow: Image {// @disable-check M16
                id: arrowImage
                x: parent.width - width
                y: parent.height/2 -height/2
                visible: menuItem.subMenu
                source: "qrc:/Right arrow.png"
            }
      }

    }
   TestListModel{
      id: myMode
      onLayoutChanged:{
         console.log("LayoutChanged")
      }
   }
   // Page{
   //    x:listwidget.x
   //    y:listwidget.y
   //    width:listwidget.width
   //    height: listwidget.height
   //    background: Rectangle{
   //      anchors.fill: parent
   //      color: "white"
   //      border.width: 1
   //      border.color: "black"
   //    }
   // }
   Rectangle{
         width:window.width-60+2
         height: 300+2
         border.color: "lightgreen"
         border.width: 1
         color: "transparent"
         x:30
         y:40
   ListView {
         id: listwidget
         width:parent.width-2//window.width-60
         height: parent.height-2//   300
         x:1
         y:1
         interactive: false // @disable-check M16
         model: myMode
         clip: true//不写的话,滚动的时候,listview会有拖拽的感觉
         //orientation: ListView.Vertical //垂直列表      
         ScrollBar.vertical: ScrollBar {
             id: scrollBar
             hoverEnabled: true
             active: hovered || pressed
             policy: ScrollBar.AlwaysOn
             orientation: Qt.Vertical
             size: 0.8
             anchors.top: parent.top
             anchors.right: parent.right
             anchors.bottom: parent.bottom
             contentItem: Rectangle{
               implicitWidth: 6//没指定的时候的宽度
               implicitHeight: 100 //没有指定高度的时候
               radius: width / 2
               color: scrollBar.pressed ? "#81e889" : "#c2f4c6"

             }
         }
      Rectangle{
             id : dargRect
             width: 100
             height: 30
             visible: false
             color: "lightgray";
             Text {
               anchors.verticalCenter: parent.verticalCenter
               anchors.horizontalCenter: parent.horizontalCenter
               id: dargRectText
               // text: "123"
               horizontalAlignment: Text.AlignHCenter
               verticalAlignment: Text.AlignVCenter
             }
         }
         delegate: Item{
             id:itemDrag1
             width: window.width-60
             height: 30
             property int dragItemIndex: 0
             property bool isHover: false
             Rectangle {
               width: window.width-60
               height: 30
               //radius: 5;
               // border.width: 1
               // border.color: "white"
               color:isHover === true? "lightgreen":listwidget.currentIndex === index ? "lightblue" : "gray"
               Text {
                     id:itemDrag2
                     anchors.verticalCenter: parent.verticalCenter
                     anchors.left: parent.left
                     // text: "123"
                     horizontalAlignment: Text.AlignHCenter
                     verticalAlignment: Text.AlignVCenter
                     text: id+":"+name+":"+sex
               }               
               MouseArea {
                     id: mouseArea
                     anchors.fill: parent
                     acceptedButtons: Qt.LeftButton | Qt.RightButton
                     hoverEnabled: true
                     onWheel: {// @disable-check M16
                         // 当滚轮被滚动时调用
                         // 事件参数wheel提供了滚动的方向和距离
                         if (wheel.angleDelta.y > 0) {
                           //console.log("向上滚动")
                           scrollBar.decrease();
                         }
                         else {
                           //console.log("向下滚动")
                           scrollBar.increase();
                         }
                     }
                     onEntered:
                     {
                         isHover = true
                         //console.log("onEntered" +isHover)
                     }
                     onExited:
                     {
                         isHover = false
                         //console.log("onExited" +isHover)
                     }
                     onClicked:
                     {
                         if (mouse.button === Qt.RightButton)//菜单
                         {
                           console.log("menu RightButton")
                           contextMenu.popup()
                         }
                         else
                         {
                           //var other_index = listwidget.indexAt(mouseArea.mouseX , mouseArea.mouseY );

                           listwidget.currentIndex = index // 点击时设置当前索引为该项的索引值
                           dragItemIndex = index;
                           console.log("onClicked"+index)
                         }
                     }
                     onPressAndHold:{
                         if(mouse.button === Qt.LeftButton)
                         {
                           console.log("onPressAndHold"+index)
                           listwidget.currentIndex = index
                           dargRect.x = mouseX +itemDrag1.x
                           dargRect.y = mouseY+itemDrag1.y
                           dragItemIndex = index;
                           dargRectText.text = itemDrag2.text
                           dargRect.visible = true
                         }
                     }
                     onReleased:{
                        if(dargRect.visible === true)
                        {
                            dargRect.visible = false
                            var other_index = listwidget.indexAt(mouseX +itemDrag1.x , mouseY+itemDrag1.y );
                            console.log("onReleased"+other_index)
                            if(dragItemIndex!==other_index)
                            {
                            var afterItem   = listwidget.itemAtIndex(other_index );
                            // listwidget.myModel.get(other_index).text
                            myModel.modifyItemText(dragItemIndex,other_index)
                            //console.log("onReleased"+myModel)
                            }

                        }
                     }
                     onPositionChanged:{
                         //console.log("onPositionChanged111" + mouse.button)
                         if(mouse.button === Qt.LeftButton)
                         {
                           //console.log("onPositionChanged222")
                           var other_index = listwidget.indexAt(mouseX +itemDrag1.x , mouseY+itemDrag1.y );
                           listwidget.currentIndex= other_index;
                           dargRect.x = mouseX +itemDrag1.x
                           dargRect.y = mouseY+itemDrag1.y
                         }
                     }                     
               }
             }
         }
   }
}
    Button {
      id: button1
      x: parent.width-80
      y: parent.height-36
      width:70
      height:30
      //text: qsTr("Button")
      background:Rectangle // @disable-check M16
      {
            //anchors.fill: parent
            border.color: "royalblue"
            border.width: 1
            color: button1.down ? "red" :(button1.hovered?"blue":"lightsteelblue")
      }
      Text {
            text: "1213";
            // anchors.fill: parent
            anchors.centerIn: parent;
            color: button1.hovered?"yellow":"red";
            font.pixelSize: 13;
            //font.weight: Font.DemiBold
      }      
      Connections {
            target: button1
            function onClicked()
            {
                window.close();
            }
      }
    }
    function myQmlFunction( msg,index) {
            console.log("Got message:", msg)
            return "some return value"
      }
    function setSignalB(name, value){

         console.log("setPoint"+" "+testmsg);
         console.log("qml function processB",name,value);
         myMode.add();
         return value
       }

}
运行结果https://i-blog.csdnimg.cn/direct/85d3309f395e423ca10089a209abaf3f.png

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: qml 实现一个listview