problem of CheckBox in ListView
Unsolved
QML and Qt Quick
-
I am writing a simple file manager. I want to realize multi-select.
Suppose that there is three files a,b,c in current path. If I check file a, a selection menu will apper.
Then I uncheck file a, and choose "Select All". file b and c will be checked as expected,but file a not.
What is the problem?
Here is my code:#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QtQml> #include <QQmlContext> #include "mainclass.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; qmlRegisterType<MainClass>("per.pqy.mc", 1, 0, "MainClass"); engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); return app.exec(); }
#ifndef MAINCLASS_H #define MAINCLASS_H #include <QObject> #include <QDir> #include <QFile> class MyModelItem :public QObject { Q_OBJECT Q_PROPERTY(QString name READ name CONSTANT) Q_PROPERTY(bool checked READ checked WRITE setChecked NOTIFY checkedChanged) public: MyModelItem(const QString &name, QObject *parent=0):_name(name), _checked(false){} QString name() const{ return _name; } bool checked() const {return _checked; } signals: void checkedChanged(); public slots: void setChecked(bool c){ _checked = c; emit checkedChanged();} private: QString _name, _info; bool _checked; }; class MainClass : public QObject { Q_OBJECT Q_PROPERTY(QString currentPath READ currentPath CONSTANT) Q_PROPERTY(QList<QObject*> myModel READ myModel NOTIFY myModelChanged) public: explicit MainClass(QObject *parent = 0, QString root = "/"); QString currentPath(){return _currentPath;} QStringList filesInfoList(); QList<QObject*> myModel(){ return fList; } inline QDir::Filters currentFilter(){ if(QDir(_currentPath).isRoot()) return QDir::NoDotAndDotDot|QDir::AllEntries; else return QDir::NoDot|QDir::AllEntries; } signals: void myModelChanged(); void clickFile(QString type); public slots: void setCurrentPath(int index); void selectAll(); void reverseSelect(); private: QString _currentPath; QList<QObject*> fList; }; #endif // MAINCLASS_H
#include "mainclass.h" MainClass::MainClass(QObject *parent,QString root) : QObject(parent),_currentPath(root) { QStringList currentFilesList = QDir(_currentPath).entryList(currentFilter(),QDir::DirsFirst); for(int i=0;i<currentFilesList.count();i++) fList.append(new MyModelItem(currentFilesList[i])); emit myModelChanged(); } void MainClass::setCurrentPath(int index) { QStringList currentFilesList = QDir(_currentPath).entryList(currentFilter(),QDir::DirsFirst); QFileInfo finfo(_currentPath,currentFilesList[index]); QString cp = _currentPath; if(!finfo.isReadable()){ //todo } else if(finfo.isDir()&&finfo.isExecutable()){ cp += "/"; cp += currentFilesList[index]; _currentPath = QDir(cp).absolutePath(); _currentPath = QDir(_currentPath).path(); currentFilesList = QDir(_currentPath).entryList(currentFilter(),QDir::DirsFirst); qDeleteAll(fList); fList.clear(); for(int i=0;i<currentFilesList.count();i++) fList.append(new MyModelItem(currentFilesList[i])); emit myModelChanged(); } else if(finfo.isFile()){ if(finfo.suffix()=="apk") emit clickFile("ApkMenu.qml"); else emit clickFile("NormalMenu.qml"); } } void MainClass::selectAll() { for(int i=0;i<fList.count();i++){ MyModelItem *item = qobject_cast<MyModelItem *>(fList[i]); item->setChecked(true); } } void MainClass::reverseSelect() { for(int i=0;i<fList.count();i++){ MyModelItem *item = qobject_cast<MyModelItem *>(fList[i]); item->setChecked(!item->checked()); } }
import QtQuick 2.5 import QtQuick.Controls 1.4 import per.pqy.mc 1.0 ApplicationWindow { visible: true width: 480 height: 800 title: qsTr("Hello World") function showselectMenu(){ selectMenu.y = 0; } function hideselectMenu(){ selectMenu.y = -selectMenu.height; } MainClass { id:mc } Rectangle { id: root anchors.fill: parent color: "#000000" ListView { id: list anchors.fill: parent flickDeceleration: 3000 maximumFlickVelocity: 8000 spacing: 1 clip: true model:mc.myModel delegate: Rectangle { id: listItem height: root.height/15 width: root.width property alias checked: checkItem.checked MouseArea { id:mouseArea anchors.fill: parent onClicked: mc.setCurrentPath(index) } color: mouseArea.pressed?"#ff999999":"#aa505050" CheckBox { id: checkItem anchors.right: parent.right anchors.top: parent.top anchors.bottom: parent.bottom anchors.margins: root.height/150 width: height checked: model.modelData.checked onClicked: { model.modelData.setChecked(checked); showselectMenu(); } } Text { id: t1 text: model.modelData.name color: "white" height: parent.height*2/3 font.pixelSize: height*4/7 anchors.left: parent.left } } } } Rectangle { id: selectMenu width: root.width/2 height: root.height/5+2 anchors.horizontalCenter: parent.horizontalCenter opacity: 0.8 y: -height Behavior on y { NumberAnimation { duration: 500 easing.type: Easing.OutExpo } } Column { anchors.fill: parent spacing: 1 property real btnWid: parent.width property real btnHei: (parent.height-2)/3 Button { id: button1 text: qsTr("Select All") width: parent.btnWid height: parent.btnHei onClicked: mc.selectAll() } Button { id: button2 text: qsTr("Reverse Selection") width: parent.btnWid height: parent.btnHei onClicked: mc.reverseSelect() } Button { id: button3 text: qsTr("Done Selection") width: parent.btnWid height: parent.btnHei onClicked: hideselectMenu() } } } }