我有一个现有的项目,我正试图围绕它构建一个GUI(使用PyGI+Gtk3)。我需要稍微扩展一些本机对象,使其可渲染。我把问题归结为以下简化代码:
# Simplified Equivalent Code
from gi.repository import GObject
from gi.repository import Gtk
from gi.repository import GdkPixbuf
# Pre-existing, complex object
class Move(object):
def __init__(self, color):
self.color = color
# Pre-existing, complex object
class Block(object):
def __init__(self,move=None,**kwds):
self.move = move
# New object created to help render a Block
class BlockGui(Block):
pixbufs = {
'empty' : GdkPixbuf.Pixbuf.new_from_file('block_empty.png'),
'red' : GdkPixbuf.Pixbuf.new_from_file('block_red.png'),
'blue' : GdkPixbuf.Pixbuf.new_from_file('block_blue.png'),
}
def __setattr__(self, name, value):
super(BlockGui, self).__setattr__(name, value)
if name == 'move':
print "Need to emit a signal here"
def get_pixbuf(self):
try:
return BlockGui.pixbufs[self.move.color]
except AttributeError:
return BlockGui.pixbufs['empty']
class BlockRenderer(Gtk.CellRendererPixbuf):
__gproperties__ = {
'block' : (GObject.TYPE_PYOBJECT,
'block to render',
'the block object to be rendered',
GObject.PARAM_READWRITE)
}
def __init__(self):
GObject.GObject.__init__(self)
self.block = None
def do_set_property(self, prop, value):
# What is a GParamBoxed? Should I be checking if prop == 'block' from it somehow?
if isinstance(value, BlockGui):
self.block = value
self.set_property('pixbuf', self.block.get_pixbuf())
GObject.type_register(BlockRenderer)
def destroy(widget, data=None):
Gtk.main_quit()
# Normally do not have access to this assignment
def on_clicked(widget, liststore, treeview):
treeiter = liststore.get_iter(2)
block = liststore.get_value(treeiter, 1)
block.move = Move('red')
def main():
# 3x5 so this demo window has some size
fmt = [GObject.TYPE_PYOBJECT] * 3
liststore = Gtk.ListStore(*fmt)
for r in xrange(5):
liststore.append([BlockGui() for x in xrange(3)])
treeview = Gtk.TreeView(liststore)
for c in xrange(3):
col = Gtk.TreeViewColumn(str(c))
treeview.append_column(col)
cell = BlockRenderer()
col.pack_start(cell, True)
col.add_attribute(cell, 'block', c)
button = Gtk.Button("Change Color!")
button.connect('clicked', on_clicked, liststore, treeview)
vbox = Gtk.VBox()
vbox.add(treeview)
vbox.add(button)
window = Gtk.Window(Gtk.WindowType.TOPLEVEL)
window.connect('destroy', destroy)
window.add(vbox)
window.show_all()
Gtk.main()
if __name__ == '__main__':
main()
当当前代码运行时,单击该按钮不会立即产生结果,但是在更改的行上运行鼠标将导致中心正方形变为红色(因为将鼠标悬停在该行上会触发刷新)。通常,当一个'proper'GObject有一个set_属性被调用时,它会发出一些信号来通知包含它的小部件重新呈现。在
我需要知道是哪个信号发出的,它是向谁发出的,以及如何模仿这种行为。在
如果您知道必须重新绘制的小部件,那么您可以为该小部件调用}。这将使窗口区域无效,并将重新绘制。如果您想要更细粒度的控制,您可能需要使用Gtk图纸区域. 在
queue_draw()
、queue_draw_region()
或{您可能需要检查文档中的The GTK+ Drawing Model。在
相关问题 更多 >
编程相关推荐