我是QML的新手,我正在评估在我当前的项目中使用它。我有2年前的WPF经验,但我觉得他们的安静不同。
我尝试做的是一个TableView,根据模型,它的列是动态生成的。这部分对我来说没关系,它有效。
第二件事是根据其中的数据类型使用不同的组件作为不同列的委托。我打算使用Checkbox list和ComboBox,为它提供文本字段。一般来说,它按预期工作。
这是3天以来的问题,我发现无法让它工作:我希望动态定义ComoboBox的条目,如果它是ComboBox,我无法绑定该函数模式:(
以下是代码:
TableEditing.qml
import QtQuick 2.4
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
TableView {
Layout.fillWidth: true
id: view
model: myModel
Component {
id: columnComponent
TableViewColumn
{
width: 100
}
}
// <---you can ignore this editableDelegate, it's not relevant to this question
Component {
id: editableDelegate
Item {
Text {
width: parent.width
anchors.margins: 4
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
elide: styleData.elideMode
text: styleData.value !== undefined ? styleData.value : ""
color: styleData.textColor
visible: !styleData.selected
}
Loader {
id: loaderEditor
anchors.fill: parent
anchors.margins: 4
Connections {
target: loaderEditor.item
onAccepted: {
if (typeof styleData.value === 'number')
largeModel.setProperty(styleData.row, styleData.role, Number(parseFloat(loaderEditor.item.text).toFixed(0)))
else
largeModel.setProperty(styleData.row, styleData.role, loaderEditor.item.text)
}
}
sourceComponent: styleData.selected ? editor : null
Component {
id: editor
TextInput {
id: textinput
color: styleData.textColor
text: styleData.value
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: textinput.forceActiveFocus()
}
}
}
}
}
}
// Read from here will be better
Component {
id: editableCombo
Item {
property var modelData : ["aa", "bb"] // <- This works
ComboBox {
id : combox
anchors.verticalCenter: parent.verticalCenter
}
Binding {
target: combox
property: "model"
value: modelData
}
}
}
function getEditor(type, options) {
switch(type) {
case 3: return editableCombo
default: return editableDelegate;
}
}
function addCol(role, index) {
var colType = myModel.columnType(index);
var colOptions = myModel.optionList(index);
var editor = getEditor(colType, colOptions);
var cellEditor = {
role: role,
title: role,
delegate: editor \\ <--------- I think here need some work, I think I need to bind colOptions to the modelData of editor, but I have tried many forms, the loader and bindings, it doesn't work
};
view.addColumn(columnComponent.createObject(view, cellEditor))
}
Connections {
target: myModel
onHeaderDataChanged: myModel.columnNames.forEach(addCol)
}
}
这是模型的标题,columnType()给出了列中的数据类型,optionList()给出了可能的条目。
#pragma once
#include "ItemControllerBase.h"
#include "ItemPropertyDescriptor.h"
#include "Macro.h"
#include "Const.h"
namespace PROJECTNAME { namespace Controller {
class TableEditingModel : public QAbstractItemModel {
Q_OBJECT
Q_PROPERTY(QStringList columnNames READ columnNames CONSTANT)
public:
TableEditingModel() = default;
//! \brief Déstructeur.
~TableEditingModel();
Q_INVOKABLE int columnType(int columnIndex) const;
Q_INVOKABLE QStringList optionList(int columnIndex) const;
QStringList columnNames() const;
QHash<int, QByteArray> roleNames() const override;
//! \brief L'index dans QListView.
//! \param row La ligne.
//! \param column Le column.
//! \return Un QModelIndex.
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
//! \brief Obtiens le parent.
//! \param child Le fils.
//! \return L'index de parent.
QModelIndex parent(const QModelIndex &) const override
{
return QModelIndex();
}
//! \brief Le numbre totale des lignes.
//! \param parent Le parent.
//! \return Le nombre totale des lignes.
int rowCount(const QModelIndex & = QModelIndex()) const override
{
//! \todo
return m_controllers.size();
}
//! \brief Le nombre totales des column.
//! \param parent (Optional) Le parent.
//! \return Le nombre totales des column.
int columnCount(const QModelIndex & = QModelIndex()) const override
{
return m_controllers.size() > 0 ? m_controllers[0]->descriptor()->size() : 0;
}
//! \brief Données d'un celule.
//! \param index L'objet index.
//! \param role Le rôle.
//! \return La données.
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
//! \brief Mise à jour de données.
//! \param index L'index.
//! \param value La valeur.
//! \return Vrai si la modification est réussit
bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override;
//! \brief Renvoie le numéro de ligne d'un élément.
//! \param element Elément recherché
//! \return Numéro de ligne de l'élément recherché
int indexOf(QSharedPointer<Controller::ItemControllerBase> element) { return m_controllers.indexOf(element); }
//! \brief Lors l'ajoute d'une élément.
//! \param [in,out] descriptor Le déscripteur d'élément.
void addElement(QSharedPointer<Controller::ItemControllerBase> element);
//! \brief Lors la suppression d'une élément.
//! \param [in,out] descriptor Le déscripteur d'élément
void removeElement(QSharedPointer<Controller::ItemControllerBase> element);
void refreshElement(QSharedPointer<Controller::ItemControllerBase> element);
private:
QueryableVector<QSharedPointer<Controller::ItemControllerBase>> m_controllers; //!< Liste des controlleurs
QueryableVector<std::tuple<QString, Model::PropertyValueType, QStringList>> m_horizontalHeaders; //!< Liste des titres de colonne };
} // Controller } // PROJECTNAME