2012-09-17 2 views
0

나는 PyGI + Gtk3를 사용하여 GUI를 만들려고하는 기존 프로젝트를 가지고있다. 렌더링 할 수 있도록 약간 확장해야하는 기본 객체가 있습니다. 버튼 수익률에게 즉각적인 결과를 클릭하지PyGI는 set_attribute/적절한 신호를 에뮬레이션 할 수 있습니까?

# 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() 

현재 코드가 실행되지만 변경된 행 위에 마우스를 실행하는 설정하는 가운데 사각형의 원인이됩니다 : 여기 단순화 된 코드까지 문제를 삶은했습니다 빨간색 (행 위로 마우스를 가져 가면 새로 고침이 트리거 됨) 일반적으로 '적절한'GObject에 set_attribute가 호출되면, 위젯에 포함 된 위젯에 다시 렌더링하라는 신호를 내 보냅니다.

내가 방출하는 신호, 방출 된 신호 및 해당 동작을 에뮬레이션하는 방법을 알아야합니다.

+0

또한, 저보다 담당자가 많은 사람은 PyGI 태그를 만들어야합니다. PyGTK는 죽은 AFAIK입니다 ... – Pat

+1

나는 그것을'pygobject'라고 태그했습니다. PyGI는 현재 PyGObject라는 이름입니다. 혼동스럽게도 PyGObject는 PyGTK에서 GObject 바인딩의 이름이기도합니다. – ptomato

답변

0

다시 그려야하는 위젯을 알고 있다면 위젯에 queue_draw(), queue_draw_region() 또는 queue_draw_area()을 호출하면됩니다. 그러면 창 영역이 무효화되고 다시 그려집니다. 보다 세분화 된 제어가 필요하면 Gtk.DrawingArea를 사용하는 것이 좋습니다.

The GTK+ Drawing Model에 대한 설명서를 확인하십시오.

관련 문제