在Python中构建Gtk3应用程序的正确方法

Mic*_*bor 18 python gtk3

我刚开始学习如何用Python创建GUI应用程序.我决定使用Gtk版本3.根据http://python-gtk-3-tutorial.readthedocs.org/上的(官方?)教程,构建hello world应用程序的正确方法是:

from gi.repository import Gtk

class MyWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.set_default_size(200, 100)
        self.connect('destroy', Gtk.main_quit)
        self.show_all()

MyWindow()
Gtk.main()
Run Code Online (Sandbox Code Playgroud)

在其他教程(http://www.micahcarrick.com/gtk3-python-hello-world.html)中,我发现完全不同的方法是:

from gi.repository import Gtk, Gio

class HelloWorldApp(Gtk.Application):
    def __init__(self):
        Gtk.Application.__init__(self, application_id="apps.test.helloworld",
                                 flags=Gio.ApplicationFlags.FLAGS_NONE)
        self.connect("activate", self.on_activate)

    def on_activate(self, data=None):
        window = Gtk.Window(type=Gtk.WindowType.TOPLEVEL)
        window.set_title("Gtk3 Python Example")
        window.set_border_width(24)
        label = Gtk.Label("Hello World!")
        window.add(label)
        window.show_all()
        self.add_window(window)

if __name__ == "__main__":
    app = HelloWorldApp()
    app.run(None)
Run Code Online (Sandbox Code Playgroud)

这个类别中有经验的人能告诉我这些天我应该以什么方式在python中编写Gtk 3应用程序?我已经熟悉编写GUI(在Java的Swing中花了几个月),所以你可以继续使用诸如事件,回调等术语.

ile*_*nt2 15

选择使用GtkApplication或GtkWindow编写新程序取决于您需要的功能,以及某种程度上的目标受众.

对于大多数情况,特别是当你还在学习工具包时,我倾向于同意valmynd认为GtkApplication不必要地复杂化.GtkApplication提供了许多额外的功能,您可能在较小的应用程序中不需要或不需要.

对于更大,更完整的应用程序,我同意Dragnucs,第二种方法更优越,可以更好地集成到桌面环境中.从GNOME目标:端口到GtkApplication(另请参阅GtkApplication文档):

将应用程序移植到使用GtkApplication有很好的好处:GtkApplication处理GTK +初始化,应用程序唯一性,会话管理,通过导出操作和菜单提供一些基本的脚本化和桌面shell集成,并管理生命周期自动绑定到的顶级窗口列表应用程序的生命周期.

但是我不同意Dragnucs关于为什么在教程中引入GtkWindow方法.我倾向于认为具有非常少的样板的简单示例更适合于教程入门部分(但是,我认为需要更新read-the-docs教程以至少包括一些GtkApplication).

在我编写的应用程序中,我倾向于将GtkApplication和GtkWindow子类化,或者单窗口快速和讨厌的应用程序只是GtkWindow的子类.您的决定取决于您的应用需求.

技术差异:两个示例的实现方式之间也存在重要的技术差异.仅使用GtkWindow的示例为程序的每个实例创建一个新的Gtk主循环.GtkApplication的示例创建了一个附加到第一个实例的单个主循环,每个后续调用run(None)将请求原始实例创建一个新窗口(然后新实例将退出).尝试打开两个终端并在每个窗口中运行应用程序,注意一个终端将等待所有窗口关闭,然后再次变得敏感.您可以使用G_APPLICATION_NON_UNIQUE而不是更改此行为G_APPLICATION_FLAGS_NONE.


val*_*ynd 6

第二个代码示例看起来不必要复杂,第一个看起来非常好.第二个教程的作者已经将链接指向了另一个更简单的示例(Source):

from gi.repository import Gtk

window = Gtk.Window(title="Hello World")
window.connect("destroy", lambda w: Gtk.main_quit())
window.add(Gtk.Label("Hello World!"))
window.show_all()

Gtk.main()
Run Code Online (Sandbox Code Playgroud)

两种方法都没有错.您可以使用所有默认小部件,而不是子类化任何内容,如上例所示.或者你可以子类化某些小部件,主要是为了给你的代码一个很好的结构,并最终有可重用的自定义/修改小部件.这完全取决于你.

这同样适用于Qt和许多其他GUI框架,顺便说一下.


小智 6

第二种方法更好.它使应用程序更加集成到桌面中,并更多地了解它的功能或意图.它还为您提供了更多可用于您的应用程序的工具.

我认为第一种方法不是最新的或类似的东西.第二个是真正的首选方式.

您可以看到应用程序Gnome-music实际上正在使用Gtk.Application用法的第二种方法.所有官方Gnome应用程序都使用Gtk.Application,所有Gtk应用程序也应该使用它.