布局相关类为最小值并且伸缩因子为stretch直到布局末尾
网络布局
网格布局(QGridLayout)顾名思义,将空间划分成多行多列的网络,然后通过addWidget、addItem将widget填充到指定的单元格(cell)。这个比较像网页中使用table布局的思路。下面的代码即创建上图中的网格布局:
grid = QGridLayout() grid.addWidget(setidLabel, 0, 0) grid.addWidget(self.setidLineEdit, 0, 1) grid.addWidget(QLabel("(第1位-2,第2~3位-表示适用角色,第4~5位-挂点位置,第6~8位-序号)"), 0, 2) grid.addWidget(subidLabel, 1, 0) grid.addWidget(self.subidLineEdit, 1, 1) grid.addWidget(QLabel("(套装包含的物品,多个物品适用逗号分隔;必须在套装之前添加)"), 1, 2) grid.addWidget(fashionLabel, 2, 0) grid.addWidget(self.fashionLineEdit, 2, 1) grid.addWidget(nameLabel, 3, 0) grid.addWidget(self.nameLineEdit, 3, 1) grid.addWidget(descLabel, 4, 0) grid.addWidget(self.descLineEdit, 4, 1) grid.addWidget(marketTagLabel, 5, 0) grid.addWidget(self.tagCombox, 5, 1) grid.addWidget(recommendLabel, 6, 0) grid.addWidget(self.recommendCombox, 6, 1) grid.addWidget(roleLabel, 8, 0) grid.addWidget(self.roleChkBoxGroup, 8, 1) grid.addWidget(beginLabel, 9, 0) grid.addWidget(self.beginTime, 9, 1) grid.addWidget(endLabel, 10, 0) grid.addWidget(self.endTime, 10, 1)
gridWidget = QWidget() gridWidget.setLayout(grid)
上述往网格中添加的widget都是占一个单元格的情况,其实还支持占用几个单元格。如下代码,往网格中的第二行、第一列添加一个widget,占用1行、2列:
grid.addWidget(self.createDetail(), 1, 0, 1, 2)
网格布局默认是均分每列,为了更好的控制布局,QGridLayout为每列提供了最小宽度(setColumnMinimumWidth())、伸缩因子(setColumnStretch()),为每行提供了最小高度(setRowMinimumHeight())、伸缩因子(setRowStretch())。最小宽/高度很好理解,伸缩因子如下面代码,设置了第二列和三列的比例是1:2。
layout.setColumnStretch(1, 10) layout.setColumnStretch(2, 20)
3. 二级弹窗
QDialog类是对话框窗口的基类。对话框窗口是主要用于短期任务以及和用户进行简要通讯的顶级窗口。QDialog可以是模态对话框也可以是非模态对话框。QDialog支持扩展性并且可以提供返回值。它们可以有默认按钮。
内置对话框
内置常用的对话框有:QColorDialog、QErrorMessage、QFileDialog、QFontDialog、QInputDialog、QMessageBox、QProgressDialog、QTabDialog、QWizard。
内置的对话框提供了一些常用的功能,使用起来也必将遍历。编写该工具使用到了,选择文件、目录的对话框QFileDialog。
自定义对话框
如果内置的对话框不能满足需求,可以自定义对话框(继承自QDialog)。如下定义了一个设置路径的对话框:

