我刚开始学习如何在Python中创建GUI应用程序。我决定使用Gtk版本3。 根据{{3}}上的(官方?)教程,构建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()
在其他教程(http://python-gtk-3-tutorial.readthedocs.org/)中,我找到了完全不同的方法:
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)
这个类别中有经验的人能告诉我这些天我应该以什么方式在python中编写Gtk 3应用程序?我已经熟悉编写GUI(在Java的Swing中花了几个月),所以你可以继续使用诸如事件,回调等术语。
答案 0 :(得分:14)
选择使用GtkApplication或GtkWindow编写新程序取决于您需要的功能,以及某种程度上的目标受众。
对于大多数情况,尤其是当你还在学习工具包时,我倾向于同意valmynd认为GtkApplication不必要地复杂化。 GtkApplication提供了许多额外的功能,您可能在较小的应用程序中不需要或不需要。
对于更大,更完整的应用程序,我同意Dragnucs,第二种方法更优越,可以更好地集成到桌面环境中。来自GNOME Goal: Port to 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
来更改此行为。
答案 1 :(得分: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()
这两种方法都没有错。您可以使用所有默认小部件,而不是子类化任何内容,如上例所示。或者你可以子类化某些小部件,主要是为了给你的代码一个很好的结构,并最终有可重用的自定义/修改小部件。这完全取决于你。
这同样适用于Qt和许多其他GUI框架,顺便说一句。
答案 2 :(得分:5)
第二种方法更好。它使应用程序更加集成到桌面中,并更多地了解它的功能或意图。它还为您提供了更多可用于您的应用程序的工具。
我认为第一种方法不是最新的或类似的东西。第二个是真正的首选方式。
您可以看到应用程序Gnome-music实际上正在使用second approach和Gtk.Application用法。所有官方Gnome应用程序都使用Gtk.Application,所有Gtk应用程序也应该使用它。