ToB企服应用市场:ToB评测及商务社交产业平台

标题: qml 实现一个listview [打印本页]

作者: 三尺非寒    时间: 2024-7-20 06:17
标题: qml 实现一个listview
主要通过qml实现listvie功能,主要包括右键菜单,滚动条,拖动改变内容等,c++ 与 qml之间的变量和函数的调用。
main.cpp
  1. #include <QQuickItem>
  2. #include <QQmlContext>
  3. #include "testlistmodel.h"
  4. int main(int argc, char *argv[])
  5. {
  6.     QGuiApplication app(argc, argv);
  7.     QQmlApplicationEngine engine;
  8.     qmlRegisterType<TestListModel>("TestListModel", 1, 0, "TestListModel");
  9.     engine.load(QUrl(QStringLiteral("qrc:/ui1.qml")));
  10.     QObject* root = engine.rootObjects().first();
  11.     QString retVal;
  12.     QVariant message = "Hello from c++";
  13.     QVariant returnedValue;
  14.     QQmlProperty(root,"testmsg").write("hello,world");
  15.     qDebug()<<"Cpp get qml property height222"<<root->property("msg");
  16.     bool ret =QMetaObject::invokeMethod(root,"setSignalB",
  17.                               Q_RETURN_ARG(QVariant,returnedValue),
  18.                               Q_ARG(QVariant,message),
  19.                               Q_ARG(QVariant,8));
  20.     qDebug()<<"returnedValue"<<returnedValue<<root<<ret;
  21.     return app.exec();
  22. }
复制代码
listview 的model 代码
TestListModel.h
  1. #ifndef TESTLISTMODEL_H
  2. #define TESTLISTMODEL_H
  3. #include <QAbstractListModel>
  4. typedef struct Student
  5. {
  6.     int     id;
  7.     QString name;
  8.     QString sex;
  9. }pStudent;
  10. class TestListModel : public QAbstractListModel
  11. {
  12.     Q_OBJECT
  13. public:
  14.     explicit TestListModel(QObject *parent = nullptr);
  15.     int rowCount(const QModelIndex &parent) const;
  16.     QVariant data(const QModelIndex &index, int role) const;
  17.     virtual QHash<int, QByteArray> roleNames() const;
  18.     Qt::ItemFlags flags(const QModelIndex &index) const override;
  19.     Q_INVOKABLE void modifyItemText(int row1,int row2);
  20.     Q_INVOKABLE void add();
  21.     enum MyType{
  22.         ID=Qt::UserRole+1,
  23.         Name,
  24.         Sex
  25.     };
  26. private:
  27.      QVector<Student>  m_studentList;
  28. signals:
  29.      void    layoutChanged();
  30. };
  31. #endif // TESTLISTMODEL_H
复制代码
TestListModel.cpp
  1. #include "testlistmodel.h"
  2. #include <QDebug>
  3. TestListModel::TestListModel(QObject *parent)
  4.     : QAbstractListModel{parent}
  5. {
  6.     for(int i=0;i<20;i++)
  7.     {
  8.         Student oneData;
  9.         oneData.id = i;
  10.         oneData.name  = QString("张三%1").arg(i);
  11.         if(i%2==0)
  12.         {
  13.             oneData.sex = "female" ;
  14.         }
  15.         else
  16.         {
  17.             oneData.sex = "male" ;
  18.         }
  19.         //qDebug()<<"TestListModel"<<m_studentList.size();
  20.         m_studentList.append(oneData);
  21.     }   
  22. }
  23. int TestListModel::rowCount(const QModelIndex &parent) const
  24. {
  25.     //qDebug()<<"rowCount"<<m_studentList.size();
  26.     return m_studentList.size();
  27. }
  28. QVariant TestListModel::data(const QModelIndex &index, int role) const
  29. {
  30.    // qDebug()<<"TestListModel::data11111111111"<<index.isValid();
  31.     QVariant var;
  32.     if ( !index.isValid() )
  33.     {
  34.         return QVariant();
  35.     }
  36.     int nRow    = index.row();
  37.     int nColumn = index.column();
  38.     if(Qt::UserRole+1 == role)
  39.     {
  40.         var = QVariant::fromValue(m_studentList.at(nRow).id);
  41.     }
  42.     else if(Qt::UserRole+2 == role)
  43.     {
  44.         var = QVariant::fromValue(m_studentList.at(nRow).name);
  45.         // qDebug()<<"m_listData.at(nRow).name"<<m_listData.at(nRow).name;
  46.     }
  47.     else if(Qt::UserRole+3 == role)
  48.     {
  49.         var = QVariant::fromValue(m_studentList.at(nRow).sex);
  50.         // qDebug()<<"m_listData.at(nRow).name"<<m_listData.at(nRow).name;
  51.     }
  52.     return var;
  53. }
  54. QHash<int, QByteArray> TestListModel::roleNames() const
  55. {
  56.     QHash<int, QByteArray> d;
  57.     d[MyType::ID]="id";
  58.     d[MyType::Name]="name";
  59.     d[MyType::Sex]="sex";
  60.     qDebug()<<"d .size"<<d.size();
  61.     return d;
  62. }
  63. Qt::ItemFlags TestListModel::flags(const QModelIndex &index) const
  64. {
  65.     Q_UNUSED(index)
  66.     // if(index.column() ==1)
  67.     // {
  68.     //     qDebug()<<"UserInfoModel::flags  1111";
  69.     //     return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
  70.     // }
  71.     qDebug()<<"TestListModel::flags";
  72.     return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
  73. }
  74. void TestListModel::modifyItemText(int row1, int row2)
  75. {
  76.     m_studentList.swapItemsAt(row1,row2);
  77.     beginResetModel();
  78.     endResetModel();
  79. }
  80. void TestListModel::add()
  81. {
  82.     Student student;
  83.     student.id   = 123;
  84.     student.name = "love";
  85.     student.sex  = "man";
  86.     m_studentList.push_back(student);
  87.     beginResetModel();
  88.     endResetModel();
  89.     emit layoutChanged();
  90. }