class SettingDialog(QDialog): def __init__(self, parent=None): super(SettingDialog, self).__init__(parent) self.path = Global.path self.initUI() self.setWindowIcon(QIcon("res/ico/settingPath.ico")) self.setWindowTitle("设置") self.resize(240, 100)
def initUI(self): grid = QGridLayout() grid.addWidget(QLabel("路径:"), 0, 0) self.pathLineEdit = QLineEdit() self.pathLineEdit.setFixedWidth(200) self.pathLineEdit.setText(Global.path) grid.addWidget(self.pathLineEdit, 0, 1) button = QPushButton("更改") button.clicked.connect(self.changePath) grid.addWidget(button, 0, 2) grid.addWidget(QLabel("<font color='#ff0000'>包含Keywords.xml、Avatar,AvatarSet,Market.xls的路径</font>"), 1, 0, 1, 3) buttonBox = QDialogButtonBox() buttonBox.setOrientation(Qt.Horizontal) # 设置为水平方向 buttonBox.setStandardButtons(QDialogButtonBox.Ok|QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.accept) # 确定 buttonBox.rejected.connect(self.reject) # 取消 grid.addWidget(buttonBox, 2, 1) self.setLayout(grid)
def changePath(self): open = QFileDialog() self.path = open.getExistingDirectory() self.pathLineEdit.setText(self.path) print(self.path)
使用对话框,只需要:
dialog = SettingDialog() if dialog.exec_(): # -----
4. 常用组件
下面介绍编写工具过程中使用到的组件的一些注意事项。
QTableWidget
列自适应
如果有很多列,QTableWidget出出现水平滚动条,但是有不希望有滚动条可以通过设置列自适应方式:
tw.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
保证所以列都能显示,不会出现水平滚动条,这样有的单元格显示会被截断显示,如图中的"青年套装下装"-->"青年套装...",这时可以设置单元的tooltip提供完整显示的途径。

禁止编辑
编写工具时,有要求QTableWidget展示出来的数据不能编辑,是通过以下方式实现:
tw.setEditTriggers(QAbstractItemView.NoEditTriggers)
QAbstractItemView还定义了其它的模式,如下表所示:
个问题:
l 点了下qtablewidget 的标题,它排序正常,修改数据,在查询,数据显示有问题
重新获取数据之前先关闭可排序性,获取到数据之后再开启排序性
l 排序规则问题,默认使用字母排序
使用以下方式设置单元格,会使用字母排序
item = QTableWidgetItem() item.setData(Qt.DisplayRole, "xxx")
或者
item = QTableWidgetItem() item.setText("xxx")
如果需要按照数值排序需要使用以下方式设置单元格
item = QTableWidgetItem() item.setData(Qt.DisplayRole, int(1212))
自定义单元格控件
可以对QTableWidget自定义(添加)widget,如下为QTableWidget设置单元格为一个下拉选择的QCombox
combox = QComboBox() for _, v in ParseKeyword.currencyType.items(): combox.addItem(v["cname"], v["value"]) combox.setCurrentText("点券") tw.setCellWidget(row, 1, combox)
效果如下图所示:

QDateTimeEdit
显示格式
默认的时间显示格式(如2015/1/16 17:42),可能不满足需求,可以通过setDisplayFormat()设置显示格式来定制。格式选项如下所示:
这些是可能用到的日期表达式:
l d - 没有前置0的数字的天(1-31)
l dd - 前置0的数字的天(01-31)
l ddd - 缩写的日名称(Mon-Sun)。使用QDate.shortDayName()。
l dddd - 长的日名称(Monday-Sunday)。使用QDate.longDayName()。
l M - 没有前置0的数字的月(1-12)
l MM - 前置0的数字的月(01-12)
l MMM - 缩写的月名称(Jan-Dec)。使用QDate.shortMonthName()。
l MMMM - 长的月名称(January-December)。使用QDate.longMonthName()。
l yy - 两位数字的年(00-99)
l yyyy - 四位数字的年(0000-9999)
这些是可能用到的时间表达式:
l h - 没有前置0的数字的小时(0-23或者如果显示AM/PM时,1-12)
l hh - 前置0的数字的小时(00-23或者如果显示AM/PM时,01-12)
l m - 没有前置0的数字的分钟(0-59)
l mm - 前置0的数字的分钟(00-59)
l s - 没有前置0的数字的秒(0-59)
l ss - 前置0的数字的秒(00-59)
l z - 没有前置0的数字的毫秒(0-999)
l zzz - 前置0的数字的毫秒(000-999)
l AP - 切换为AM/PM显示。AP将被“AM”或“PM”替换。
l ap - 切换为am/pm显示。ap将被“am”或“pm”替换。
如工具中使用的格式为:
setDisplayFormat("yyyy-MM-dd hh:mm:ss")
显示效果如下图所示:

