我一直在关注this article以在QtRuby中显示ActiveRecord数据。我从那里复制了BoatTableModel
类(其余的使用了我自己的代码)。在本文中,BoatTableModel
被定义为仅支持Boat
模型,但除了列定义之外,代码非常通用。所以,我已经更改了它,而不是在那里定义列,我已经从column_names
方法获取了列,并在每个模型的子类中定义了这些方法。
这是我的代码:
class QtArModel<Qt::AbstractTableModel
def initialize(items)
super()
@items=items
end
def rowCount(parent=nil)
@items.size
end
def columnCount(parent=nil)
column_names.length
end
def data(index,role=Qt::DisplayRole)
invalid=Qt::Variant.new
return invalid unless role==Qt::DisplayRole or role==Qt::EditRole
item=@items[index.row]
return invalid if item.nil?
v=item[column_names[index.column]]||""
return Qt::Variant.new(v)
end
def headerData(section,orientation,role=Qt::DisplayRole)
invalid=Qt::Variant.new
return invalid unless role==Qt::DisplayRole
v=case orientation
when Qt::Horizontal
column_names[section]
else
""
end
return Qt::Variant.new(v.to_s)
end
def flags(index)
return Qt::ItemIsEditable|super(index)
end
def setData(index,variant,role=Qt::EditRole)
if index.valid? and role==Qt::EditRole
s=variant.toString
item=@items[index.row]
if index.column.between?(0,column_names.length-1)
item[column_names[index.column]]=s
else
raise "invalid column #{index.column}"
end
item.save
emit dataChanged(index,index)
else
return false
end
end
end
class QtCoursesTableModel<QtArModel
def column_names
return [
:number,
:name,
:tutor_name,
:site,
:active,
]
end
end
class QtTasksTableModel<QtArModel
def column_names
return [
:course,
:ex_number,
:received,
:due,
:description,
:link,
:completed,
:file,
]
end
end
现在,当我显示一个模型(无关紧要)时 - 一切正常。但是,当我显示两个模型时,每个模型都有自己的Qt::TableView
- 只显示第一个模型,而另一个表格视图为空白。
我尝试了不同的排序,并且显示它的数据的表总是首先创建Qt::TableView
的表 - 创建Qt模型的顺序无关紧要。此外,当我为第一个表创建模型对象,但实际上没有为它设置model
属性时,第二个表显示它的数据。
我还尝试在两个不同的表视图中两次显示相同的模型 - 它工作 - 一瞬间,然后第二个视图的数据消失。
我还尝试复制粘贴QtArModel
,更改其名称,并使其中一个模型继承自副本。那个做了工作 - 但这显然是一个巨大的代码重复,所以我真的想避免这种情况。
现在,我的猜测是QtArModel中的某些内容被定义为类成员而不是实例成员,这使得两个模型实例共享它们不应共享的内容。它必须在QtArModel中 - 因为如果它在继承树中更高,那么当我复制QtArModel
时问题就会存在。但是,我在QtArModel
中找不到任何类的作用域而不是实例作用域。
我错过了什么?
答案 0 :(得分:0)
好的,我已成功解决了这个问题。显然,问题不是继承,而是GC。由于与模型的唯一连接来自TableView的model
属性 - 它只是C ++ getter和setter的包装器 - ruby认为它丢失了对我的模型的引用,并且GC它们。
通过将模型保存在ruby变量中来解决。