使用PyGObject创建自定义小部件

时间:2014-06-13 09:25:07

标签: python gtk3 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 个答案:

答案 0 :(得分: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(..作为你想要它在你的问题。这个问题是,如果ImageButtonGtk.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(..)我希望它足够清楚!