[Kde-bindings] const_missing method in ruby 1.8

Alexander Kellett lypanov at kde.org
Tue Aug 5 08:39:37 UTC 2003


On Tue, Aug 05, 2003 at 08:57:34AM +0100, Richard Dale wrote:
> From the ruby 1.8 release notes:
> 
> ': constants lookup
> 
>   improved at the performance of searching by using an internal hash
>   table.
> 
>   calls const_missing method of the class/module, if constant is not
>   found in the look up path.'
> 
> So it does look as though it will possible to trap references to to 
> const_missing for constants in QtRuby. Then the Qt::Widget::MYCONST syntax 
> can be used rather than Qt::Widget.MYCONST.

yay for 1.8 :)

was trying to hack on this as i noticed the same
thing, but, i need to figure out exactly how
the current bindings work first :)

but, quick question nevertheless, would this 
be modifications to Qt.rb or Qt.cpp?, i didn't
really understand the do_method_missing. i'll
try to read more code tonight. haven't read 
all that much up till now.

erm. slightly OT now.

also. i'm having problems with iterators as
return types. example attached. this doesn't
appear to exist at all in the smoke bindings.
yet i notice that the perlqt docs say that
while templates aren't bound, templated classes
are, or, thats what i understood from it in 
any case :)

so, in qcanvas.h is see:
   class QCanvasItemList : public QValueList<QCanvasItem*>;

then. in smoke
   smokedata.cpp:  { "QCanvasItemList", 0, Smoke::t_voidp | Smoke::tf_stack },     //44

and grep QCanvasItemList turns up nothing else but for return types

so. the error
   builder.rb:17: [BUG] Cannot handle 'QCanvasItemList' as return-type of QCanvas::collisions
is really quite understandable. 
though a nice error message would be nicer, which
brings me to another tangent.

i'm guessing that some sort of generic base QValueList[Iterator] 
object handler needs to be created?, or, is there a minor
bug in the bindings generation that stops this case maybe?

i'm guessing its also not possible to use it as a parameter
therefore, which is pretty limiting as a large number of
functions use QPtrLists's, QValueList's etc.

okay, back to the tangent. error handling currently code 
such as canvas.setBrush(Qt::Color.new(r,g,b)) will simply 
bomb out with little information as brush is expecting 
a QBrush, not a QColor. as i'm guessing

this pqtsh thing looks really nice. i'd like to 
do something like this in ruby. i wonder if it
uses anything more than perl's introspection or
if PerlQt provides a sort of smoke perl binding?

any ideas?

later,
Alex

p.s: if anyone has a PerlQt checkout, i really 
     could use it, as i can't get anything 
     whatsoever from sourceforge cvs  :(
-------------- next part --------------
#!/usr/bin/ruby -w

require 'Qt'
require 'kicons.rb'
require 'rui.rb'
require 'rexml/document'

class MyCanvasView < Qt::CanvasView
   def initialize(canvas, parent)
      @canvas = canvas
      super(canvas, parent)
   end
   def contentsMouseReleaseEvent(e)
      p e
   end
   def contentsMousePressEvent(e)
      p l = canvas.collisions(e.pos);
=begin
      for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
         if ( (*it)->rtti() == QCanvasRectangle::RTTI )
            qDebug("A QCanvasRectangle lies somewhere at this point");
      }
=end
   end
end

