使用PyGObject创建自定义小部件
我正在尝试用PyGObject创建一个自定义的小部件。比如,我想创建一个叫做CustomButton
的小部件,它可以在按钮里添加一张图片和一个标签(这只是个例子):
#!/usr/bin/python
#-*- coding: utf-8 -*
from gi.repository import Gtk
class ImageButton(Gtk.Widget):
def __init__(self, label, image):
Gtk.Widget.__init__(self)
self.hbox = Gtk.HBox()
self.label = Gtk.Label(label)
self.image = Gtk.Image.new_from_stock(image, Gtk.IconSize.MENU)
self.hbox.pack_start(self.image, False, False, 3)
self.hbox.pack_start(self.label, False, False, 3)
self.button = Gtk.Button()
self.button.add(self.hbox)
在另一个文件或类里,我可以这样使用它:
button = ImageButton("My label", Gtk.STOCK_HOME)
但是当我想用它的时候,我必须调用button
这个属性,像这样:
# Connect the "clicked" event
button.button.connect("clicked", on_clicked_button)
# Add the button in a container
window.add(button.button)
这样是可以工作的,但不太方便。请问如何创建一个像其他小部件一样好用的自定义小部件呢:
button = ImageButton("My label", Gtk.STOCK_HOME)
button.connect("clicked", on_clicked_button)
window.add(button)
1 个回答
2
我觉得你的问题其实是关于理解类的,而不是继承。如果你想让你的控件完全像一个按钮,那它就应该是一个按钮。
看看下面这个例子:
from gi.repository import Gtk
class ImageButton(Gtk.EventBox):
def __init__(self, label):
Gtk.EventBox.__init__(self)
self.label = Gtk.Label(label)
self.add(self.label)
if __name__ == '__main__':
def on_imagebutton_clicked(button, data=None):
print("Button has been clicked!")
window = Gtk.Window()
button = ImageButton("My label")
button.connect('button-press-event', on_imagebutton_clicked)
window.add(button)
window.show_all()
Gtk.main()
我没有说我的类是一个 Gtk.Widget
,而是说它是一个 Gtk.EventBox
,并且是这样开始的。从现在开始,ImageButton
将会拥有和 Gtk.EventBox
一样的属性和方法。
*如果我用 Gtk.Button
来做同样的例子,而不是 Gtk.EventBox
,那么你可以用 button.connect(..
来代替 buton.connect.connect(..
,这正是你在问题中想要的。这样做的问题是,如果 ImageButton
是一个 Gtk.Button
,那么就不能再修改它去做一些按钮不能做的事情(比如添加容器和标签)。
简单来说:
你可以基于其他控件创建一个自定义控件,但树形结构中只有一个控件会在最上面。
--> Parent
---------> Child
---------> Child
所以当你使用 self.method
时,它总是会查找:
1) 你的父类方法(就是你通过 Gtk.EventBox.__init__(self)
复制过来的那个)
2) 你自己创建的方法。
另外,你可以通过这个方式来“撒谎”:
from gi.repository import Gtk
class ImageButton(Gtk.EventBox):
def __init__(self, label):
Gtk.EventBox.__init__(self)
self.label = Gtk.Label(label)
self.add(self.label)
def set_text(self, text):
self.label.set_text(text)
if __name__ == '__main__':
def on_imagebutton_clicked(button, data=None):
print("Button has been clicked!")
window = Gtk.Window()
button = ImageButton("My label")
button.connect('button-press-event', on_imagebutton_clicked)
button.set_text('New text!!')
window.add(button)
window.show_all()
Gtk.main()
注意,我并没有调用 button.label.set_text(..)
,希望这样能让你明白!