1

我一直在关注这篇文章以在 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但是,我在类范围而不是实例范围内找不到任何东西。

我错过了什么?

4

1 回答 1

0

好的,我已经设法解决了这个问题。显然,问题不在于继承,而在于 GC。由于与模型的唯一连接来自 TableView 的model属性 - 它只是 C++ getter 和 setter 的包装器 - ruby​​ 认为它丢失了对我的模型的引用,并且 GC'd 了它们。

通过将模型保存在 ruby​​ 变量中来解决。

于 2012-03-19T18:32:00.923 回答