[Kde-bindings] Qt::StandardItemModel#item_prototype= causes crashe in qtruby

Richard Dale rdale at foton.es
Wed Apr 15 18:46:04 UTC 2009


On Wednesday 15 April 2009 19:41:53 Richard Dale wrote:
> On Tuesday 14 April 2009 20:07:53 Richard Dale wrote:
> > On Tuesday 14 April 2009 19:56:49 Stefano Crocco wrote:
> > > On Tuesday 14 April 2009, Richard Dale wrote:
> > > > |On Friday 10 April 2009 08:58:37 Stefano Crocco wrote:
> > > > |> Using Qt::StandardItemModel#item_prototype= and
> > > > |> Qt::StandardItemModel#horizontal_header= causes ruby to crash.
> > > > |> Here's the code causing the crash:
> > > > |>
> > > > |> require 'Qt4'
> > > > |>
> > > > |> app = Qt::Application.new []
> > > > |> m = Qt::StandardItemModel.new
> > > > |> proto = Qt::StandardItem.new ''
> > > > |> proto.flags = Qt::ItemIsEnabled
> > > > |> m.set_item_prototype proto
> > > > |> m.horizontal_header_labels = %w[x y]
> > > > |> app.exec
> > > > |>
> > > > |> If I comment out the call to horizontal_header_labels=, everything
> > > > |> works correctly.
> > > > |
> > > > |The crash is because you need to implement the clone() method in
> > > > | your Qt::StandardItem:
> > > > |
> > > > |require 'Qt4'
> > > > |
> > > > |class MyStandardItem < Qt::StandardItem
> > > > |  def clone
> > > > |    return MyStandardItem.new('')
> > > > |  end
> > > > |end
> > > > |
> > > > |app = Qt::Application.new []
> > > > |m = Qt::StandardItemModel.new
> > > > |proto = MyStandardItem.new ''
> > > > |proto.flags = Qt::ItemIsEnabled
> > > > |m.set_item_prototype proto
> > > > |m.horizontal_header_labels = %w[x y]
> > > > |app.exec
> > > > |
> > > > |-- Richard
> > >
> > > Sorry, I completely misunderstood what the prototype does and how it
> > > should be used. However, I still can't understand why my program
> > > crashes. After all, my prototype was an instance of QStandardItem,
> > > which does have a clone method. So why should it crash? Also, I tried
> > > writing the same program in C++, and it doesn't crash (of course, as I
> > > now understand, setting the prototype this way doesn't do anything, but
> > > now this is beside the point). Here's the C++ version:
> > >
> > > #include <QApplication>
> > > #include <QStandardItemModel>
> > > #include <QStringList>
> > >
> > > int main(int argc, char *argv[])
> > > {
> > >       QApplication app(argc, argv);
> > >       QStandardItemModel * m = new QStandardItemModel;
> > >       QStandardItem * proto = new QStandardItem;
> > >       proto->setFlags(Qt::ItemIsEnabled);
> > >       m -> setItemPrototype(proto);
> > >       QStringList headers;
> > >       headers << "x" << "y";
> > >       m->setHorizontalHeaderLabels(headers);
> > >       return app.exec();
> > > }
> > >
> > > Am I missing something else?
> >
> > Ah, for some reason I thought that clone() was a pure virtual method, but
> > it isn't. So I'm still not sure why the Ruby code crashes - I'll carry on
> > looking at it.
>
> The crash is happening in the QStandardItem copy constructor.
>
> I think the cause of the problem might be that we added a 'binding'
> instance variable to each class in the smoke lib for virtual method
> callbacks, and it would need to be initialized when an instance of
> x_QStandardItem is copied.
>
> class x_QStandardItem : public QStandardItem {
>     SmokeBinding* _binding;
> public:
>     void x_0(Smoke::Stack x) {
> 	// set the smoke binding
> 	_binding = (SmokeBinding*)x[1].s_class;
>     }
> ..
>
> If the copy is done in the superclass, then this isn't going to happen.
>
> QStandardItem::QStandardItem(const QStandardItem &other)
>
>     : d_ptr(new QStandardItemPrivate)
>
> {
>     Q_D(QStandardItem);
>     d->q_ptr = this;
>     operator=(other);
> }
>
> So this is quite tricky to fix, and needs a bit of thinking about.
Ah in fact the above comments aren't quite right because this crashes too:

class MyStandardItem < Qt::StandardItem
  def clone
    return MyStandardItem.new(self)
  end
end

So I'm stuck still.

-- Richard



More information about the Kde-bindings mailing list