Python论坛  - 讨论区

标题:[python-chinese] 用于 Python 的高级 GUI 库[ת]

2005年12月01日 星期四 19:47

batfree batfreelist at gmail.com
Thu Dec 1 19:47:43 HKT 2005

我不看好PyQT,因为有版权问题,而且没多少人支持,目前看好的是PyGTK和
wxPython,这二者发展都有前途。而且用的人多。pygtk的背后是Gnome,wxPython
背后是wxWidget,好像是有Borland支持。PyQT我都不知道Trolltech是不是支持他
的发展。

jejwe wrote:
> Qt 工具箱是一个使用广泛的跨平台 GUI 工具箱,可用于 Windows、Linux、Mac
> OSX 和许多手持平台。QT 具有良好结构化(但灵活)的面向对象的结构、清晰的
> 文档以及直观的 API。本文中,David Mertz 和 Boudewijn Rempt 探讨了 Qt
> 库,集中讨论了允许 Python 程序员访问 Qt 功能的 PyQt 绑定。
> 一般来说,选择用于应用程序的 GUI 工具箱会是一件棘手的事。使用 Python(许
> 多语言也一样)的程序员可以选择的 GUI 工具箱种类繁多,而每个工具箱都有各
> 自的优缺点。有些速度比其它工具箱快,有些比较小;有些易于安装,有些更适合
> 于跨平台使用(对于这一点,还要指出,有些支持您需要满足的特定特性)。当
> 然,各种库都相应具有各种许可证。
> 
> 对于 Python 程序员而言,缺省的 GUI 选择是 Tk(通过 Tkinter 绑定)— 其原
> 因显而易见。Tkinter 和闲置的 IDE 是由 Python 创始人编写的,它们是作为大
> 多数 Python 分发版的缺省选择而出现的。标准 Python 文档讨论了 Tkinter,但
> 没有涉及任何其它 GUI 绑定。这是故意的!至少可以这么认为,如果 Tk 和
> Tkinter 不是这么糟糕,程序员就没有理由去寻找替代品了。要诱导 Python 程序
> 员放弃缺省选择,那么工具箱必须提供额外的东西。PyQt 就是这样一个工具箱。
> 
> PyQt 所具有的优点远远超过了 Tkinter(它也有几个缺点)。Qt 和 PyQt 速度都
> 很快;Qt 和 PyQt 的设计完全是面向对象的;Qt 提供了一个设计良好的窗口构件
> 集合,它比 Tk 所提供的要大得多。就其缺点而言,Qt 的许可证受到的限制比许
> 多工具箱(至少在非 Linux 平台方面)都多;正确安装 Qt 和 PyQt 常常会很复
> 杂;另外,Qt 是一个相当大的库。PyQt 应用程序的用户将需要设法完成安装 Qt
> 和 PyQt,这使分发变得很困难。(请阅读本文后面的用于其它语言的 Qt 绑定。)
> 
> PyQt 严格遵循 Qt 的发放许可。特别是,它可用于 UNIX/X11 平台上的 GPL,并
> 可用于 Zaurus 上的 Qt Palmtop Environment 环境,还存在用于较老的 Qt 版本
> 的免费(free-as-in-free-beer)Windows 软件包。PyQt 的商业许可证可用于
> Windows。
> 
> 对于本文而言,PyQt 有一个方面优于许多其它工具箱,它值得我们特别关注。Qt
> 使用一种称为信号/插槽(signals/slots)的机制在窗口构件(以及其它对象)
> 之间传递事件和消息。这种机制完全不同于包括 Tkinter 在内的大多数工具箱所
> 用的回调(callback)机制。使用信号/插槽以灵活且可维护的方式控制对象间通
> 信要比使用脆弱的回调风格容易得多。应用程序越大,Qt 的这个优势就越重要。
> 
> 本文的作者之一 Boudewijn Rempt 已经出版了一本有关使用 PyQt 进行应用程序
> 开发的书籍。GUI Programming with Python: QT Edition(请参阅参考资料)显
> 示了如何设计和开发完整的 GUI 应用程序,其中包括从最初的构思到分发的全过程。
> 
> 样本应用程序
> 要显示信号/插槽和回调之间的反差,我们提供了一个写着玩玩的应用程序,它使
> 用 Tkinter 和 PyQt。尽管实际上 PyQt 版本对于这个基本程序并不更简单,但是
> 它已经演示了 PyQt 应用程序更好的模块性和可维护性。
> 
> 应用程序包括四个窗口构件:
> 
> "Quit"按钮(用来与整个应用程序通信)
> "Log Timestamp"按钮(用于窗口构件间的消息)
> 文本区域,显示可滚动的已记录日志的时间戳记列表
> 消息窗口构件,显示已记录日志的时间戳记数
> 在 Tkinter 中,我们可以这样实现应用程序:
> 
> 
> 清单 1. Logger.py Tkinter 应用程序 #!/usr/bin/python
> import sys, time
> from Tkinter import *
> 
> class Logger(Frame):
>     def __init__(self):
>         Frame.__init__(self)
>         self.pack(expand=YES, fill=BOTH)
>         self.master.title("Timestamp logging application")
>         self.tslist = []
>         self.tsdisp = Text(height=6, width=25)
>         self.count = StringVar()
>         self.cntdisp = Message(font=('Sans',24),
>                                textvariable=self.count)
>         self.log = Button(text="Log Timestamp",
>                           command=self.log_timestamp)
>         self.quit = Button(text="Quit", command=sys.exit)
>         self.tsdisp.pack(side=LEFT)
>         self.cntdisp.pack ()
>         self.log.pack(side=TOP, expand=YES, fill=BOTH)
>         self.quit.pack(side=BOTTOM, fill=BOTH)
>     def log_timestamp(self):
>         stamp = time.ctime()
>         self.tsdisp.insert(END, stamp+"")
>         self.tsdisp.see(END)
>         self.tslist.append(stamp)
>         self.count.set("% 3d" % len(self.tslist))
> 
> if __name__=='__main__':
>     Logger().mainloop()
>  
> 
> 
> 这个 Tk 版本使用了 log_timestamp() 方法作为按钮的 command= 参数。这个方
> 法需要依次单独操作它要影响的所有窗口构件。如果我们想更改按钮按下的效果
> (例如还要记录时间戳记),那么这个风格就很脆弱。通过继承您可以实现这一点:
> 
> 清单 2. StdOutLogger.py Tkinter 增强 class StdOutLogger(Logger):
>     def log_timestamp(self):
>         Logger.log_timestamp(self)
>         print self.tslist[-1]
>  
> 
> 
> 但是这个子类的作者需要相当精确地理解 Logger.log_timestamp() 已经做了什
> 么;而且除非通过在子类中完全重写 .log_timestamp() 方法并且不调用父方法,
> 否则没有办法除去消息。
> 
> 一个非常基本的 PyQt 应用程序总有一些样本代码,这些代码在哪里都相同,
> Tkinter 代码也是这样。但是,当我们进一步研究设置应用程序所需的代码,以及
> 显示窗口构件的代码时,区别就显现出来了。
> 
> 清单 3. logger-qt.py PyQt 应用程序 #!/usr/bin/env python
> import sys, time
> from qt import * # Generally advertised as safe
> 
> class Logger(QWidget):
>     def __init__(self, *args):
>         QWidget.__init__(self, *args)
>         self.setCaption("Timestamp logging application")
>         self.layout = QGridLayout(self, 3, 2, 5, 10)
>         self.tsdisp = QTextEdit(self)
>         self.tsdisp.setMinimumSize(250, 300)
>         self.tsdisp.setTextFormat(Qt.PlainText)
>         self.tscount = QLabel("", self)
>         self.tscount.setFont (QFont("Sans", 24))
>         self.log = QPushButton("&Log; Timestamp", self)
>         self.quit = QPushButton("&Quit;", self)
>         self.layout.addMultiCellWidget(self.tsdisp, 0, 2, 0, 0)
>         self.layout.addWidget(self.tscount, 0, 1)
>         self.layout.addWidget(self.log, 1, 1)
>         self.layout.addWidget(self.quit, 2, 1)
>         self.connect(self.log, SIGNAL("clicked()"),
>                      self.log_timestamp)
>         self.connect(self.quit, SIGNAL("clicked()"),
>                      self.close)
>     def log_timestamp(self):
>         stamp = time.ctime()
>         self.tsdisp.append (stamp)
>         self.tscount.setText(str(self.tsdisp.lines()))
> if __name__ == "__main__":
>     app = QApplication(sys.argv)
>     app.connect(app, SIGNAL('lastWindowClosed()'), app,
>                   SLOT('quit()'))
>     logger = Logger()
>     logger.show()
>     app.setMainWidget(logger)
>     app.exec_loop()
>  
> 
> 
> 通过创建布局管理器,Logger 类开始工作了。布局管理器在任何 GUI 系统中都是
> 一个很复杂的主题,但是 Qt 的实现使之变得简单。在大多数情况下,您会使用
> Qt Designer 创建一般的 GUI 设计,随后可将它用于生成 Python 或 C++ 代码。
> 然后您可以使生成的代码生成子类,以添加功能。
> 
> 但是在这个示例中,我们选择手工创建布局管理器。窗口构件被置于网格的各个单
> 元中,或者可以跨多个单元放置。在 Tkinter 需要命名参数的地方,PyQt 就不允
> 许它们。这是一个很重要的差异,它经常会使在两种环境中工作的人们无所适从。
> 
> 所有 Qt 窗口构件都可以和 QString 对象很自然地一起工作,而不能和 Python
> 字符串或 Unicode 对象一起工作。幸运的是,转换是自动的。如果您在 Qt 方法
> 中使用了字符串或 Unicode 参数,那么它将自动转换成 QString。不能进行反向
> 转换:如果您调用了一个返回 QString 的方法,那么您获得的是 QString。
> 
> 应用程序中最有趣的部分是我们将 clicked 信号连接到功能的位置。一个按钮连
> 接到了 log_timestamp 方法;另一个连接到了 QWidget 类的 close 方法。
> 
> 图 1. logger-qt 的屏幕快照
> 
> 
> 现在我们想将日志记录添加到这个应用程序的标准输出。这十分容易。我们可以使
> Logger 类生成子类,或者为了演示,创建简单的独立函数:
> 
> 清单 4. logger-qt.py PyQt 增强 def logwrite():
>     print(time.ctime())
> 
> if __name__ == "__main__":
>    app = QApplication(sys.argv)
>    app.connect(app, SIGNAL('lastWindowClosed()'), app,
>                SLOT('quit()'))
>    logger = Logger()
>    QObject.connect(logger.log , SIGNAL("clicked()"), logwrite)
>    logger.show()
>    app.setMainWidget(logger)
>    app.exec_loop()
>  
> 
> 
> 从上述代码我们可以看到,这就是将 log QPushButton 的 clicked() 信号连接到
> 新函数的事情。注:信号也可以将任何数据传送到它们所连接的插槽,尽管在这里
> 我们没有显示这样的示例。
> 
> 如果您不想调用原始方法,那么可以从插槽 disconnect 信号,例如通过在
> logger.show() 行之前添加以下行:
> 
> 清单 5. logger-qt.py PyQt 增强 QObject.disconnect(logger.log,
> SIGNAL("clicked()"),
>                    logger.log_timestamp)
>  
> 
> 
> 现在将不再更新 GUI。
> 
> 用于 Python 的其它 GUI 绑定
> PyQt 在给定实例中可能不是很有用,可能是许可证状态问题,也可能是平台可用
> 性问题(或者,可能因为再分发很困难,例如大小很大)。由于这个原因(也为了
> 比较),我们想指出一些用于 Python 的其它流行 GUI 工具箱。
> 
> Anygui
> Anygui 实际上不是 GUI 工具箱,而是一个作用于大量工具箱(甚至是令人惊奇的
> 象 curses 和 Java/Jython Swing 那样的工具箱)的抽象包装器。在编程风格方
> 面,使用 Anygui 类似于使用 Tkinter,但是要选中这个底层工具箱,要么自动进
> 行,要么进行配置调用。Anygui 很好用,因为它允许应用程序未经更改就可以运
> 行在差异很大的平台上(但因此它支持受支持工具箱的"最低级公共特性")。
> PyGTK
> PyGTK 绑定包装了 GPL 下使用的 GTK 工具箱,它是流行的 Gnome 环境的基础。
> GTK 在根本上是 X Window 工具箱,但是它还有 Win32 的 beta 级支持和 BeOS
> 的 alpha 级支持。在常规范例中,PyGTK 对窗口构件使用回调。绑定存在于 GTK
> 和大量编程语言之间,而不仅仅是 Qt,或甚至是 Tk。
> FXPy
> Python 绑定 FXPy 包装了 FOX 工具箱。FOX 工具箱已经被移植到大多数类 UNIX
> 平台上,以及 Win32 上。与大多数工具箱类似,FOX 和 FXPy 都使用回调范例。
> FOX 由 LGPL 特许。
> wxPython
> 这个绑定包装了 wxWindows 工具箱。与 FOX 或 GTK 类似,wxWindows 被移植到
> Win32 和类 UNIX 平台上(但是没有移植到 MacOS、OS/2、BeOS 或其它"次要"平
> 台上 — 尽管它对 MacOSX 的支持是 alpha 级的)。在范例方面,wxPython 接近
> 回调风格。wxPython 对继承结构的关注程度高于大多数其它工具箱,而且它使用"
> 事件",而不是回调。但是本质上,事件仍旧被连接到单个方法上,随后可能需要
> 作用于各种窗口构件。
> win32ui
> win32ui 属于 win32all 软件包,它包装了 MFC 类。很显然,这个工具箱是特定
> 于 Win32 的库。MFC 实际上不只是 GUI 工具箱,它还使用各种范例的混合。对于
> 想创建 Windows 应用程序的读者而言,与其它工具箱相比,win32ui 会让您"更接
> 近于实质"。
> 
> 从其它语言使用 Qt
> 如同 Python,从大量其它编程语言使用 Qt 工具箱是可能的。如果可以自由选
> 择,我们会首选 Python,而不是其它语言。诸如公司政策以及与其它代码库连接
> 之类的外部约束可以决定编程语言的选择。Qt 的原始语言是 C++,但也有用于
> C、Java、Perl 和 Ruby 的绑定。就与 Python 示例的比较而言,让我们讨论一下
> 用 Ruby 和 Java 写着玩玩的应用程序。
> 
> Ruby/Qt 在用法上十分类似于 PyQt。这两种语言具有相似的动态性和简明性,所
> 以除了拼写上的差别外,其代码很类似:
> 
> 清单 6. HelloWorld.rb Qt2 应用程序 #!/usr/local/bin/ruby
> require 'qt2'
> include Qt2
> a = QApplication.new([$0] + ARGV)
> hello = QPushButton.new('Hello world!')
> hello.resize(100, 30)
> a.connect( hello, QSIGNAL('clicked()'), a, QSLOT('quit()'))
> a.setMainWidget(hello)
> hello.show
> a.exec
>  
> 
> 
> Java 总是比脚本编制语言要冗长一点,但是基本部分都相同。一个同等功能的最
> 小 qtjava 应用程序类似于:
> 
> 清单 7. HelloWorld.java Qt2 应用程序 import org.kde.qt.*;
> public class HelloWorld {
>   public static void main(String[] args)
>   {
>     QApplication myapp = new QApplication(args);
>     QPushButton hello = new QPushButton("Hello World", null);
>     hello.resize(100,30);
>     myapp.connect(hello, SIGNAL("clicked"),
>                   this, SLOT("quit()"));
>     myapp.setMainWidget(hello);
>     hello.show();
>     myapp.exec();
>     return;
>   }
>   static {
>     System.loadLibrary("qtjava");
>     try {
>         Class c = Class.forName("org.kde.qt.qtjava");
>     } catch (Exception e) {
>         System.out.println("Can't load qtjava class");
>     }
>   }
> }
>  
> 
> 
> PyQt 是一个吸引人和快速的接口,它将 Qt 工具箱和 Python 编程语言集成在一
> 起。除了该工具箱提供的种类繁多的窗口构件外,Qt 所用的信号/插槽编程风格
> 在生产能力和可维护性方面都要优于大多数其它 GUI 工具箱所用的回调风格。
> 
> 参考资料
> 
> 从 Riverbank 访问 PyQt 页面。
> 
> 
> GUI programming with Python(OpenDocs;2001 年)页面包含有关 Boudewijn
> Rempt 所写书籍的信息,以及有关 PyQt 的更多信息。
> 
> 
> 依照 Python.org,Tkinter 是 Python 的实际标准 GUI。在 David 撰写的
> developerWorks 文章"可爱的 Python:Python 中的 TK 编程 "中,您也可以了解
> 关于它的更多信息。
> 
> 
> 通常不需要下载 IDLE(因为目前它与每个 Python 分发版捆绑在一起),除非您
> 想使用实验版本或其它非标准的版本。如果是这样的话,您可以在 Python.org
> <http://Python.org> 的 IDLE 页面上找到这样的版本。
> 
> 
> 在 SourceForge 您会找到 Anygui,David 撰写的 developerWorks 文章"可爱的
> Python:[anygui] 项目预览"中对它进行了概述。
> 
> 
> 您会发现 Cameron Laird's personal notes on Python GUIs 也很有趣。
> 
> 
> 用于 GTK 窗口构件集的 Python 绑定(Python Bindings for the GTK Widget
> Set,或简称 PyGTK)提供了到流行的 GKT 窗口构件集的面向对象接口。
> 
> 
> FXPy 是一个扩展模块,它提供了到 FOX GUI 库的接口。
> 
> 
> 如果您必须使用 wxWindows C++ 类库,那么您会发现 wxPython 非常有帮助。
> 
> 
> win32ui 模块封装了 Microsoft Foundation Class。它是分布式的,它和
> Pythonwin 都属于 win32all 安装软件包。
> 
> 
> 在 developerWorks Linux 专区查找更多 Linux 开发人员资料。
> 
> 关于作者
> Boudewijn Rempt 编写了一本有关 PyQt 的书籍,已由 Opendocs 出版,书名为
> GUI Programming with Python: QT Edition。在印刷出版的文档中,本书的实用
> 性将 PyQt 提升到与 Tkinter 同等的位置。可以通过 boud at valdyas.org
> boud at valdyas.org> 与 Boudewijn 联系。
> 
> David Mertz 希望百花齐放。可以通过 mertz at gnosis.cx
> mertz at gnosis.cx> 与 David 联系;http://gnosis.cx/publish/ 介绍了
> 他的生活。欢迎对过去的、这一篇或将来的专栏文章提出意见和建议。请访问他即
> 将出版的书籍 Text Processing in Python 的 Web 页面。
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> python-chinese
> Post: send python-chinese at lists.python.cn
> Subscribe: send subscribe to python-chinese-request at lists.python.cn
> Unsubscribe: send unsubscribe to  python-chinese-request at lists.python.cn
> Detail Info: http://python.cn/mailman/listinfo/python-chinese

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年12月02日 星期五 11:11