class MyWidget < Qt::MainWindow
   slots 'new()', 'open()', 'save_as()'
   def make_rect
      rect = Qt::CanvasRectangle.new(rand(@canvas.width()), rand(@canvas.height()),
                                     @canvas.width / 5, @canvas.width / 5, @canvas)
      z = rand(256)
      color = Qt::Color.new(z,z,z)
      rect.setBrush(Qt::Brush.new(color))
      color = Qt::Color.new(rand(32)*8, rand(32)*8, rand(32)*8)
      rect.setPen(Qt::Pen.new(color, 6))
      rect.setZ(z)
      rect.show
      @rects << rect
   end
   def initialize()
      super

      fileTools = Qt::ToolBar.new(self, "file operations")
      fileMenu = Qt::PopupMenu.new(self)

      actions = [
         RAction.new("&New",  Icons::FILE_NEW, self, SLOT('new()'), [fileTools, fileMenu]),
         RAction.new("&Open...", Icons::FILE_OPEN, self, SLOT('open()'), [fileTools, fileMenu]),
         @save = RAction.new("Save &As...", Icons::FILE_SAVE_AS, self, SLOT('save_as()'), [fileTools, fileMenu]),
         RSeperator.new([fileMenu]),
         RAction.new("E&xit", Icons::EXIT, $qApp, SLOT('quit()'), [fileMenu])
      ]
      build_actions(actions)

      menubar = Qt::MenuBar.new(self)
      menubar.insertItem("&File", fileMenu)

      @canvas = Qt::Canvas.new(640, 480)

      @rects = []
      5.times { make_rect }

      @canvas_view = MyCanvasView.new(@canvas, self)
      self.setCentralWidget(@canvas_view)
      @canvas.update
   end
end

a = Qt::Application.new(ARGV)

w = MyWidget.new
w.show

a.setMainWidget(w)
a.exec()
exit
-------------- next part --------------
class KIconCollection
   IconInfo = Struct.new(:collection, :id, :filetype)
   def initialize(icon_collections)
      @icon_info = {}
      icon_collections.each_pair {
         |collection_name, collection|
         collection.each_pair {
            |key, value|
            info = IconInfo.new(collection_name, value, "png")
            @icon_info[key] = info
         }
      }
   end
   def dims
      "16x16"
   end
   def kdedir
      ENV["KDEDIR"]
   end
   def get_icon_path(icon_type)
      info = @icon_info[icon_type]
      "#{kdedir}/share/icons/default.kde/#{dims}/#{info.collection}/#{info.id}.#{info.filetype}"
   end
   def get_icon_set(icon_type)
      path = get_icon_path(icon_type)
      pixmap = Qt::Pixmap.new(path)
      icon_set = Qt::IconSet.new
      icon_set.setPixmap(pixmap, Qt::IconSet.Small)
      icon_set
   end
   def make_qt_action(parent, text_with_accel, icon_type)
      act = Qt::Action.new(parent)
      act.setIconSet(get_icon_set(icon_type))
      act.setMenuText(text_with_accel)
      act
   end

end

module Icons
   FILE_NEW, FILE_OPEN, FILE_CLOSE, FILE_SAVE, FILE_SAVE_AS, EXIT = 1,2,3,4,5, 6
end

icon_collections = {
   "actions" => {
      Icons::FILE_NEW       => "filenew",
      Icons::FILE_OPEN      => "fileopen",
      Icons::FILE_CLOSE     => "fileclose",
      Icons::FILE_SAVE      => "filesave",
      Icons::FILE_SAVE_AS   => "filesaveas",
      Icons::EXIT           => "exit"
   }
}
$kIcons = KIconCollection.new(icon_collections)
print "Using KDEDIR == ", $kIcons.kdedir, "\n"
-------------- next part --------------
require 'kicons.rb'

# # ambiguity problems with 
# Qt::MessageBox.question(self, "File Already Exists", "Are you sure you want to overwrite this file?")
# # and with popupmenu.insertItem(txt, reciever, slot):
# # evil workaround
class Qt::PopupMenu
   def insertItem(txt, rec, slot)
      id = super(txt)
      self.connectItem(id, rec, slot)
      id
   end
end

RAction = Struct.new(:text_with_accel, :icon_type, :rec, :slot, :included_in, :action)
RSeperator = Struct.new(:included_in, :id)

def build_actions(actions)
   actions.each { |a|
      if a.is_a? RSeperator
         a.included_in.each {
            |to| a.id = to.insertSeparator() 
         }
      else
         qt_action = $kIcons.make_qt_action(self, a.text_with_accel, a.icon_type)
         connect(qt_action, SIGNAL('activated()'), a.rec, a.slot)
         a.included_in.each {
            |to| qt_action.addTo(to)
         }
         a.action = qt_action
      end
   }
end


More information about the Kde-bindings mailing list