弹出日期选择窗口
希望点击QDateTimeEdit可以弹出日期选择窗口,可以简单的通过setCalendarPopup(True)实现,非常的简单。
5. 打包
python常用的打包工具有py2exe、pyinstaller、cx_freeze,而且现在都开始支持python3,py2exe可以打包成单exe文件,一般简单的东西都是用它来打包供其他人使用。但是使用py2exe打包PyQt5时,碰到了不少错误,后面干脆使用cx_freeze打包一次成功(不足之处,就是不能打包成单个exe)。下面简单介绍编写setup.py几个关键的点,详细的参考官方文档(http://cx-freeze.readthedocs.org/en/latest/index.html)。
l 默认只会打包代码文件,如果程序有非代码文件,如配置、资源文件需要打包,需要显示指定。如"include_files": ["setting.ini", "res"],打包时会将setting.ini文件、res资源目录拷贝到exe目录下。
l cx_freeze会自动检测依赖文件,但是有时候会抽风,可以通过"packages": ["os", "xlrd3", "xlwt3", "lxml"]显示包含。同时对不要的包,可以"excludes": ["tkinter"]指定不要编译到最终的软件包中。
l 指定文件名需要带exe后缀,cx_freeze是不会自动添加exe后缀的。
l 如果需要一次编译多个exe,可以在executables数组中列出多个,例如:
executables = [ Executable("main.py", base=base, targetName="Joker3DAvatarMgr.exe", compress=True, icon="res/ico/icon.ico"),
Executable("test.py", base=base, targetName="test.exe", compress=True, icon="res/ico/test.ico") ]
完整的setup.py文件如下所示:
import sys from cx_Freeze import setup, Executable
# GUI applications require a different base on Windows (the default is for a # console application). base = None if sys.platform == "win32": base = "Win32GUI"
# Dependencies are automatically detected, but it might need fine tuning. build_exe_options = { "packages": ["os", "xlrd3", "xlwt3", "lxml"], "excludes": ["tkinter"], "include_files": ["setting.ini", "res"] }
# executables = [ Executable("main.py", base=base, targetName="Joker3DAvatarMgr.exe", compress=True, icon="res/ico/icon.ico") ]
setup( name = "setup", version = "0.1", description = "Joker3D prop manager tool!", author = "tylerzhu", author_email = "saylor.zhu@gmail.com", options = {"build_exe": build_exe_options}, executables = executables, )
编写好setup.py之后,可以通过python setup.py build打包。
网上有不少人反馈打包之后,放到没有按照PyQt的PC上执行,会报以下错误:“This application failed to start because it could not find or load the Qt platform plugin windows”

这个问题,我以前也碰到过,但是这次我用的Python3.4 + cx_freeze 4.3.4 + PyQt5-5.4-gpl-Py3.4-Qt5.4.0-x32.exe并没有出现这个问题。如果出现了这个问题也不要紧,通过以下方法可以解决:将PyQt5安装目录(Lib\site-packages\PyQt5)下的libGLESv2.dll拷到打包的exe目录下即可。
- 【Python开发】PyQt5应用与实践
一个典型的GUI应用程序可以抽象为:主界面(菜单栏.工具栏.状态栏.内容区域),二级界面(模态.非模态),信息提示(Tooltip),程序图标等组成.本篇根据作者使用PyQt5编写的一个工具,介绍如何 ...
- [ PyQt入门教程 ] PyQt5环境搭建和配置
PyQt入门系列教程主要目的是希望通过该系列课程学习,可以使用PyQt5工具快速实现简单的界面开发,包括界面设计.布局管理以及业务逻辑实现(信号与槽).简单说就是可以使用PyQt5工具快速画一个控件摆 ...
- c++ 发布动态.so
原文地址 代码改变世界 Posts - 105, Articles - 0, Comments - 1561 Cnblogs Dashboard Logout Home Contact Gallery ...
- PyQt5开发实践(一、准备篇)
前言 近一年来我开发了不少PyQt小项目,因为之前没用过使用C++语言的Qt,所以可以算是从零基础开始边学边做的,这个过程中再一次体会到国内技术社区的匮乏-- 国内关于PyQt的资料说少不少,说多也不 ...
- 安装PyQt5之后mayavi和VTK不能使用
mayavi在显示数据的过程中需要调用PyQt4的GUI方法产生应用框架.但是新发布的PyQt5和PyQt4在很多方面都是不兼容的,这也就导致了用mayavi编写的程序运行失败.在实践之后,我的解决方 ...
- QT学习之windows下安装配置PyQt5
windows下安装配置PyQt5 目录 为什么要学习QT 命令行安装PyQt5以及PyQt5-tools 配置QtDesigner.PyUIC及PyRcc 为什么要学习QT python下与界面开发 ...
- PyQt5系列教程(二)利用QtDesigner设计UI界面
软硬件环境 OS X EI Capitan Python 3.5.1 PyQt 5.5.1 PyCharm 5.0.1 前言 在PyQt5系列教程的第一篇http://blog.csdn.net/dj ...
- linux下Python2.7编译安装PyQt5
---作者吴疆,未经允许,严禁转载,违权必究--- ---欢迎指正,需要源码和文件可站内私信联系--- -----------点击此处链接至博客园原文----------- 功能说明:在ubuntu系 ...
- [ PyQt入门教程 ] PyQt5信号与槽
信号和槽是PyQt编程对象之间进行通信的机制.每个继承自QWideget的控件都支持信号与槽机制.信号发射时(发送请求),连接的槽函数就会自动执行(针对请求进行处理).本文主要讲述信号和槽最基本.最经 ...
随机推荐
- X-UA-Compatible失效问题
有时候发现页面中写了<meta http-equiv="X-UA-Compatible" content="IE=8" />,但是文档模式依旧没改变 ...
- sed笔记
sed是stream editor缩写,表示流编辑器,它是一款文本处理工具,可以配合正则表达式进行文本替换. 1.使用正则表达式匹配并进行文本中的字符串替换 *使用-i选项可以直接将替换结果应用到源文 ...
- 《UML大战需求分析》阅读笔记5
流程分析利器三,顺序图. 顺序图描述的是一件事发生的顺序,按照时间的发展,事情的走向,其中分为角色,消息等,每个角色下面都有一条生命线,从上到下,从左到右,依次进行事件,没有事情的时候用虚线表示,而有 ...
- 等比例压缩图片到指定的KB大小
基本原理: 取原来的图片,长宽乘以比例,重新生成一张图片,获取这张图片的大小,如果还是超过预期大小,继续在此基础上乘以压缩比例,生成图片,直到达到预期 /** * @获取远程图片的体积大小 单位byt ...
- doxygen的使用(一)配置并生成文档
原创文章,欢迎阅读,禁止转载. doxygen是个好用的文档生成工具,他的强大功能有很多介绍,我就不说了.自带的chm帮助手册很全面,包括功能.注释规范.怎么配置.工具用法等.doxygen的用法共3 ...
- 使用html2canvas实现网页截图并嵌入到PDF
以前我们只能通过截图工具进行截取图像.这使得在业务生产中,变得越来越不方便.目前的浏览器功能越来越强大,H5也逐渐普及,浏览器也可以实现截图了.这里来聊下之前在工作中用到的html2canvas.这里 ...
- 总有一项适合你:联想 Miix2 8寸版触摸屏失灵的各项解决方案
今天试着自己拆开后盖重新拆了一下排线,果然这个方法才是王道.在搜索攻略的时候看到了下面的帖子,觉得总结的不错,特此转载过来: 白色石头 2015-05-22 10:07● 使用评测 总有一 ...
- 轻松创建R语言函数包
讲真,用R这么几年,始终未尝试过写自己的包,看来这就是我与真正程序员的差距了——编程习惯等于没有. 昨天一个偶然的机会想开始写自己的工具包,发现了前期教程的有一些过时.于是,写一个**windows* ...
- Android中 int 和 String 互相转换的多种方法
1 如何将字串 String 转换成整数 int? A. 有两个方法: 1). int i = Integer.parseInt([String]); 或 i = Integer.parseInt([ ...
- UE4动作流程总结
右键新窗口打开看大图
| |