doudou doudou.du at gmail.com
Fri Dec 2 11:11:43 HKT 2005

错鸟,gg,奇趣已经在去年release了一个GPL的的port,详情在limdou的blog也有。pyQT非常的强大。。。当然wxPython也很好。。。

2005/12/1, batfree <batfreelist at gmail.com>:
>
> 我不看好PyQT,因为有版权问题,而且没多少人支持,目前看好的是PyGTK和
> wxPython,这二者发展都有前途。而且用的人多。pygtk的背后是Gnome,wxPython
> 背后是wxWidget,好像是有Borland支持。PyQT我都不知道Trolltech是不是支持他
> 的发展。
>
> jejwe wrote:
> > Qt 工具箱是一个使用广泛的跨平台 GUI 工具箱,可用于 Windows、Linux、Mac
> > OSX 和许多手持平台。QT 具有良好结构化(但灵活)的面向对象的结构、清晰的
> > 文档以及直观的 API。本文中,David Mertz 和 Boudewijn Rempt 探讨了 Qt
> > 库,集中讨论了允许 Python 程序员访问 Qt 功能的 PyQt 绑定。
> > 一般来说,选择用于应用程序的 GUI 工具箱会是一件棘手的事。使用 Python(许
> > 多语言也一样)的程序员可以选择的 GUI 工具箱种类繁多,而每个工具箱都有各
> > 自的优缺点。有些速度比其它工具箱快,有些比较小;有些易于安装,有些更适合
> > 于跨平台使用(对于这一点,还要指出,有些支持您需要满足的特定特性)。当
> > 然,各种库都相应具有各种许可证。
> >
> > 对于 Python 程序员而言,缺省的 GUI 选择是 Tk(通过 Tkinter 绑定)― 其原
> > 因显而易见。Tkinter 和闲置的 IDE 是由 Python 创始人编写的,它们是作为大
> > 多数 Python 分发版的缺省选择而出现的。标准 Python 文档讨论了 Tkinter,但
> > 没有涉及任何其它 GUI 绑定。这是故意的!至少可以这么认为,如果 Tk 和
> > Tkinter 不是这么糟糕,程序员就没有理由去寻找替代品了。要诱导 Python 程序
> > 员放弃缺省选择,那么工具箱必须提供额外的东西。PyQt 就是这样一个工具箱。
> >
> > PyQt 所具有的优点远远超过了 Tkinter(它也有几个缺点)。Qt 和 PyQt 速度都
> > 很快;Qt 和 PyQt 的设计完全是面向对象的;Qt 提供了一个设计良好的窗口构件
> > 集合,它比 Tk 所提供的要大得多。就其缺点而言,Qt 的许可证受到的限制比许
> > 多工具箱(至少在非 Linux 平台方面)都多;正确安装 Qt 和 PyQt 常常会很复
> > 杂;另外,Qt 是一个相当大的库。PyQt 应用程序的用户将需要设法完成安装 Qt
> > 和 PyQt,这使分发变得很困难。(请阅读本文后面的用于其它语言的 Qt 绑定。)
> >
> > PyQt 严格遵循 Qt 的发放许可。特别是,它可用于 UNIX/X11 平台上的 GPL,并
> > 可用于 Zaurus 上的 Qt Palmtop Environment 环境,还存在用于较老的 Qt 版本
> > 的免费(free-as-in-free-beer)Windows 软件包。PyQt 的商业许可证可用于
> > Windows。
> >
> > 对于本文而言,PyQt 有一个方面优于许多其它工具箱,它值得我们特别关注。Qt
> > 使用一种称为信号/插槽(signals/slots)的机制在窗口构件(以及其它对象)
> > 之间传递事件和消息。这种机制完全不同于包括 Tkinter 在内的大多数工具箱所
> > 用的回调(callback)机制。使用信号/插槽以灵活且可维护的方式控制对象间通
> > 信要比使用脆弱的回调风格容易得多。应用程序越大,Qt 的这个优势就越重要。
> >
> > 本文的作者之一 Boudewijn Rempt 已经出版了一本有关使用 PyQt 进行应用程序
> > 开发的书籍。GUI Programming with Python: QT Edition(请参阅参考资料)显
> > 示了如何设计和开发完整的 GUI 应用程序,其中包括从最初的构思到分发的全过程。
> >
> > 样本应用程序
> > 要显示信号/插槽和回调之间的反差,我们提供了一个写着玩玩的应用程序,它使
> > 用 Tkinter 和 PyQt。尽管实际上 PyQt 版本对于这个基本程序并不更简单,但是
> > 它已经演示了 PyQt 应用程序更好的模块性和可维护性。
> >
> > 应用程序包括四个窗口构件:
> >
> > "Quit"按钮(用来与整个应用程序通信)
> > "Log Timestamp"按钮(用于窗口构件间的消息)
> > 文本区域,显示可滚动的已记录日志的时间戳记列表
> > 消息窗口构件,显示已记录日志的时间戳记数
> > 在 Tkinter 中,我们可以这样实现应用程序:
> >
> >
> > 清单 1. Logger.py Tkinter 应用程序 #!/usr/bin/python
> > import sys, time
> > from Tkinter import *
> >
> > class Logger(Frame):
> >     def __init__(self):
> >         Frame.__init__(self)
> >         self.pack(expand=YES, fill=BOTH)
> >         self.master.title("Timestamp logging application")
> >         self.tslist = []
> >         self.tsdisp = Text(height=6, width=25)
> >         self.count = StringVar()
> >         self.cntdisp = Message(font=('Sans',24),
> >                                textvariable=self.count)
> >         self.log = Button(text="Log Timestamp",
> >                           command=self.log_timestamp)
> >         self.quit = Button(text="Quit", command=sys.exit)
> >         self.tsdisp.pack(side=LEFT)
> >         self.cntdisp.pack ()
> >         self.log.pack(side=TOP, expand=YES, fill=BOTH)
> >         self.quit.pack(side=BOTTOM, fill=BOTH)
> >     def log_timestamp(self):
> >         stamp = time.ctime()
> >         self.tsdisp.insert(END, stamp+"")
> >         self.tsdisp.see(END)
> >         self.tslist.append(stamp)
> >         self.count.set("% 3d" % len(self.tslist))
> >
> > if __name__=='__main__':
> >     Logger().mainloop()
> >
> >
> >
> > 这个 Tk 版本使用了 log_timestamp() 方法作为按钮的 command= 参数。这个方
> > 法需要依次单独操作它要影响的所有窗口构件。如果我们想更改按钮按下的效果
> > (例如还要记录时间戳记),那么这个风格就很脆弱。通过继承您可以实现这一点:
> >
> > 清单 2. StdOutLogger.py Tkinter 增强 class StdOutLogger(Logger):
> >     def log_timestamp(self):
> >         Logger.log_timestamp(self)
> >         print self.tslist[-1]
> >
> >
> >
> > 但是这个子类的作者需要相当精确地理解 Logger.log_timestamp() 已经做了什
> > 么;而且除非通过在子类中完全重写 .log_timestamp() 方法并且不调用父方法,
> > 否则没有办法除去消息。
> >
> > 一个非常基本的 PyQt 应用程序总有一些样本代码,这些代码在哪里都相同,
> > Tkinter 代码也是这样。但是,当我们进一步研究设置应用程序所需的代码,以及
> > 显示窗口构件的代码时,区别就显现出来了。
> >
> > 清单 3. logger-qt.py PyQt 应用程序 #!/usr/bin/env python
> > import sys, time
> > from qt import * # Generally advertised as safe
> >
> > class Logger(QWidget):
> >     def __init__(self, *args):
> >         QWidget.__init__(self, *args)
> >         self.setCaption("Timestamp logging application")
> >         self.layout = QGridLayout(self, 3, 2, 5, 10)
> >         self.tsdisp = QTextEdit(self)
> >         self.tsdisp.setMinimumSize(250, 300)
> >         self.tsdisp.setTextFormat(Qt.PlainText)
> >         self.tscount = QLabel("", self)
> >         self.tscount.setFont (QFont("Sans", 24))
> >         self.log = QPushButton("&Log; Timestamp", self)
> >         self.quit = QPushButton("&Quit;", self)
> >         self.layout.addMultiCellWidget(self.tsdisp, 0, 2, 0, 0)
> >         self.layout.addWidget(self.tscount, 0, 1)
> >         self.layout.addWidget(self.log, 1, 1)
> >         self.layout.addWidget(self.quit, 2, 1)
> >         self.connect(self.log, SIGNAL("clicked()"),
> >                      self.log_timestamp)
> >         self.connect(self.quit, SIGNAL("clicked()"),
> >                      self.close)
> >     def log_timestamp(self):
> >         stamp = time.ctime()
> >         self.tsdisp.append (stamp)
> >         self.tscount.setText(str(self.tsdisp.lines()))
> > if __name__ == "__main__":
> >     app = QApplication(sys.argv)
> >     app.connect(app, SIGNAL('lastWindowClosed()'), app,
> >                   SLOT('quit()'))
> >     logger = Logger()
> >     logger.show()
> >     app.setMainWidget(logger)
> >     app.exec_loop()
> >
> >
> >
> > 通过创建布局管理器,Logger 类开始工作了。布局管理器在任何 GUI 系统中都是
> > 一个很复杂的主题,但是 Qt 的实现使之变得简单。在大多数情况下,您会使用
> > Qt Designer 创建一般的 GUI 设计,随后可将它用于生成 Python 或 C++ 代码。
> > 然后您可以使生成的代码生成子类,以添加功能。
> >
> > 但是在这个示例中,我们选择手工创建布局管理器。窗口构件被置于网格的各个单
> > 元中,或者可以跨多个单元放置。在 Tkinter 需要命名参数的地方,PyQt 就不允
> > 许它们。这是一个很重要的差异,它经常会使在两种环境中工作的人们无所适从。
> >
> > 所有 Qt 窗口构件都可以和 QString 对象很自然地一起工作,而不能和 Python
> > 字符串或 Unicode 对象一起工作。幸运的是,转换是自动的。如果您在 Qt 方法
> > 中使用了字符串或 Unicode 参数,那么它将自动转换成 QString。不能进行反向
> > 转换:如果您调用了一个返回 QString 的方法,那么您获得的是 QString。
> >
> > 应用程序中最有趣的部分是我们将 clicked 信号连接到功能的位置。一个按钮连
> > 接到了 log_timestamp 方法;另一个连接到了 QWidget 类的 close 方法。
> >
> > 图 1. logger-qt 的屏幕快照
> >
> >
> > 现在我们想将日志记录添加到这个应用程序的标准输出。这十分容易。我们可以使
> > Logger 类生成子类,或者为了演示,创建简单的独立函数:
> >
> > 清单 4. logger-qt.py PyQt 增强 def logwrite():
> >     print(time.ctime())
> >
> > if __name__ == "__main__":
> >    app = QApplication(sys.argv)
> >    app.connect(app, SIGNAL('lastWindowClosed()'), app,
> >                SLOT('quit()'))
> >    logger = Logger()
> >    QObject.connect(logger.log , SIGNAL("clicked()"), logwrite)
> >    logger.show()
> >    app.setMainWidget(logger)
> >    app.exec_loop()
> >
> >
> >
> > 从上述代码我们可以看到,这就是将 log QPushButton 的 clicked() 信号连接到
> > 新函数的事情。注:信号也可以将任何数据传送到它们所连接的插槽,尽管在这里
> > 我们没有显示这样的示例。
> >
> > 如果您不想调用原始方法,那么可以从插槽 disconnect 信号,例如通过在
> > logger.show() 行之前添加以下行:
> >
> > 清单 5. logger-qt.py PyQt 增强 QObject.disconnect(logger.log,
> > SIGNAL("clicked()"),
> >                    logger.log_timestamp)
> >
> >
> >
> > 现在将不再更新 GUI。
> >
> > 用于 Python 的其它 GUI 绑定
> > PyQt 在给定实例中可能不是很有用,可能是许可证状态问题,也可能是平台可用
> > 性问题(或者,可能因为再分发很困难,例如大小很大)。由于这个原因(也为了
> > 比较),我们想指出一些用于 Python 的其它流行 GUI 工具箱。
> >
> > Anygui
> > Anygui 实际上不是 GUI 工具箱,而是一个作用于大量工具箱(甚至是令人惊奇的
> > 象 curses 和 Java/Jython Swing 那样的工具箱)的抽象包装器。在编程风格方
> > 面,使用 Anygui 类似于使用 Tkinter,但是要选中这个底层工具箱,要么自动进
> > 行,要么进行配置调用。Anygui 很好用,因为它允许应用程序未经更改就可以运
> > 行在差异很大的平台上(但因此它支持受支持工具箱的"最低级公共特性")。
> > PyGTK
> > PyGTK 绑定包装了 GPL 下使用的 GTK 工具箱,它是流行的 Gnome 环境的基础。
> > GTK 在根本上是 X Window 工具箱,但是它还有 Win32 的 beta 级支持和 BeOS
> > 的 alpha 级支持。在常规范例中,PyGTK 对窗口构件使用回调。绑定存在于 GTK
> > 和大量编程语言之间,而不仅仅是 Qt,或甚至是 Tk。
> > FXPy
> > Python 绑定 FXPy 包装了 FOX 工具箱。FOX 工具箱已经被移植到大多数类 UNIX
> > 平台上,以及 Win32 上。与大多数工具箱类似,FOX 和 FXPy 都使用回调范例。
> > FOX 由 LGPL 特许。
> > wxPython
> > 这个绑定包装了 wxWindows 工具箱。与 FOX 或 GTK 类似,wxWindows 被移植到
> > Win32 和类 UNIX 平台上(但是没有移植到 MacOS、OS/2、BeOS 或其它"次要"平
> > 台上 ― 尽管它对 MacOSX 的支持是 alpha 级的)。在范例方面,wxPython 接近
> > 回调风格。wxPython 对继承结构的关注程度高于大多数其它工具箱,而且它使用"
> > 事件",而不是回调。但是本质上,事件仍旧被连接到单个方法上,随后可能需要
> > 作用于各种窗口构件。
> > win32ui
> > win32ui 属于 win32all 软件包,它包装了 MFC 类。很显然,这个工具箱是特定
> > 于 Win32 的库。MFC 实际上不只是 GUI 工具箱,它还使用各种范例的混合。对于
> > 想创建 Windows 应用程序的读者而言,与其它工具箱相比,win32ui 会让您"更接
> > 近于实质"。
> >
> > 从其它语言使用 Qt
> > 如同 Python,从大量其它编程语言使用 Qt 工具箱是可能的。如果可以自由选
> > 择,我们会首选 Python,而不是其它语言。诸如公司政策以及与其它代码库连接
> > 之类的外部约束可以决定编程语言的选择。Qt 的原始语言是 C++,但也有用于
> > C、Java、Perl 和 Ruby 的绑定。就与 Python 示例的比较而言,让我们讨论一下
> > 用 Ruby 和 Java 写着玩玩的应用程序。
> >
> > Ruby/Qt 在用法上十分类似于 PyQt。这两种语言具有相似的动态性和简明性,所
> > 以除了拼写上的差别外,其代码很类似:
> >
> > 清单 6. HelloWorld.rb Qt2 应用程序 #!/usr/local/bin/ruby
> > require 'qt2'
> > include Qt2
> > a = QApplication.new([$0] + ARGV)
> > hello = QPushButton.new('Hello world!')
> > hello.resize(100, 30)
> > a.connect( hello, QSIGNAL('clicked()'), a, QSLOT('quit()'))
> > a.setMainWidget(hello)
> > hello.show
> > a.exec
> >
> >
> >
> > Java 总是比脚本编制语言要冗长一点,但是基本部分都相同。一个同等功能的最
> > 小 qtjava 应用程序类似于:
> >
> > 清单 7. HelloWorld.java Qt2 应用程序 import org.kde.qt.*;
> > public class HelloWorld {
> >   public static void main(String[] args)
> >   {
> >     QApplication myapp = new QApplication(args);
> >     QPushButton hello = new QPushButton("Hello World", null);
> >     hello.resize(100,30);
> >     myapp.connect(hello, SIGNAL("clicked"),
> >                   this, SLOT("quit()"));
> >     myapp.setMainWidget(hello);
> >     hello.show();
> >     myapp.exec();
> >     return;
> >   }
> >   static {
> >     System.loadLibrary("qtjava");
> >     try {
> >         Class c = Class.forName("org.kde.qt.qtjava");
> >     } catch (Exception e) {
> >         System.out.println("Can't load qtjava class");
> >     }
> >   }
> > }
> >
> >
> >
> > PyQt 是一个吸引人和快速的接口,它将 Qt 工具箱和 Python 编程语言集成在一
> > 起。除了该工具箱提供的种类繁多的窗口构件外,Qt 所用的信号/插槽编程风格
> > 在生产能力和可维护性方面都要优于大多数其它 GUI 工具箱所用的回调风格。
> >
> > 参考资料
> >
> > 从 Riverbank 访问 PyQt 页面。
> >
> >
> > GUI programming with Python(OpenDocs;2001 年)页面包含有关 Boudewijn
> > Rempt 所写书籍的信息,以及有关 PyQt 的更多信息。
> >
> >
> > 依照 Python.org,Tkinter 是 Python 的实际标准 GUI。在 David 撰写的
> > developerWorks 文章"可爱的 Python:Python 中的 TK 编程 "中,您也可以了解
> > 关于它的更多信息。
> >
> >
> > 通常不需要下载 IDLE(因为目前它与每个 Python 分发版捆绑在一起),除非您
> > 想使用实验版本或其它非标准的版本。如果是这样的话,您可以在 Python.org
> > <http://Python.org> 的 IDLE 页面上找到这样的版本。
> >
> >
> > 在 SourceForge 您会找到 Anygui,David 撰写的 developerWorks 文章"可爱的
> > Python:[anygui] 项目预览"中对它进行了概述。
> >
> >
> > 您会发现 Cameron Laird's personal notes on Python GUIs 也很有趣。
> >
> >
> > 用于 GTK 窗口构件集的 Python 绑定(Python Bindings for the GTK Widget
> > Set,或简称 PyGTK)提供了到流行的 GKT 窗口构件集的面向对象接口。
> >
> >
> > FXPy 是一个扩展模块,它提供了到 FOX GUI 库的接口。
> >
> >
> > 如果您必须使用 wxWindows C++ 类库,那么您会发现 wxPython 非常有帮助。
> >
> >
> > win32ui 模块封装了 Microsoft Foundation Class。它是分布式的,它和
> > Pythonwin 都属于 win32all 安装软件包。
> >
> >
> > 在 developerWorks Linux 专区查找更多 Linux 开发人员资料。
> >
> > 关于作者
> > Boudewijn Rempt 编写了一本有关 PyQt 的书籍,已由 Opendocs 出版,书名为
> > GUI Programming with Python: QT Edition。在印刷出版的文档中,本书的实用
> > 性将 PyQt 提升到与 Tkinter 同等的位置。可以通过 boud at valdyas.org
> > boud at valdyas.org> 与 Boudewijn 联系。
> >
> > David Mertz 希望百花齐放。可以通过 mertz at gnosis.cx
> > mertz at gnosis.cx> 与 David 联系;http://gnosis.cx/publish/ 介绍了
> > 他的生活。欢迎对过去的、这一篇或将来的专栏文章提出意见和建议。请访问他即
> > 将出版的书籍 Text Processing in Python 的 Web 页面。
> >
> >
> > ------------------------------------------------------------------------
> >
> > _______________________________________________
> > python-chinese
> > Post: send python-chinese at lists.python.cn
> > Subscribe: send subscribe to python-chinese-request at lists.python.cn
> > Unsubscribe: send unsubscribe to  python-chinese-request at lists.python.cn
> > Detail Info: http://python.cn/mailman/listinfo/python-chinese
> _______________________________________________
> python-chinese
> Post: send python-chinese at lists.python.cn
> Subscribe: send subscribe to python-chinese-request at lists.python.cn
> Unsubscribe: send unsubscribe to  python-chinese-request at lists.python.cn
> Detail Info: http://python.cn/mailman/listinfo/python-chinese
>



--
像实干家一样思考问题,像思想家一样付诸行动...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20051202/5e0ec687/attachment.html

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年12月02日 星期五 16:37

Hong Yuan hongyuan at homemaster.cn
Fri Dec 2 16:37:54 HKT 2005

这里有一篇详细比较pyGTK/pyQT/wxPython的文章,值得推荐给大家。

http://myddrin.com/trashdeerwood/?p=67

-- 
HONG Yuan

大管家网上建材超市
http://www.homemaster.cn
Tel: 021-50941728
Fax: 021-50941727


[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年12月02日 星期五 18:01

ONE_Fox onefox.fox at gmail.com
Fri Dec 2 18:01:44 HKT 2005

要比 API 强大? 那 Java 的 Swing 算可以了

但还是一个花瓶
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20051202/5b1763f3/attachment.htm

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

如下红色区域有误,请重新填写。

    你的回复:

    请 登录 后回复。还没有在Zeuux哲思注册吗?现在 注册 !

    Zeuux © 2025

    京ICP备05028076号