2

I'm trying to figure out how to use TableView with a model using qtruby. I tried to adapt the example in C++ in the tutorial given at http://doc.qt.io/qt-5/modelview.html and came up with the code shown below.

The problem is in the implementation of the data method of AbstractTableModel: only the role Qt::DisplayRole works as expected. The roles Qt::FontRole and Qt::BackgroundRole don't cause an error but don't seem to do anything either. Even worse, the roles Qt::TextAlignmentRole and Qt::CheckStateRole cause segmentation faults if enabled. Can someone tell me if I'm doing something wrong here?

#!/usr/bin/env ruby
require 'Qt'
include Qt

class MyModel < AbstractTableModel
  def initialize(p)
    super
  end

  def rowCount(p)
    2
  end

  def columnCount(p)
    3
  end

  def data(index, role)
    row = index.row
    col = index.column

    case role
    when Qt::DisplayRole
      return Variant.new "Row#{row + 1}, Column#{col + 1}"
    when Qt::FontRole
      # this doesn't result in an error, but doesn't seem to do anything either
      if (row == 0 && col == 0)
        boldFont = Font.new
        boldFont.setBold(true)
        return boldFont
      end
    when Qt::BackgroundRole
      # this doesn't result in an error, but doesn't seem to do anything either
      if (row == 1 && col == 2)
        redBackground = Brush.new(Qt::red)
        return redBackground
      end
    when Qt::TextAlignmentRole
      # # the following causes a segmentation fault if uncommented
      # if (row == 1 && col == 1)
      #   return Qt::AlignRight + Qt::AlignVCenter
      # end
    when Qt::CheckStateRole
      # # the following causes a segmentation fault if uncommented
      # if (row == 1 && col == 0)
      #   return Qt::Checked
      # end
    end
    Variant.new
  end
end

app = Application.new ARGV
tableView = TableView.new
myModel = MyModel.new(nil)
tableView.setModel(myModel)
tableView.show
app.exec
varro
  • 2,382
  • 2
  • 16
  • 24

1 Answers1

1

This is because for the DisplayRole you are creating a new Qt::Variant as expected.

For the other return values, you should use:

return Qt::Variant.fromValue(boldFont)

return Qt::Variant.fromValue(redBackground)

return Qt::Variant.fromValue(Qt::AlignRight + Qt::AlignVCenter)

return Qt::Variant.fromValue(Qt::Checked)
bogl
  • 1,864
  • 1
  • 15
  • 32
  • OK - that seems to work, so thank you. I didn't see that in the original C++ tutorial, but I guess the conversion is implicit in the declared return type of MyModel::data(), whereas the type conversion has to be explicit in the Ruby code? – varro Jan 14 '17 at 23:16
  • @varro It is not related to C++, but to the qtruby wrapper. It is also difficult to spot in the qtruby documentation. See https://techbase.kde.org/Languages/Ruby in section "Emitting Ruby Classes". The Qt/ruby wrapper does a lot of these conversions seamless, but here it has to be explicit. (I also had a hard time to figure it out some time ago...) – bogl Jan 16 '17 at 08:01
  • Thanks for the extra info - I still have to learn a lot more how Qt works, and I'll be studying the reference you cited. – varro Jan 29 '17 at 01:33
  • @varro You might want to look into ruby-qml instead. Please see what I wrote on http://stackoverflow.com/a/34700155/5766404 . – bogl Feb 03 '17 at 13:55