本文共 22572 字,大约阅读时间需要 75 分钟。
python qt5 框架
Python是一种流行的语言,能够编写脚本以及面向对象的程序。 几个框架提供了Python的GUI(图形用户界面),并且大多数框架都擅长于简单,高效或灵活的事情。 最受欢迎的两个是和 ,但它们如何比较? 更重要的是,您应该为项目选择哪个?
让我们来解决大多数用户首先要注意的内容-应用程序的外观。
Linux上的Thunar和WxPython
如果您使用的是KDE,则可以使用其他库来弥补原始PyQt与Linux和BSD上Plasma桌面的外观之间的差距,但这会增加新的依赖性。
Linux上的KDE和Qt
wxPython和PyQt都支持Linux,Windows和Mac,因此非常适合著名的跨平台Python。 但是,不要让“跨平台”一词蒙骗您-您仍然必须在Python代码中进行特定于平台的调整。 您的GUI工具包无法调整数据目录的路径格式,因此您仍然必须在python中使用os.path.join和一些不同的退出方法等来练习最佳实践。 您选择的GUI工具包不会神奇地从一个平台到另一个平台。
作为开发人员,您可能不介意获取应用程序所需的库所需的安装步骤。 但是,如果您打算分发应用程序,则需要考虑用户必须执行的安装过程才能运行应用程序。
但是,对于所有平台而言,PyQt也取决于Qt本身的C ++代码。 这意味着用户不仅必须安装PyQt,还必须安装所有Qt。 这不是一个小包装,需要很多单击,并可能逐步完成安装向导。 Qt和PyQt团队使安装尽可能容易,因此,尽管要求用户看起来似乎很多,但只要您提供直接链接,任何可以安装Web浏览器或游戏的用户应该能够与Qt安装抗衡。 如果您非常专心,甚至可以将安装脚本编写为自己的安装程序的一部分。
在Linux,BSD和Ilumos家族中,安装通常已经由发行版的软件包管理器为您编写了脚本。
PyQt和wxPython都具有您期望从GUI工具包获得的所有常用小部件,包括按钮,复选框,下拉菜单等。 两者都支持拖放操作,选项卡式界面,对话框以及自定义窗口小部件的创建。
移动Qt面板
只要您使用正确的小部件,这些功能就会内置,并且您无需重新设计花哨的技巧即可为高级用户提供友好的功能。
最终,wxPython毕竟只是wxWidgets的前端,因此,如果您确实需要某个功能,则可以在C ++中实现它,然后在wxPython中加以利用。 与PyQt相比,这是一个很高的要求。
GUI应用程序由许多较小的可视元素组成,通常称为“小部件”。 为了使GUI应用程序平稳运行,小部件必须彼此通信,例如,要显示图像的窗格知道用户选择了哪个缩略图。
它运行良好,只要您将其与lambda结合使用,它就是一个非常灵活的解决方案。 有时,根据您希望通信的复杂程度,您最终会得到比预期多得多的代码,但是它确实可以工作。
Qt中的信号和插槽( GFDL许可证)
有了信号和插槽,所有东西都可以签名。 发出信号的小部件不需要知道其消息的目的地是哪个插槽,甚至根本不需要知道它的目的地是哪个插槽。 只要您将信号连接到插槽,广播信号时,该插槽就会被信号的参数调用。
可以将插槽设置为侦听任何数量的信号,并且可以将信号设置为广播到任意数量的插槽。 您甚至可以将一个信号连接到另一个信号,以创建信号的连锁React。 您不必再回到代码中就可以手动将所有东西“连接”在一起。
信号和插槽可以采用任意数量的任何类型的参数。 在某些情况下,您不必编写代码即可过滤掉您所做或不希望做的事情。
更好的是,广告位不仅仅是听众; 它们是正常的功能,可以在有信号或无信号的情况下执行有用的操作。 正如对象不知道是否有任何东西正在监听其信号一样,插槽也不知道它是否正在监听信号。 没有代码块依赖于现有的连接。 如果有连接,它只会在不同时间触发。
不管您是否了解信号和插槽,一旦使用它们并尝试返回传统的回调,您都会上瘾。
在对GUI应用程序进行编程时,必须设计其布局,以便所有小部件都知道在应用程序窗口中出现的位置。 就像网页一样,您可以选择设计要调整大小的应用程序,也可以将其限制为固定大小。 在某些方面,这是GUI编程中最GUI的部分。
存在潜在的混乱点,主要是在基本级别的GUI元素中。 例如,如果您正在编写应用程序,是从QMainWindow还是QWidget开始以形成父窗口? 两者都可以作为您的应用程序的窗口,因此答案就如在计算中一样常见:这取决于。
QWidget是一个原始的空容器。 其他所有小部件都使用它,但这意味着它也可以按原样使用,以形成可在其中放置更多小部件的父窗口。 与其他所有小部件一样, QMainWindow也使用QWidget ,但是它添加了大多数应用程序所需的许多便利功能,例如顶部的工具栏,底部的状态栏等。
Q主窗口
一个使用QMainWindow的小型文本编辑器,仅使用100多行Python代码:
#!/usr/bin/env python # a minimal text editor to demo PyQt5 # GNU All-Permissive License # Copying and distribution of this file, with or without modification, # are permitted in any medium without royalty provided the copyright # notice and this notice are preserved. This file is offered as-is, # without any warranty. import sys import os import pickle from PyQt5 import * from PyQt5. QtWidgets import * from PyQt5. QtCore import * from PyQt5. QtGui import * class TextEdit ( QMainWindow ) : def __init__ ( self ) : super ( TextEdit , self ) . __init__ ( ) #font = QFont("Courier", 11) #self.setFont(font) self . filename = False self . Ui ( ) def Ui ( self ) : quitApp = QAction ( QIcon ( '/usr/share/icons/breeze-dark/actions/32/application-exit.svg' ) , 'Quit' , self ) saveFile = QAction ( QIcon ( '/usr/share/icons/breeze-dark/actions/32/document-save.svg' ) , 'Save' , self ) newFile = QAction ( 'New' , self ) openFile = QAction ( 'Open' , self ) copyText = QAction ( 'Copy' , self ) pasteText = QAction ( 'Yank' , self ) newFile. setShortcut ( 'Ctrl+N' ) newFile. triggered . connect ( self . newFile ) openFile. setShortcut ( 'Ctrl+O' ) openFile. triggered . connect ( self . openFile ) saveFile. setShortcut ( 'Ctrl+S' ) saveFile. triggered . connect ( self . saveFile ) quitApp. setShortcut ( 'Ctrl+Q' ) quitApp. triggered . connect ( self . close ) copyText. setShortcut ( 'Ctrl+K' ) copyText. triggered . connect ( self . copyFunc ) pasteText. setShortcut ( 'Ctrl+Y' ) pasteText. triggered . connect ( self . pasteFunc ) menubar = self . menuBar ( ) menubar. setNativeMenuBar ( True ) menuFile = menubar. addMenu ( '&File' ) menuFile. addAction ( newFile ) menuFile. addAction ( openFile ) menuFile. addAction ( saveFile ) menuFile. addAction ( quitApp ) menuEdit = menubar. addMenu ( '&Edit' ) menuEdit. addAction ( copyText ) menuEdit. addAction ( pasteText ) toolbar = self . addToolBar ( 'Toolbar' ) toolbar. addAction ( quitApp ) toolbar. addAction ( saveFile ) self . text = QTextEdit ( self ) self . setCentralWidget ( self . text ) self . setMenuWidget ( menubar ) self . setMenuBar ( menubar ) self . setGeometry ( 200 , 200 , 480 , 320 ) self . setWindowTitle ( 'TextEdit' ) self . show ( ) def copyFunc ( self ) : self . text . copy ( ) def pasteFunc ( self ) : self . text . paste ( ) def unSaved ( self ) : destroy = self . text . document ( ) . isModified ( ) print ( destroy ) if destroy == False : return False else : detour = QMessageBox. question ( self , "Hold your horses." , "File has unsaved changes. Save now?" , QMessageBox. Yes |QMessageBox. No | QMessageBox. Cancel ) if detour == QMessageBox. Cancel : return True elif detour == QMessageBox. No : return False elif detour == QMessageBox. Yes : return self . saveFile ( ) return True def saveFile ( self ) : self . filename = QFileDialog. getSaveFileName ( self , 'Save File' , os . path . expanduser ( '~' ) ) f = self . filename [ 0 ] with open ( f , "w" ) as CurrentFile: CurrentFile. write ( self . text . toPlainText ( ) ) CurrentFile. close ( ) def newFile ( self ) : if not self . unSaved ( ) : self . text . clear ( ) def openFile ( self ) : filename , _ = QFileDialog. getOpenFileName ( self , "Open File" , '' , "All Files (*)" ) try : self . text . setText ( open ( filename ) . read ( ) ) except : True def closeEvent ( self , event ) : if self . unSaved ( ) : event. ignore ( ) else : exit def main ( ) : app = QApplication ( sys . argv ) editor = TextEdit ( ) sys . exit ( app. exec_ ( ) ) if __name__ == '__main__' : main ( )
wx.Frame类扮演您和我认为的台式机窗口的传统角色。 要使用wx.Frame创建一个空窗口:
#!/usr/bin/env python # -*- coding: utf-8 -*- import wx class Myframe ( wx. Frame ) : def __init__ ( self , parent , title ) : super ( Myframe , self ) . __init__ ( parent , title = title , size = ( 520 , 340 ) ) self . Centre ( ) self . Show ( ) if __name__ == '__main__' : app = wx. App ( ) Myframe ( None , title = 'Just an empty frame' ) app. MainLoop ( )
将其他小部件放在wx.Frame窗口中,然后在构建GUI应用程序。 例如, wx.Panel小部件类似于HTML中具有绝对大小限制的div ,因此您可以使用它在主窗口中创建面板(除非它不是窗口,而是wx.Frame )。
与PyQt相比,WxPython的便利功能更少。 例如,复制和粘贴功能直接内置在PyQt中,而必须在wxPython中手动进行编码(并且仍然部分取决于其运行的平台)。 其中一些功能是由具有内置功能的优质台式机优雅地处理的,但是要实现与PyQt应用程序的功能相等,wxPython需要更多的手动工作。
框架
wxPython中的一个简单的文本编辑器:
#!/usr/bin/env python # a minimal text editor to demo wxPython # GNU All-Permissive License # Copying and distribution of this file, with or without modification, # are permitted in any medium without royalty provided the copyright # notice and this notice are preserved. This file is offered as-is, # without any warranty. import wx import os class TextEdit ( wx. Frame ) : def __init__ ( self , parent , title ) : wx. Frame . __init__ ( self , parent , wx. ID_ANY , title , size = ( 520 , 340 ) ) menuBar = wx. MenuBar ( ) menuFile = wx. Menu ( ) menuBar. Append ( menuFile , "&File" ) menuFile. Append ( 1 , "&Open" ) menuFile. Append ( 2 , "&Save" ) menuFile. Append ( 3 , "&Quit" ) self . SetMenuBar ( menuBar ) wx. EVT_MENU ( self , 1 , self . openAction ) wx. EVT_MENU ( self , 2 , self . saveAction ) wx. EVT_MENU ( self , 3 , self . quitAction ) self . p1 = wx. Panel ( self ) self . initUI ( ) def initUI ( self ) : self . text = wx. TextCtrl ( self . p1 , style = wx. TE_MULTILINE ) vbox = wx. BoxSizer ( wx. VERTICAL ) vbox. Add ( self . p1 , 1 , wx. EXPAND | wx. ALIGN_CENTER ) self . SetSizer ( vbox ) self . Bind ( wx. EVT_SIZE , self ._onSize ) self . Show ( ) def _onSize ( self , e ) : e. Skip ( ) self . text . SetSize ( self . GetClientSizeTuple ( ) ) def quitAction ( self , e ) : if self . text . IsModified ( ) : dlg = wx. MessageDialog ( self , "Quit? All changes will be lost." , "" , wx. YES_NO ) if dlg. ShowModal ( ) == wx. ID_YES : self . Close ( True ) else : self . saveAction ( self ) else : exit ( ) def openAction ( self , e ) : dlg = wx. FileDialog ( self , "File chooser" , os . path . expanduser ( '~' ) , "" , "*.*" , wx. OPEN ) if dlg. ShowModal ( ) == wx. ID_OK : filename = dlg. GetFilename ( ) dir = dlg. GetDirectory ( ) f = open ( os . path . join ( dir , filename ) , 'r' ) self . text . SetValue ( f. read ( ) ) f. close ( ) dlg. Destroy ( ) def saveAction ( self , e ) : dlg = wx. FileDialog ( self , "Save as" , os . path . expanduser ( '~' ) , "" , "*.*" , wx. SAVE | wx. OVERWRITE_PROMPT ) if dlg. ShowModal ( ) == wx. ID_OK : filedata = self . text . GetValue ( ) filename = dlg. GetFilename ( ) dir = dlg. GetDirectory ( ) f = open ( os . path . join ( dir , filename ) , 'w' ) f. write ( filedata ) f. close ( ) dlg. Destroy ( ) def main ( ) : app = wx. App ( False ) view = TextEdit ( None , "TextEdit" ) app. MainLoop ( ) if __name__ == '__main__' : main ( )
PyQt和wxPython GUI工具箱都有其优势。
另外,它使用本机窗口小部件,因此您的应用程序看起来应该与目标计算机上预装的应用程序没有什么不同。
但是,请不要太过wxPython关于跨平台的说法。 它有时在某些平台上有安装问题,并且没有太多的抽象层来保护您不受平台之间的差异的影响。
如果您只是刚入门,则应该尝试每种方式中的一点,看看哪个对您有吸引力。 如果您是一位经验丰富的程序员,请尝试一个尚未使用过的程序员,然后看看您的想法。 两者都是开源的,因此您不必仅选择一个。 要知道的重要一点是何时使用哪种解决方案。
骇客入侵。
翻译自:
python qt5 框架
转载地址:http://bzdzd.baihongyu.com/