Qt-可編輯的ListView


新建一個QML項目, main.cpp不動如下:

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
        &app, [url](QObject *obj, const QUrl &objUrl) {
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

主界面main.qml如下

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")


    DemoList {
        anchors.centerIn: parent
        width: parent.width
        height: parent.height
    }

}

用到的Model文件 MyModel.qml 如下:

import QtQuick 2.0

ListModel {
    ListElement {
        description: "Wash the car"
        done: true
    }
    ListElement {
        description: "Read a book"
        done: false
    }

    ListElement {
        description: "Buy a cup"
        done: false
    }

}

主要界面 DemoList.qml :

import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
import QtQml.Models 2.1


/**
  方法2: 通過設置currentIndex, 屬性自動變化. 支持鍵盤
*/
ColumnLayout {

    RowLayout {

        Layout.fillHeight: true

        Layout.leftMargin: 10
        Layout.rightMargin: 20
        Layout.alignment: Qt.AlignHCenter | Qt.AlignTop

        Component {
            id: delegateItem

            Rectangle {
                id: dragRect
                height: 50
                width: parent.width

                onFocusChanged: {
                    if(focus){
                        console.debug("got focus dragRect" );
                        textinput.focus = true;
                    }
                }

                CheckBox {
                    id: chkbox
                    width: 50
                    checked: model.done
                    onClicked: model.done = checked
                }


                Rectangle {
                    id: textSection
                    height: parent.height

                    width: parent.width - chkbox.width
                    anchors.left: chkbox.right

                    Text {
                        id: textShow

                        text: model.description
                        font.underline: true
                        font.bold: true
                        anchors.verticalCenter: parent.verticalCenter

                        visible: !dragRect.ListView.isCurrentItem
                        color: "black"


                    } //end textShow


                    TextInput {
                        id: textinput

                        anchors.verticalCenter: parent.verticalCenter

                        color: "blue"

                        text:  model.description
                        visible: dragRect.ListView.isCurrentItem
                        enabled: dragRect.ListView.isCurrentItem
                        focus: true

                        onFocusChanged: {
                            if(focus){
                                console.debug("got focus" + "textInput");
                            }
                        }

                        onEditingFinished: {
                            model.description = textinput.text

                            //方法1: 設置index
                            if(listView.currentIndex == index){
                                listView.currentIndex = -1;
                            }


                            console.log(("TextInput listview currentIndex: " + listView.currentIndex +  " index: " + index ))
                            console.log(("TextInput ListView isCurrentItem: " + dragRect.ListView.isCurrentItem))

                        }

                    } //end TextInput

                } //end textSection Rectangle

                MouseArea {
                    id: mouseArea
                    width: parent.width
                    height: parent.height
                    hoverEnabled: true

                    z: -1 //避免遮住checkbox

                    onClicked: {
                        //方法1: 設置當前
                        listView.currentIndex = index

                        console.log(("MouseArea listview currentIndex: " + listView.currentIndex +  " index: " + index ))
                        console.log(("MouseArea ListView isCurrentItem: " + dragRect.ListView.isCurrentItem))

                        // 在dragRect的 onFocusChanged 中設置了, 此處不需要了
                        //textinput.focus = true;
                    }
                }


            }
        } //end Row Rectangle

        ListView {
            id: listView
            Layout.fillWidth: true
            Layout.fillHeight: true
            keyNavigationEnabled: true

            //clip: true
            model: MyModel {}
            delegate: delegateItem

            //默認不要是第一個, 否則第一個是可編輯狀態(針對方法1)
            Component.onCompleted : {
                currentIndex = -1;
            }

            //默認焦點
            focus: true
        }
    }

    RowLayout {
        Button {
            text: qsTr("Add New Item")
            Layout.fillWidth: true

            onClicked: {
                var c = listView.model.rowCount();
                listView.model.append({
                                          "description": "Buy a new book " + (c + 1),
                                          "done": false
                                      })

                //設置焦點, 否則listView就沒焦點了
                listView.focus = true;
                listView.currentIndex = c;
            }
        }
    }
}

幾個關鍵點, 詳見代碼:

  • Text/TextInput的visible屬性
  • MouseArea的點擊事件: 設置 listView.currentIndex = index
  • MouseArea避免遮擋: z: -1 //避免遮住checkbox
  • ListView的 Component.onCompleted, 設置默認不選中
  • ListView默認設置: focus: true
  • TextInput的onEditingFinished, 處理編輯完成事件
  • 組件dragRect的onFocusChanged, 使TextInput獲得焦點

項目代碼

https://github.com/cnscud/learn/tree/master/qt/editListView


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM