logo资料库

Pyside开发笔记.docx

第1页 / 共11页
第2页 / 共11页
第3页 / 共11页
第4页 / 共11页
第5页 / 共11页
第6页 / 共11页
第7页 / 共11页
第8页 / 共11页
资料共11页,剩余部分请下载后查看
1 简单Pyside开发例子
1.1 QtDesigner 设计UI
1.2 转换UI文件未py文件
1.3 界面的py文件导入使用
2 Qt Designer的UI设计
2.1 Toolbar的实现
2.1.1 UI绘制
2.1.2 事件实现
2.2 滚动区域
2.2.1 UI绘制
2.2.2 事件实现
2.3 文件浏览
2.4 文本显示
2.4.1 读取文本内容
2.4.2 文本显示
2.5 UI刷新
2.5.1 信号
2.6 分类浏览和勾选
2.6.1 左边选择
2.6.2 右边展示逻辑
2.6.3 显示Model
1 简单 Pyside 开发例子 1.1 QtDesigner 设计 UI 设置窗口类名称:
1.2 转换 UI 文件未 py 文件 pyside-uic smoking_case_browser.ui -o smoking_case_browser.py 1.3 界面的 py 文件导入使用 建立 smoking_case_browser_win.py 文件。 实现窗口如下: import sys import os from PySide.QtGui import * from PySide.QtCore import * from smoking_case_browser import * class SmokingCaseBrowserWindow(QMainWindow, Ui_SmokingCaseBrowser): currentPath = "../../" def __init__(self, parent = None): super(SmokingCaseBrowserWindow, self).__init__(parent) self.setupUi(self) if __name__ == '__main__': program = QApplication(sys.argv) window = SmokingCaseBrowserWindow() window.show() program.exec_() program.exit(0) 2 Qt Designer 的 UI 设计 2.1 Toolbar 的实现 2.1.1 UI 绘制 先添加 toobar 区域
添加 Toolbar Action 拖动 Action 按钮到 Toolbar 区域 2.1.2 事件实现 注册 toolbar 中的激活事件:
self.openTask.triggered.connect(self.openTaskList) openTaskList 是一个函数: def openTaskList(self): self.fileDialog = QFileDialog(self, "Browser", "Open") self.fileDialog.setFileMode(QFileDialog.AnyFile) self.fileDialog.show() 2.2 滚动区域 2.2.1 UI 绘制 scrollArea 下的上下滚动实现,必须最小高度要大于绘制的区域高度。 水平滑动实现方式一样。 2.2.2 事件实现 滚动区域下面挂载新组件: def showTaskListView(self, taskDic): for taskkey in taskDic.keys(): pb_Task = QPushButton() print taskkey.encode("utf-8", "Error") pb_Task.setText(QtGui.QApplication.translate("Error", taskkey.encode("utf-8", "Error"), None, QtGui.QApplication.UnicodeUTF8))
self.TaskListLayout.addWidget(pb_Task) pb_Task.clicked.connect(self.showTaskDetail) 2.3 文件浏览 利用原生的 QFileDialog 浏览文件,并选择一个文件。 def openTaskList(self): self.fileDialog = QFileDialog(self, "Browser", "Open") self.fileDialog.setFileMode(QFileDialog.AnyFile) self.fileDialog.show() self.fileDialog.setDirectory(self.currentPath) self.fileDialog.setViewMode(QFileDialog.Detail) if self.fileDialog.exec_(): self.rootDirs = self.fileDialog.selectedFiles() self.taskNoteFile = self.rootDirs[0] print "选中的文件:",self.taskNoteFile self.loadTaskDic(self.taskNoteFile) self.showTaskListView(self.taskDic) 这里虽然返回选择值是 File 列表,但是操作界面只能选择一个文件。 2.4 文本显示 一定要注意 Python 的字符串和 PyQt 的字符串不一样,需要转换。
已全部为 utf-8 编码为例: 2.4.1 读取文本内容 def getScriptsConfig(config): conDic = {} cfgFile = open(config, "r", -1) strline = "init" while (strline <> None and strline <> ""): strline = cfgFile.readline().strip("\n") info = strline.decode("utf-8", "error") # 防止文本读取结束时,“#”判断出错 if (info.__len__() > 1 and info[0] <> "#"): print "position=", cfgFile.tell(), ";line:", info.encode("utf-8") strarr = info.split("=") print "getConfig,", strarr if (strarr.__len__() > 1): conDic[strarr[0]] = strarr[1] cfgFile.close() return conDic 代码说明: info = strline.decode("utf-8", "error") 上述一行代码,必须要,否则默认用 anscii 来读取文本内容。 2.4.2 文本显示 def showTaskListView(self, taskDic): for taskkey in taskDic.keys(): pb_Task = QPushButton() pb_Task.setText(QtGui.QApplication.translate("Error", taskkey.encode("utf-8", "Error"), None, QtGui.QApplication.UnicodeUTF8)) self.TaskListLayout.addWidget(pb_Task) pb_Task.clicked.connect(lambda :self.showTaskDetail(taskkey)) 代码说明: QtGui.QApplication.translate("Error", QtGui.QApplication.UnicodeUTF8) taskkey.encode("utf-8", "Error"), None, 就是把 Python 的字符串,转换成 PyQt 的字符串。此处转换的是 utf-8 编码字符串,中文显 示正常。
这里的 taskDic 就是 2.4.1 代码中的 conDic。 问题 1:在代码里直接输入中文字符,用于显示在 UI 上时,需指定采用 utf-8 编码,否则默 认采用 ascii 编码,在 UI 显示永远是乱码。这里也可以直接转换成 QT.QApplication.UnicodeUTF8 编码。 专码方式如下: def toQtUTF8String(src, coding): if (coding == "utf-8"): return QtGui.QApplication.translate("Error", src.encode("utf-8"), None, QtGui.QApplication.UnicodeUTF8) else: return QtGui.QApplication.translate("Error", src, None, QtGui.QApplication.UnicodeUTF8) 当在代码中组合字符串,字符串含有中文时,经常出现编码错误问题。为避免这个问题, 统一所有编码为 utf-8. 方式如下红色字体部分: import sys reload(sys) sys.setdefaultencoding("utf8") from test_thread import * from request import * 代码位置:在代码文件前面导入库文件位置。 2.5 UI 刷新 先看下面的错误: QObject: Cannot create children for a parent that is in a different thread. (Parent is QTextDocument(0x7716e80), parent's thread is QThread(0x3932c10), current thread is QThread(0x77181c0) 原因,我在界面启动了一个线程,然后把该界面对象给到子线程,然后直接到子线用 UI 对象来获取组件刷新界面,然后出现上述错误提示。 注意:这里不能说明线程 1 不能直接改变线程 2 里的变量值。关于 UI 对象值为什么不 能直接改变,和 Android UI 设计一样,具体原因需要单独探讨. 初级解释:Qt 只允许主线程使用界面类,因为界面类不是线程安全的,不可重入,在 多个线程中使用可能会出现问题,因此 Qt 不建议主界面线程外的线程使用图形类和调用图 形类接口。 本章将讨论如何在其他线程刷新 UI。
2.5.1 信号 信号和槽是 Pyside 重要线程通信机制。 情况 1:都在 UI 线程,通过 UI 操作事件信号刷新 UI 界面 这种情况,例子如 2.1 Toolbar 和 2.4.2 中文本显示中的按钮点击。 self.openTask.triggered.connect(self.openTaskList) pb_Task.clicked.connect(lambda :self.showTaskDetail(taskkey)) Pyside 标准库中,Toolbar 的 Action 和 PushButton,有信号 triggered 和 clicked。利用这 套已有信号机制,同时都在 UI 线程中,所以可以直接调用 UI 中组件对象函数刷新,例如 setText。 情况 2:在非 UI 线程,通过自建信号刷新 UI 界面。 在非 UI 线程,需要跨越线程刷新 UI 界面,如同模拟情况 1 的机制。 步骤 1:在非 UI 线程中有对象持有信号对象。 实现: class UiHandler(QtCore.QObject): noteSign = QtCore.Signal(str) def __init__(self, uiWindow, parent = None): super(UiHandler, self).__init__(parent) self.window=uiWindow def appendNote(self, info): print "appendNote noteSign.emit, info=", info self.noteSign.emit(info) 在这里,非 UI 线程需要持有 UiHandler 类对象。 UiHandler 对象持有 noteSign 对象,类型是 Signal。 函数:appendNote 中 noteSign.emit 就是用来发送信号,也可以理解为事件激活。那这 里就存在一个接受处理方。 接受处理方:可以是函数,也可以是槽。这里仅说函数。 步骤 2:在 UI 线程实现信号处理函数 def appendNote(self, info): self.textB_Cmd.append(info) 目前看起来,两个信号发送方和信号处理函数没有任何关联,所以需要建立连接。 步骤 3:进行信号处理连接 self.uiHandler = UiHandler(self) self.uiHandler.noteSign.connect(self.appendNote) 目前看,已经连接好信号发送方和处理方,剩下的就是使用。使用方式,将 uiHandler
分享到:
收藏