复制代码
ui.qml
  1. import QtQuick 2.6
  2. import QtQuick.Window 2.2
  3. import QtQuick.Layouts 1.2
  4. import TestListModel 1.0
  5. import QtQuick 2.12
  6. import QtQuick 2.2
  7. import QtQml.Models 2.2
  8. //import QtQuick.Controls 2.12
  9. //QtQuick.Controls 2.12  和QtQuick.Controls.Styles 1.4不匹配
  10. import QtQuick.Controls.Styles 1.4
  11. import QtQuick.Controls 1.4
  12. import QtQuick.Controls 2.12
  13. import QtLocation 5.15
  14. //import "CustomMenuItem.qml"
  15. // import QtQuick.Controls 2.15
  16. //import QtQuick.Controls 2.5
  17. Window {
  18.     id:window
  19.     //anchors.centerIn: parent
  20.     width: 650;
  21.     height: 457
  22.     visible: true
  23.     flags: Qt.FramelessWindowHint | Qt.Dialog
  24.     property string testmsg: "GongJianBo1992"
  25.     Rectangle{
  26.         id:rect1;
  27.         anchors.fill: parent;
  28.         border.width: 1;
  29.         color: "transparent";
  30.         border.color: "red";
  31.         clip:true//这一属性设置表示如果他的子类超出了范围,那么就剪切掉,不让他显示和起作用
  32.     }
  33.     //无边框移动
  34.     MouseArea {
  35.         id: dragRegion
  36.         anchors.fill: parent
  37.         property point clickPos: "0,0"
  38.         onPressed: {
  39.             clickPos = Qt.point(mouse.x,mouse.y)
  40.         }
  41.         onReleased: {
  42.             clickPos = Qt.point(0,0)
  43.         }
  44.         onPositionChanged: {
  45.             //鼠标偏移量
  46.             var delta = Qt.point(mouse.x-clickPos.x, mouse.y-clickPos.y)
  47.             //如果mainwindow继承自QWidget,用setPos
  48.             window.setX(window.x+delta.x)
  49.             window.setY(window.y+delta.y)
  50.         }
  51.     }
  52.     Menu {
  53.         id: contextMenu
  54.         background: Rectangle {// @disable-check M16
  55.             anchors.fill:parent
  56.             implicitWidth: 200
  57.             implicitHeight: 30
  58.             color: "lightblue"
  59.         }
  60.         Action{
  61.             id:no1
  62.             text:"123"
  63.             onTriggered:
  64.             {
  65.                 console.log("选项一被点击")
  66.                 tableView.selectAllItem()
  67.             }
  68.             // @disable-check M16
  69.         }
  70.         Menu{
  71.             background: Rectangle {// @disable-check M16
  72.                 anchors.fill:parent
  73.                 implicitWidth: 200
  74.                 implicitHeight: 30
  75.                 color: "lightblue"
  76.             }
  77.             title:"love"
  78.             Action{
  79.                 id:no4
  80.                 text:"789"
  81.                 onTriggered:
  82.                 {
  83.                     console.log("选项六被点击")
  84.                     tableView.selectAllItem()
  85.                 }
  86.             }
  87.         }
  88.         Action {
  89.             id:no2
  90.             text:"234"
  91.             onTriggered:
  92.             {
  93.                 console.log("选项二被点击")
  94.                 tableView.disselectAllItem()
  95.             }
  96.         }
  97.         MenuSeparator {
  98.             contentItem: Rectangle {// @disable-check M16
  99.                 implicitWidth: 200
  100.                 implicitHeight: 1
  101.                 color: "#21be2b"
  102.             }
  103.         }
  104.         Action {
  105.             id:no3
  106.             text:"345"
  107.             onTriggered: console.log("选项三被点击")
  108.         }
  109.         delegate: MenuItem {// @disable-check M16
  110.             id: menuItem
  111.             height: 40// @disable-check M16
  112.              contentItem: Text{// @disable-check M16
  113.               text:menuItem.text
  114.               color: menuItem.highlighted? "gary": "blue"
  115.             }
  116.             background: Rectangle{// @disable-check M16
  117.                 implicitWidth: 200
  118.                 implicitHeight: 30
  119.                 color: menuItem.highlighted? "purple":"lightblue"
  120.             }
  121.             arrow: Image {// @disable-check M16
  122.                 id: arrowImage
  123.                 x: parent.width - width
  124.                 y: parent.height/2 -height/2
  125.                 visible: menuItem.subMenu
  126.                 source: "qrc:/Right arrow.png"
  127.             }
  128.         }
  129.     }
  130.      TestListModel{
  131.         id: myMode
  132.         onLayoutChanged:{
  133.            console.log("LayoutChanged")
  134.         }
  135.      }
  136.      // Page{
  137.      //    x:listwidget.x
  138.      //    y:listwidget.y
  139.      //    width:  listwidget.width
  140.      //    height: listwidget.height
  141.      //    background: Rectangle{
  142.      //        anchors.fill: parent
  143.      //        color: "white"
  144.      //        border.width: 1
  145.      //        border.color: "black"
  146.      //    }
  147.      // }
  148.      Rectangle{
  149.          width:  window.width-60+2
  150.          height: 300+2
  151.          border.color: "lightgreen"
  152.          border.width: 1
  153.          color: "transparent"
  154.          x:30
  155.          y:40
  156.      ListView {
  157.          id: listwidget
  158.          width:  parent.width-2//window.width-60
  159.          height: parent.height-2//   300
  160.          x:1
  161.          y:1
  162.          interactive: false // @disable-check M16
  163.          model: myMode
  164.          clip: true  //不写的话,滚动的时候,listview会有拖拽的感觉
  165.          //orientation: ListView.Vertical //垂直列表        
  166.          ScrollBar.vertical: ScrollBar {
  167.              id: scrollBar
  168.              hoverEnabled: true
  169.              active: hovered || pressed
  170.              policy: ScrollBar.AlwaysOn
  171.              orientation: Qt.Vertical
  172.              size: 0.8
  173.              anchors.top: parent.top
  174.              anchors.right: parent.right
  175.              anchors.bottom: parent.bottom
  176.              contentItem: Rectangle  {
  177.                  implicitWidth: 6  //没指定的时候的宽度
  178.                  implicitHeight: 100 //没有指定高度的时候
  179.                  radius: width / 2
  180.                  color: scrollBar.pressed ? "#81e889" : "#c2f4c6"
  181.              }
  182.          }
  183.         Rectangle{
  184.              id : dargRect
  185.              width: 100
  186.              height: 30
  187.              visible: false
  188.              color: "lightgray";
  189.              Text {
  190.                  anchors.verticalCenter: parent.verticalCenter
  191.                  anchors.horizontalCenter: parent.horizontalCenter
  192.                  id: dargRectText
  193.                  // text: "123"
  194.                  horizontalAlignment: Text.AlignHCenter
  195.                  verticalAlignment: Text.AlignVCenter
  196.              }
  197.          }
  198.          delegate: Item{
  199.              id:itemDrag1
  200.              width: window.width-60
  201.              height: 30
  202.              property int dragItemIndex: 0
  203.              property bool isHover: false
  204.              Rectangle {
  205.                  width: window.width-60
  206.                  height: 30
  207.                  //radius: 5;
  208.                  // border.width: 1
  209.                  // border.color: "white"
  210.                  color:isHover === true? "lightgreen":listwidget.currentIndex === index ? "lightblue" : "gray"
  211.                  Text {
  212.                      id:itemDrag2
  213.                      anchors.verticalCenter: parent.verticalCenter
  214.                      anchors.left: parent.left
  215.                      // text: "123"
  216.                      horizontalAlignment: Text.AlignHCenter
  217.                      verticalAlignment: Text.AlignVCenter
  218.                      text: id+":"+name+":"+sex
  219.                  }               
  220.                  MouseArea {
  221.                      id: mouseArea
  222.                      anchors.fill: parent
  223.                      acceptedButtons: Qt.LeftButton | Qt.RightButton
  224.                      hoverEnabled: true
  225.                      onWheel: {// @disable-check M16
  226.                          // 当滚轮被滚动时调用
  227.                          // 事件参数wheel提供了滚动的方向和距离
  228.                          if (wheel.angleDelta.y > 0) {
  229.                              //console.log("向上滚动")
  230.                              scrollBar.decrease();
  231.                          }
  232.                          else {
  233.                              //console.log("向下滚动")
  234.                              scrollBar.increase();
  235.                          }
  236.                      }
  237.                      onEntered:
  238.                      {
  239.                          isHover = true
  240.                          //console.log("onEntered" +isHover)
  241.                      }
  242.                      onExited:
  243.                      {
  244.                          isHover = false
  245.                          //console.log("onExited" +isHover)
  246.                      }
  247.                      onClicked:
  248.                      {
  249.                          if (mouse.button === Qt.RightButton)//菜单
  250.                          {
  251.                              console.log("menu RightButton")
  252.                              contextMenu.popup()
  253.                          }
  254.                          else
  255.                          {
  256.                              //var other_index = listwidget.indexAt(mouseArea.mouseX , mouseArea.mouseY );
  257.                              listwidget.currentIndex = index // 点击时设置当前索引为该项的索引值
  258.                              dragItemIndex = index;
  259.                              console.log("onClicked"+index)
  260.                          }
  261.                      }
  262.                      onPressAndHold:  {
  263.                          if(mouse.button === Qt.LeftButton)
  264.                          {
  265.                              console.log("onPressAndHold"+index)
  266.                              listwidget.currentIndex = index
  267.                              dargRect.x = mouseX +itemDrag1.x
  268.                              dargRect.y = mouseY+itemDrag1.y
  269.                              dragItemIndex = index;
  270.                              dargRectText.text = itemDrag2.text
  271.                              dargRect.visible = true
  272.                          }
  273.                      }
  274.                      onReleased:{
  275.                         if(dargRect.visible === true)
  276.                         {
  277.                             dargRect.visible = false
  278.                             var other_index = listwidget.indexAt(mouseX +itemDrag1.x , mouseY+itemDrag1.y );
  279.                             console.log("onReleased"+other_index)
  280.                             if(dragItemIndex!==other_index)
  281.                             {
  282.                             var afterItem   = listwidget.itemAtIndex(other_index );
  283.                             // listwidget.myModel.get(other_index).text
  284.                             myModel.modifyItemText(dragItemIndex,other_index)
  285.                             //console.log("onReleased"+myModel)
  286.                             }
  287.                         }
  288.                      }
  289.                      onPositionChanged:{
  290.                          //console.log("onPositionChanged111" + mouse.button)
  291.                          if(mouse.button === Qt.LeftButton)
  292.                          {
  293.                              //console.log("onPositionChanged222")
  294.                              var other_index = listwidget.indexAt(mouseX +itemDrag1.x , mouseY+itemDrag1.y );
  295.                              listwidget.currentIndex  = other_index;
  296.                              dargRect.x = mouseX +itemDrag1.x
  297.                              dargRect.y = mouseY+itemDrag1.y
  298.                          }
  299.                      }                     
  300.                  }
  301.              }
  302.          }
  303.      }
  304. }
  305.     Button {
  306.         id: button1
  307.         x: parent.width-80
  308.         y: parent.height-36
  309.         width:70
  310.         height:30
  311.         //text: qsTr("Button")
  312.         background:Rectangle // @disable-check M16
  313.         {
  314.             //anchors.fill: parent
  315.             border.color: "royalblue"
  316.             border.width: 1
  317.             color: button1.down ? "red" :(button1.hovered?"blue":"lightsteelblue")
  318.         }
  319.         Text {
  320.             text: "1213";
  321.             // anchors.fill: parent
  322.             anchors.centerIn: parent;
  323.             color: button1.hovered?"yellow":"red";
  324.             font.pixelSize: 13;
  325.             //font.weight: Font.DemiBold
  326.         }      
  327.         Connections {
  328.             target: button1
  329.             function onClicked()
  330.             {
  331.                 window.close();
  332.             }
  333.         }
  334.     }
  335.     function myQmlFunction( msg,index) {
  336.             console.log("Got message:", msg)
  337.             return "some return value"
  338.         }
  339.     function setSignalB(name, value){
  340.            console.log("setPoint"+" "+testmsg);
  341.            console.log("qml function processB",name,value);
  342.            myMode.add();
  343.            return value
  344.        }
  345. }
复制代码
运行结果


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




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4