问题描述
我一直在尝试使用QML TableView
来显示 QAbstractTableModel
。等式中缺少的部分似乎是,尽管重写了 QAbstractItemModel :: roleNames,但
应该告诉Qt我的列的数量和名称。我尝试仅使用QML进行测试: TableView
中不可能有可变的列数
I have been trying to use a QML TableView
to display a QAbstractTableModel
. The missing part of the equation seems to be that it is not possible to have a variable number of columns in the TableView
, despite overriding QAbstractItemModel::roleNames
which should tell Qt the number and name of my columns. I tried testing this out using only QML:
import QtQuick 2.0
import QtQuick.Controls 1.1
Rectangle {
anchors.fill: parent
property real showImage: 1.0
width: 500
TableView {
id: myTable
model: myModel
// TableViewColumn {
// role: "title"; title: "Name"; width: 200
// }
}
ListModel {
id: myModel
ListElement {
title: "item one"
}
ListElement {
title: "item two"
}
}
}
运行时,尽管 TableView
的模式包含 s
When run this doesn't show anything despite the TableView
's mode containing ListElement
s with roles defined in them.
但是,如果上面的代码没有注释,并且定义了 TableViewColumn
,则该列将显示该角色符合预期,但该表仍不会显示任何其他角色。显然,这仅适用于静态定义的列数,不适用于直到运行时才知道列数的情况。
However if the above code is uncommented and a TableViewColumn
is defined then the column will display data for that role as expected but the table will still not display any other roles. Obviously that will only work for a statically defined number of columns and not my case where the number of columns is not known until run time.
给出的示例基本相同作为我的现实生活示例,除了我的模型是用C ++定义的。
The example given is basically the same as my real life example except that my model is defined in C++.
似乎这已经被问过了,但未获得任何响应。
It seems as if this may have already been asked here but it did not gain any response.
编辑: 我曾尝试调用JavaScript函数:
I had tried calling a javascript function:
function addColumnToTable(roleName) {
var columnString = 'import QtQuick 2.3; import QtQuick.Controls 1.2; TableViewColumn {role: "'
+ roleName + '"; title: "' + roleName + '"; width: 40}';
var column = Qt.createQmlObject(
columnString
, myTable
, "dynamicSnippet1")
myTable.addColumn(column);
}
来自C ++:
QVariant roleName = "name";
QObject *root = view->rootObject();
QMetaObject::invokeMethod(root, "addColumnToTable", Q_ARG(QVariant, roleName));
这至少允许我从C ++动态添加列,尽管不是从模型/视图架构中添加。 Yoann的解决方案远比这更好。
This at least allowed me to dynamically add columns from C++ although not from within the model/view architecture. Yoann's solution is far and away better than this though.
推荐答案
您可以动态创建尽可能多的 TableViewColumn
,根据需要,使用 TableView
的资源
属性。
You could create dynamically as many TableViewColumn
as you need, using the resources
property of your TableView
.
您将必须在自定义模型类中添加一个方法,该方法将为您提供要显示的roleNames。
You will have to add a method in your custom model class which will give you the roleNames you want to display.
QML:
Component
{
id: columnComponent
TableViewColumn{width: 100 }
}
TableView {
id: view
anchors.fill: parent
resources:
{
var roleList = myModel.customRoleNames
var temp = []
for(var i=0; i<roleList.length; i++)
{
var role = roleList[i]
temp.push(columnComponent.createObject(view, { "role": role, "title": role}))
}
return temp
}
model: myModel
MyModel.h:
class MyModel: public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(QStringList userRoleNames READ userRoleNames CONSTANT)
public:
explicit MyModel(QObject *parent = 0);
enum MyModelRoles {
UserRole1 = Qt::UserRole + 1,
UserRole2,
...
};
QStringList userRoleNames();
int rowCount(const QModelIndex & parent = QModelIndex()) const;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
...
private:
QHash<int, QByteArray> roleNames() const;
...
};
MyModel.cpp:
...
...
QHash<int, QByteArray> MyModel::roleNames() const {
QHash<int, QByteArray> roles = QAbstractListModel::roleNames ();
roles[UserRole1] = "whatever";
roles[UserRole2] = "youwant";
return roles;
}
QStringList MyModel::userRoleNames() // Return ordered List of user-defined roles
{
QMap<int, QString> res;
QHashIterator<int, QByteArray> i(roleNames());
while (i.hasNext()) {
i.next();
if(i.key() > Qt::UserRole)
res[i.key()] = i.value();
}
return res.values();
}
...
...
这篇关于具有动态列数的QML TableView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!