From: Stefano Crocco Date: 2010-12-06T18:39:10+09:00 Subject: Re: qt4-ruby crash On Monday 06 December 2010 03:50:26 Marco Polo wrote: > This is the piece of code that makes ruby to crash: > > > def load_plists > #return > @ui.lists_tv.clear > DBIntf::connection.execute( "SELECT * FROM plists ORDER BY > LOWER(sname)" ) do |row| > @ui.lists_tv.addTopLevelItem(Qt::TreeWidgetItem.new { > setText(0, row[0]); setText(1, row[1]) }) > end > end > > > I added the order by statement to get rid from the sort in the tree > view. The tree view comes from a qtdesigner ui file and is used as a > list > view, there are no children and only 16 entries in the sqlite3 plists > table. > In another similar case, slightly more complex, i have 2000+ entries and > it works even if sort is enabled but only if the code is surrounded with > GC.enable/disable: > > > def load_entries > clear > > GC.disable > has_compile = false > DBIntf::connection.execute(generate_sql) do |row| > map_row_to_entry(row, Qt::TreeWidgetItem.new) > has_compile = true if row[ROW_REF] == "0" > end > unless @mc.main_filter.empty? > unless has_compile > map_row_to_entry(["0", "Compilation"], > Qt::TreeWidgetItem.new) > end > end > > GC.enable > return self > end > > > In this case, the class inherits a treeview. > > Thanks for the links and your help. > > marco First of all, just to be clear, you're using tree widgets, not tree views. Asides from this, I don't see anything wrong with your code. As I said in my other mail, I think your best option is to post the C backtrace from the crash to either the qt-ruby forum or mailing list. If you do, you may be asked for a small program which reproduces the crash. I guess this might not be easy to do. If all else fails, you can try replacing the tree widget with a tree view coupled with a Qt::StandardItemModel. Model/View-based widgets (Qt::ListView, Qt::TreeView and Qt::TableView) are more flexible than their *Widget counterparts and, when used with a Qt::StandardItemModel, are just as easy to use. If you choose to do so, you can create the view widget using the designer just like you did with the tree widget. Then, in your widget's constructor do something like (referring to your first piece of code): @ui.lists_tv.model = Qt::StandardItemModel.new @ui.lists_tv Then, in your load_plists method, you can do something like this: @ui.lists_tv.clear DBIntf::connection.execute( "SELECT * FROM plists ORDER BY LOWER(sname)" ) do |row| items = row.map{|i| Qt::StandardItem.new i} @ui.lists_tv.model.append_row items end Even if you don't find TreeView better than TreeWidget, it may avoid the crashes you see. By the way, referring to your first message, why do you think that using qt- ruby "our code looks like to a c++ app written in another language (you almost lose all advantages of a clean ruby port like ruby-gnome2, exception messages are unclear when it's qt related)"? (I never used ruby-gnome2, so I can't compare with it). Looking at your code, it seems you aren't aware that you can replace camel- case names with snake-case ones (for example, addTopLevelItem could have been written as add_top_level_item). Also, in case you aren't aware, methods starting with is are availlable in the more rubysh form ending with a question mark: isEmpty can also be called as empty?. I'm not sure if this is also the case for methods starting with has. Setters methods taking a single argument are also availlable as methods ending with =. For instance, the Qt::TreeView setColumnCount method can also be written as column_count =. Regarding the exception issue, I'm afraid I have to agree they are often wrong. In particular (I guess this is what you're referring to), qt-ruby raises NoMethodError even when the method does exist, but takes different arguments from what you passed. I read somewhere that this is to mimic the behaviour you get in C++, where using the wrong arguments would make the compiler complain about calling a non existing method. I thought to post a bug report about this but decided against that knowing they would have rejected it because of compatibility issues. I hope this helps Stefano