我一直在尝试使用QML TableView
来显示QAbstractTableModel
。等式中缺少的部分似乎是TableView
中不可能有一个可变数量的列,尽管重写QAbstractItemModel::roleNames
应该告诉Qt我的列的数量和名称。我尝试仅使用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
的模式包含ListElement
并且其中定义了角色,但这并未显示任何内容。
但是,如果上述代码已取消注释并且定义了TableViewColumn
,则该列将按预期显示该角色的数据,但该表仍将不显示任何其他角色。显然,这只适用于静态定义的列数,而不适用于直到运行时才知道列数的情况。
给出的示例与我的现实生活示例基本相同,只是我的模型是用C ++定义的。
好像这可能已被问过here,但它没有得到任何回复。
编辑:我曾尝试调用javascript函数:
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的解决方案远比这更好。
答案 0 :(得分:11)
您可以使用TableViewColumn
的{{1}}属性动态创建所需数量resources
。
您必须在自定义模型类中添加一个方法,该方法将为您提供要显示的roleNames。
<强> QML:强>
TableView
<强> MyModel.h:强>
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.cpp:强>
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;
...
};
答案 1 :(得分:1)
有资源的解决方案对我不起作用(Qt 5.6)。 TableView未更新。
这对我有用:
Component{
id: columnComponent
TableViewColumn{width: 30 }
}
TableView {
id: tableView
model: listModel
property var titles: somethingDynamic
property var curTitles: {
var t=[]
for(var i=0;i<columnCount;i++){
t.push(getColumn(i).title)
}
return t
}
onTitlesChanged:{
for(var i=0;i<titles.length;i++){
if(curTitles.indexOf(titles[i])==-1){
var column = addColumn(columnComponent)
column.title=titles[i]
column.role=titles[i]
}
}
for(var i=curTitles.length-1;i>=0;i--){
if(titles.indexOf(curTitles[i])==-1){
removeColumn(i)
}
}
}
}
}
它还可以正确更新拖放重新排序的列。