klayout/testdata/ruby/qtbinding.rb

598 lines
15 KiB
Ruby

$:.push(File::dirname($0))
load("test_prologue.rb")
# an event filter class
# don't create a class twice since the alias orgEventFilter will
# refer to itself
if !Object.const_defined?("EventFilter")
class EventFilter < RBA::QObject
alias orgEventFilter eventFilter
def initialize
@log = []
end
def log
@log
end
def eventFilter(obj, event)
@log << (event.class.to_s + ": " + event.type.inspect)
self.orgEventFilter(obj, event)
end
end
# implementation
class MyAction < RBA::QAction
def initialize(p, n)
super(p)
self.objectName = n
@ce = nil
end
def childEvent(ev)
if @ce
@ce.call(ev)
end
end
def on_child_event(&ce)
@ce = ce
end
end
class MyObject < RBA::QObject
def initialize
@ef = nil
super(nil)
end
alias baseEventFilter eventFilter
def eventFilter(watched, event)
if @ef.call(watched, event)
return true
end
baseEventFilter(watched, event)
end
def on_event_filter(&ef)
@ef = ef
end
end
class MyStandardItemModel < RBA::QStandardItemModel
def srn(rn)
if self.respond_to?(:setRoleNames, true)
self.setRoleNames(rn)
else
self.setItemRoleNames(rn)
end
end
end
end
class QtBinding_TestClass < TestBase
def test_00
# initial test
end
def test_10
a = MyAction.new(nil, "a")
a.text = "mytext"
a.checkable = true
assert_equal(a.isChecked, false)
a.checked = true
assert_equal(a.text, "mytext")
assert_equal(a.objectName, "a")
a.text += "."
assert_equal(a.text, "mytext.")
assert_equal(a.isChecked, true)
t = ""
a.triggered do |checked|
t += "[#{checked}]";
end
assert_equal(t, "")
a.trigger # also toggles checked state
assert_equal(t, "[false]")
t = ""
a.trigger # also toggles checked state
assert_equal(t, "[true]")
# force GC and destruction
a = nil
GC.start
a = MyAction.new(nil, "anew")
assert_equal(a.objectName, "anew")
a = nil
GC.start
end
def test_11
a = RBA::QAction.new(nil)
aa = MyAction.new(a, "aa")
assert_equal(aa.objectName, "aa")
# destroying a will also destroy aa
a.destroy
assert_equal(a.destroyed?, true)
assert_equal(aa.destroyed?, true)
end
def test_12
a = RBA::QAction.new(nil)
aa = RBA::QAction.new(a)
aa.objectName = "aa"
# destroying in the GC will also destroy aa
a = nil
GC.start
a = RBA::QAction.new(nil)
a = nil
GC.start
assert_equal(aa.destroyed?, true)
end
def test_13
a = RBA::QAction.new(nil)
aa = RBA::QAction.new(a)
aa.objectName = "aa"
aa.text = "aatext"
cc = []
a.children.each do |c|
cc.push(c.objectName)
end
assert_equal(cc.join(","), "aa")
# aa now is kept by a
aa = nil
GC.start
aa = RBA::QAction.new(nil)
aa = nil
GC.start
# fetch aa again
a.children.each do |c|
if c.objectName == "aa"
aa = c
end
end
assert_equal(aa != nil, true)
assert_equal(aa.class.to_s, "RBA::QAction")
assert_equal(aa.text, "aatext")
assert_equal(aa.destroyed?, false)
end
def test_20
no_event = false
x = []
ef = MyObject.new
ef.on_event_filter do |watched,event|
x.push(watched.inspect + ":" + event.inspect)
no_event
end
ce_log = []
a = MyAction.new(nil, "a")
a.on_child_event do |ce|
ce_log.push("#{ce.added}:#{ce.child.objectName}")
end
a.installEventFilter(ef)
aa = MyAction.new(nil, "aa1")
assert_equal(ce_log.join(","), "")
aa.setParent(a)
assert_equal(ce_log.join(","), "true:aa1")
ce_log = []
# destroy aa
aa.destroy
aa = nil
assert_equal(ce_log.join(","), "false:aa1")
ce_log = []
no_event = true
aa = MyAction.new(nil, "aa2")
aa.setParent(a)
assert_equal(ce_log.join(","), "")
ce_log = []
no_event = false
aa.destroy
aa = nil
assert_equal(ce_log.join(","), "false:aa2")
ce_log = []
end
def test_30
# dialog construction, cleanup, object dependency ...
mw = nil # more fun than with RBA::Application::instance.main_window because Ruby's GC does all the cleanup
dialog = RBA::QDialog::new(mw)
label = RBA::QLabel::new(dialog)
layout = RBA::QHBoxLayout::new(dialog)
layout.addWidget(label)
GC.start
dialog = RBA::QDialog::new(mw)
label = RBA::QLabel::new(dialog)
layout = RBA::QHBoxLayout::new(dialog)
layout.addWidget(label)
label.destroy
GC.start
dialog = RBA::QDialog::new(mw)
label = RBA::QLabel::new(dialog)
layout = RBA::QHBoxLayout::new(dialog)
layout.addWidget(label)
layout.destroy
GC.start
dialog = RBA::QDialog::new(mw)
label = RBA::QLabel::new(dialog)
layout = RBA::QHBoxLayout::new(dialog)
layout.addWidget(label)
dialog.destroy
GC.start
dialog = RBA::QDialog::new(mw)
label = RBA::QLabel::new(dialog)
layout = RBA::QHBoxLayout::new(dialog)
layout.addWidget(label)
GC.start
end
def test_31
# Optional arguments, enums, QFlag's
mw = nil # more fun than with RBA::Application::instance.main_window because Ruby's GC does all the cleanup
mb = RBA::QMessageBox::new(RBA::QMessageBox::Critical, "title", "text")
assert_equal(mb.icon.to_i != RBA::QMessageBox::Warning.to_i, true)
assert_equal(mb.icon.to_i == RBA::QMessageBox::Critical.to_i, true)
assert_equal(mb.standardButtons.to_i == RBA::QMessageBox::NoButton.to_i, true)
mb = RBA::QMessageBox::new(RBA::QMessageBox::Critical, "title", "text", RBA::QMessageBox::Ok)
assert_equal(mb.standardButtons.to_i == RBA::QMessageBox::Ok.to_i, true)
mb = RBA::QMessageBox::new(RBA::QMessageBox::Critical, "title", "text", RBA::QMessageBox::Ok | RBA::QMessageBox::Cancel)
assert_equal(mb.standardButtons.to_i == RBA::QMessageBox::Ok.to_i + RBA::QMessageBox::Cancel.to_i, true)
end
def test_40
# Lifetime management of objects/methods not using QObject::parent
# QTreeWidget (parent)/QTreeWidgetItem (child)
# constructor with parent-like argument:
tw = RBA::QTreeWidget::new
ti = RBA::QTreeWidgetItem::new(tw)
# strange, but true:
assert_equal(ti.parent, nil)
assert_equal(tw.topLevelItemCount, 1)
ti = nil
# force delete of the ti item unless it's referenced
# NOTE: it's not sufficient to just set ti to nil, we also
# have to create a new QTreeWidgetItem (special for Ruby >1.9?)
ti = RBA::QTreeWidgetItem::new
GC.start
# gives 1, because the tree widget item is kept by
# the tree widget:
assert_equal(tw.topLevelItemCount, 1)
# the tree item belongs to the widget, hence it's destroyed with
# the widget
ti = tw.topLevelItem(0)
tw._destroy
# gives true, because tw owns ti too.
assert_equal(ti._destroyed?, true)
# The same works for insert too
tw = RBA::QTreeWidget::new
ti = RBA::QTreeWidgetItem::new
tw.insertTopLevelItem(0, ti)
assert_equal(tw.topLevelItemCount, 1)
ti = nil
# force delete of the ti item unless it's referenced
ti = RBA::QTreeWidgetItem::new
GC.start
# gives 1, because the tree widget item is kept by
# the tree widget:
assert_equal(tw.topLevelItemCount, 1)
# the tree item belongs to the widget, hence it's destroyed with
# the widget
ti = tw.topLevelItem(0)
tw._destroy
# gives true, because tw owns ti
assert_equal(ti._destroyed?, true)
# And add:
tw = RBA::QTreeWidget::new
ti = RBA::QTreeWidgetItem::new
tw.addTopLevelItem(ti)
assert_equal(tw.topLevelItemCount, 1)
ti = nil
# force delete of the ti item unless it's referenced
ti = RBA::QTreeWidgetItem::new
GC.start
# gives 1, because the tree widget item is kept by
# the tree widget:
assert_equal(tw.topLevelItemCount, 1)
# the tree item belongs to the widget, hence it's destroyed with
# the widget
ti = tw.topLevelItem(0)
tw._destroy
# gives true, because tw owns ti
assert_equal(ti._destroyed?, true)
# But the item is released when we take it and add:
tw = RBA::QTreeWidget::new
ti = RBA::QTreeWidgetItem::new
tw.addTopLevelItem(ti)
assert_equal(tw.topLevelItemCount, 1)
ti = nil
# force delete of the ti item unless it's referenced
ti = RBA::QTreeWidgetItem::new
GC.start
# gives 1, because the tree widget item is kept by
# the tree widget:
assert_equal(tw.topLevelItemCount, 1)
ti = tw.takeTopLevelItem(0)
tw._destroy
# gives false, because we took ti and tw no longer owns it
assert_equal(ti._destroyed?, false)
# And we can destroy a child too
tw = RBA::QTreeWidget::new
ti = RBA::QTreeWidgetItem::new
tw.addTopLevelItem(ti)
assert_equal(tw.topLevelItemCount, 1)
ti._destroy
assert_equal(tw.topLevelItemCount, 0)
end
def test_41
# Lifetime management of objects/methods not using QObject::parent
# QTreeWidgetItem (parent)/QTreeWidgetItem (child)
# constructor with parent-like argument (supported by QObject parent/child relationship):
tw = RBA::QTreeWidgetItem::new
ti = RBA::QTreeWidgetItem::new(tw)
# that's not QObject::parent - this one still is 0 (not seen by RBA)
assert_equal(ti.parent, tw)
assert_equal(tw.childCount, 1)
ti = nil
# force delete of the ti item unless it's referenced
# NOTE: it's not sufficient to just set ti to nil, we also
# have to create a new QTreeWidgetItem (special for Ruby >1.9?)
ti = RBA::QTreeWidgetItem::new
GC.start
# gives 1, because the tree widget item is kept by
# the tree widget:
assert_equal(tw.childCount, 1)
# the tree item belongs to the widget, hence it's destroyed with
# the widget
ti = tw.child(0)
tw._destroy
# gives true, because tw owns ti too.
assert_equal(ti._destroyed?, true)
# The same works for insert too
tw = RBA::QTreeWidgetItem::new
ti = RBA::QTreeWidgetItem::new
tw.insertChild(0, ti)
assert_equal(tw.childCount, 1)
ti = nil
# force delete of the ti item unless it's referenced
ti = RBA::QTreeWidgetItem::new
GC.start
# gives 1, because the tree widget item is kept by
# the tree widget:
assert_equal(tw.childCount, 1)
# the tree item belongs to the widget, hence it's destroyed with
# the widget
ti = tw.child(0)
tw._destroy
# gives true, because tw owns ti
assert_equal(ti._destroyed?, true)
# And add:
tw = RBA::QTreeWidgetItem::new
ti = RBA::QTreeWidgetItem::new
tw.addChild(ti)
assert_equal(tw.childCount, 1)
ti = nil
# force delete of the ti item unless it's referenced
ti = RBA::QTreeWidgetItem::new
GC.start
# gives 1, because the tree widget item is kept by
# the tree widget:
assert_equal(tw.childCount, 1)
# the tree item belongs to the widget, hence it's destroyed with
# the widget
ti = tw.child(0)
tw._destroy
# gives true, because tw owns ti
assert_equal(ti._destroyed?, true)
# But the item is released when we take it and add:
tw = RBA::QTreeWidgetItem::new
ti = RBA::QTreeWidgetItem::new
tw.addChild(ti)
assert_equal(tw.childCount, 1)
ti = nil
# force delete of the ti item unless it's referenced
ti = RBA::QTreeWidgetItem::new
GC.start
# gives 1, because the tree widget item is kept by
# the tree widget:
assert_equal(tw.childCount, 1)
ti = tw.takeChild(0)
tw._destroy
# gives false, because we took ti and tw no longer owns it
assert_equal(ti._destroyed?, false)
# And we can destroy a child too
tw = RBA::QTreeWidgetItem::new
ti = RBA::QTreeWidgetItem::new
tw.addChild(ti)
assert_equal(tw.childCount, 1)
ti._destroy
assert_equal(tw.childCount, 0)
end
def test_42
# QKeyEvent and related issues
ef = EventFilter::new
widget = RBA::QLineEdit::new
widget.setText("ABC")
RBA::QApplication::processEvents
widget.installEventFilter(ef)
ke = RBA::QKeyEvent::new(RBA::QEvent::KeyPress, RBA::Qt::Key_O.to_i, RBA::Qt::ShiftModifier, "O")
RBA::QCoreApplication::postEvent(widget, ke)
ke = RBA::QKeyEvent::new(RBA::QEvent::KeyPress, RBA::Qt::Key_Left.to_i, RBA::Qt::NoModifier)
RBA::QCoreApplication::postEvent(widget, ke)
ke = RBA::QKeyEvent::new(RBA::QEvent::KeyPress, RBA::Qt::Key_P.to_i, RBA::Qt::NoModifier, "p")
RBA::QCoreApplication::postEvent(widget, ke)
RBA::QApplication::processEvents
GC.start
assert_equal(ef.log.select { |s| s !~ /RBA::QKeyEvent: ShortcutOverride/ }.join("\n"), "RBA::QKeyEvent: KeyPress (6)\nRBA::QKeyEvent: KeyPress (6)\nRBA::QKeyEvent: KeyPress (6)")
ef = nil
ef = EventFilter::new
GC.start
assert_equal(widget.text, "ABCpO")
ef = nil
widget = nil
GC.start
end
def test_43
# QHash bindings
slm = MyStandardItemModel::new
rn = slm.roleNames
assert_equal(rn.keys.sort.collect { |k| "#{k}=>\"#{rn[k]}\"" }.join(", "), "0=>\"display\", 1=>\"decoration\", 2=>\"edit\", 3=>\"toolTip\", 4=>\"statusTip\", 5=>\"whatsThis\"")
rn[7] = "blabla"
slm.srn(rn)
rn = slm.roleNames
assert_equal(rn.keys.sort.collect { |k| "#{k}=>\"#{rn[k]}\"" }.join(", "), "0=>\"display\", 1=>\"decoration\", 2=>\"edit\", 3=>\"toolTip\", 4=>\"statusTip\", 5=>\"whatsThis\", 7=>\"blabla\"")
end
def test_44
# Ability to monitor native child objects
parent = RBA::QScrollArea::new
parent.show # this makes resize actually change the widget's size
child = parent.viewport
# ensure parent and child are working
assert_equal(child.destroyed?, false)
parent.resize(200, 200)
assert_equal(child.width() > 100, true)
assert_equal(child.height() > 100, true)
parent.resize(100, 100)
assert_equal(child.width() < 100, true)
assert_equal(child.height() < 100, true)
# now if we delete the parent, the child needs to become disconnected
parent._destroy()
assert_equal(parent.destroyed?, true)
assert_equal(child.destroyed?, true)
end
def test_45
# Ability to connect to signals while ignoring arguments and
# to emit signals
b = RBA::QPushButton::new
triggered = ""
b.clicked { |checked| triggered += (checked ? "1" : "0") }
assert_equal(triggered, "")
b.emit_clicked(true)
assert_equal(triggered, "1")
b.emit_clicked(false)
assert_equal(triggered, "10")
b.clicked { triggered += "*" }
b.emit_clicked(true)
assert_equal(triggered, "10*")
b.emit_clicked(false)
assert_equal(triggered, "10**")
end
end
load("test_epilogue.rb")