<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>PythonQt on</title><link>https://lmingjian.github.io/docs/pythonqt/</link><description>Recent content in PythonQt on</description><generator>Hugo</generator><language>no</language><lastBuildDate>Thu, 25 Dec 2025 13:47:41 +0800</lastBuildDate><atom:link href="https://lmingjian.github.io/docs/pythonqt/index.xml" rel="self" type="application/rss+xml"/><item><title>Qt 如何进行多线程编程</title><link>https://lmingjian.github.io/docs/pythonqt/qt-%E5%A6%82%E4%BD%95%E8%BF%9B%E8%A1%8C%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%BC%96%E7%A8%8B/</link><pubDate>Thu, 25 Dec 2025 13:47:41 +0800</pubDate><guid>https://lmingjian.github.io/docs/pythonqt/qt-%E5%A6%82%E4%BD%95%E8%BF%9B%E8%A1%8C%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%BC%96%E7%A8%8B/</guid><description>需求 # 在 Qt 编程时，主窗口所在的主线程运行着用户设计的所有界面。当用户在主窗口点击某个按钮，希望执行某些耗时操作，如网络请求，文件读取，数据搜索时，如果是单一线程运行，则主窗口的整个界面会被卡住（因为线程正在运行其他耗时操作，导致无法更新界面），此时对用户的观感造成极大的影响。此时，使用多线程并发的运行程序就显得极为必要了。
在 Qt 中，多线程可以通过使用 QThread 和 QThreadPool 来实现，这两个组件分别适应少量多线程与大量多线程的使用环境。
QThread # QThread 是 Qt 框架中的线程管理类，用于创建和控制单个子线程，每次调用一个 QThread 类，都代表启动了一个子线程。
QThread 类有两种使用方法，分别是重写 run() 方法和使用 moveToThread() 将工作对象移到子线程，这两种方法的区别在于：
run() 方法需要继承 QThread 并重写 run()，子线程在重写的 run() 方法执行完成后就会销毁，不允许线程的复用。 moveToThread() 方法不需要继承 QThread，也不用重写 run()，它将工作对象移动到子线程单独运行，通过信号机制，可以多次，重复的调用工作对象中的方法，子线程不会在某一个方法执行完成后销毁，允许线程的复用。 正因 moveToThread() 方法的支持复用，因此在实际使用时，一般推荐使用 moveToThread() 完成多线程的使用。
在使用 moveToThread() 实现方式时，工作对象可以按以下结构进行设计：
# 构建工作线程，没什么特殊要求，都建议继承 QObject class Worker(QObject): # 定义工作线程的完成信号 finished1 = Signal() # 如果工作线程需要返回数据，则标注数据类型 finished2 = Signal(int) finished3 = Signal(str, int) @Slot() # 指示这个函数是槽函数（信号的执行函数）（显示指定槽函数能让系统自动的为其进行性能优化） def do_work1(self): pass # 耗时操作 self.</description></item><item><title>Qt 如何解决 Emoji 表情符号编译失败的问题</title><link>https://lmingjian.github.io/docs/pythonqt/qt-%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3-emoji-%E8%A1%A8%E6%83%85%E7%AC%A6%E5%8F%B7%E7%BC%96%E8%AF%91%E5%A4%B1%E8%B4%A5%E7%9A%84%E9%97%AE%E9%A2%98/</link><pubDate>Wed, 24 Dec 2025 10:38:14 +0800</pubDate><guid>https://lmingjian.github.io/docs/pythonqt/qt-%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3-emoji-%E8%A1%A8%E6%83%85%E7%AC%A6%E5%8F%B7%E7%BC%96%E8%AF%91%E5%A4%B1%E8%B4%A5%E7%9A%84%E9%97%AE%E9%A2%98/</guid><description>问题 # 在 Windows 系统上使用 Python 编写 Qt 程序时，一般的步骤都是先通过 QtDesigner 设计好界面，然后再通过 pyside6-uic.exe 或者 QtDesigner 自带的 View Python Code 工具，将 QtDesigner 生成的 .ui 文件转换为 .py 文件。
在这个转换过程中，对于一般的文字或符号，都不会出现异常。但是，如果 UI 界面中存在类似下面的这些 Emoji 表情，那么转换后的 .py 文件在使用会出现编码错误的异常。
Emoji 表情是一种文本类型的特殊符号，它可以和文字一样直接使用，原产于日本，是在无线通信中使用的视觉情感符号。在 Windows 系统中，通过按下快捷键 Win+. 可以快速的调起 Emoji 工具界面，输入所需的 Emoji 表情。或者，通过访问 Emojiall 这个 Emoji 表情网站，复制表情符号然后使用。
在 Windows 系统上，如果使用工具将带有 Emoji 表情的 UI 文件转换为代码，这个代码在调用运行时，会出现如下的报错：
UnicodeEncodeError: 'utf-8' codec can't encode characters in position 0-5: surrogates not allowed
问题分析 # 正如报错提示所言 'utf-8' codec can't encode characters，无法使用 UTF-8 对代码进行解码。这里我们应该想到，应该是 Emoji 表情编码的问题（正常没带 Emoji 表情时候，代码是正常运行的）。因此，我们可以去检查生成代码中的对应编码是否正常。</description></item><item><title>Qt 如何实现子控件的自适应左上角按行排列</title><link>https://lmingjian.github.io/docs/pythonqt/qt-%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E5%AD%90%E6%8E%A7%E4%BB%B6%E7%9A%84%E8%87%AA%E9%80%82%E5%BA%94%E5%B7%A6%E4%B8%8A%E8%A7%92%E6%8C%89%E8%A1%8C%E6%8E%92%E5%88%97/</link><pubDate>Tue, 23 Dec 2025 09:35:48 +0800</pubDate><guid>https://lmingjian.github.io/docs/pythonqt/qt-%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E5%AD%90%E6%8E%A7%E4%BB%B6%E7%9A%84%E8%87%AA%E9%80%82%E5%BA%94%E5%B7%A6%E4%B8%8A%E8%A7%92%E6%8C%89%E8%A1%8C%E6%8E%92%E5%88%97/</guid><description>需求 # 在 Qt 编程时，有一个长方形 Widget，现在计划在这个 Widget 中添加不同尺寸的子 Widget，这些子 Widget 高度固定，宽度随机。
在添加子 Widget 时，要求子 Widget 从父控件的左上角开始排列，从左到右，从上到下。同时，可以根据子 Widget 的宽度，自动统计每一行的子 Widget 的数量，保证每一行所展示的子 Widget 都不会因为过长而溢出画面。
最终结果如下图所示：
界面实现 # 创建父控件
创建一个主窗口应用，在主窗口应用中添加父控件。
为了在子控件向下溢出时可以滚动查看，因此父控件需要使用 QScrollArea，在 QtDesigner 中，选择下图所示的组件加入：
加入后，将主窗口布局设置为水平布局，将 QScrollArea 的布局设置为栅栏（网格）布局。
在 QtDesigner 中，布局的设置可以通过右键对象来实现。
需要注意，在 QtDesigner 中，QScrollArea 在没有子组件的时候无法设置布局，因此可以先加入一个按钮，然后再设置布局，最后删除这个按钮，恢复原状。
最终，父控件与主窗口的结构关系如下图所示。
创建子控件
创建一个 QFrame 组件，子控件将在这里设置。
子控件要求进行信息展示，因此直接添加一个 QLabel 控件即可，布局推荐使用水平。
同时，子控件要求高度固定，宽度随机，因此还需要限定控件的最大最小尺寸。在这里，我们可以直接限定 QFrame 这个父组件的最大最小。
注意，这里只需要限定高度。
特别的，为了美观，可以为子控件设置 QCSS。
QLabel { background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #ffffff, stop: 1 #f0f9ff); border: 1px solid #000000; } QLabel:hover { background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #f8f9fa, stop: 1 #e6f7ff); border: 2px solid #000000; } 逻辑实现 # 在上面的父控件 QScrollArea 中，我们使用了栅栏布局，我们以一个 Button 充当子控件，先看看栅栏布局的效果满不满足我们的需求。</description></item><item><title>PyQt5 Widgets：QTextEdit</title><link>https://lmingjian.github.io/docs/pythonqt/pyqt5-widgetsqtextedit/</link><pubDate>Wed, 25 Dec 2024 16:07:22 +0800</pubDate><guid>https://lmingjian.github.io/docs/pythonqt/pyqt5-widgetsqtextedit/</guid><description>概述 # QTextEdit 是 Qt 提供的文本组件，与 QLineEdit 不同的是，QTextEdit 支持多行文字，以及 HTML 的输入。
支持的方法 # setPlaceholderText() #| 设置占位文本 placeholderText() #| 获取占位文本 setPlainText(str) #| 设置普通文本 insertPlainText(str) #| 插入普通文本 toPlainText() #| -&amp;gt; str 返回普通文本 setHtml(str) #| 设置Html文本 insertHtml(str) #| 插入Html文本 toHtml() #| -&amp;gt; str 返回Html 文本 setText(str) #| 设置文本（自动识别） append(str) #| 追加文本 clear() #| 清空文本 setFontPointSize(float) #| 设置字体大小 setFontFamily(str) #| 设置字体</description></item><item><title>PyQt5 Widgets：QProgressDialog</title><link>https://lmingjian.github.io/docs/pythonqt/pyqt5-widgetsqprogressdialog/</link><pubDate>Wed, 25 Dec 2024 16:07:17 +0800</pubDate><guid>https://lmingjian.github.io/docs/pythonqt/pyqt5-widgetsqprogressdialog/</guid><description>概述 # QProgressDialog 是 Qt 提供的进度条组件。
进度条使用 steps 的概念。在指定最小和最大可能的 step 值后，它将显示已经完成的 step 的百分比。
百分比是通过将进度(value() - minimum()) / (maximum() - minimum())来计算。用户可以使用 setMinimum() 和 setMaximum() 指定最小和最大 steps，默认值是 0 和 99。
需要注意的是，如果最小值和最大值都设置为 0，那么栏会显示一个繁忙的指示符，而不是步骤的百分比。
支持的方法 # setMinimum() # 设置操作中的 steps 数量 setMaximum() # 设置操作中的 steps 数量 setValue() # 任意选择步数 setAutoReset() # 自动重置 setAutoClose() # 自动关闭 setRange(0,num) # 设置最小和最大值 wasCanceled() # 是否按下取消按钮 示例 # def showDialog(self): num = int(self.edit.text()) progress = QProgressDialog(self) progress.setWindowTitle(&amp;quot;请稍等&amp;quot;) progress.setLabelText(&amp;quot;正在操作...&amp;quot;) progress.setCancelButtonText(&amp;quot;取消&amp;quot;) progress.</description></item><item><title>PyQt5 Widgets：QMessageBox</title><link>https://lmingjian.github.io/docs/pythonqt/pyqt5-widgetsqmessagebox/</link><pubDate>Wed, 25 Dec 2024 16:07:11 +0800</pubDate><guid>https://lmingjian.github.io/docs/pythonqt/pyqt5-widgetsqmessagebox/</guid><description>概述 # QMessageBox 是 Qt 提供的一个消息提示框，程序可以通过该组件完成消息提示。
# 弹出消息对话框 reply = information(QWdiget parent,title,text,buttons,defaultButton) reply = QMessageBox.information(self, '标题','消息对话框正文',QMessageBox.Yes | QMessageBox.No,QMessageBox.Yes) reply1 = QMessageBox.question(self, &amp;quot;标题&amp;quot;, &amp;quot;提问框消息正文&amp;quot;, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) reply2 = QMessageBox.warning(self, &amp;quot;标题&amp;quot;, &amp;quot;警告框消息正文&amp;quot;, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) reply3 = QMessageBox.critical(self, &amp;quot;标题&amp;quot;, &amp;quot;严重错误对话框消息正文&amp;quot;, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) reply4 = QMessageBox.about(self, &amp;quot;标题&amp;quot;, &amp;quot;关于对话框消息正文&amp;quot;) reply.exec_() # 参数 parent: 指定的父窗口控件 title: 对话框标题 text: 对话框文本 buttons: 标准按钮, 默认为ok按钮, 可以有多个, 用 | 进行分隔 defaultButton: 关闭对话框默认返回的按钮 # 方法 setTitle() # 设置标题 setText() # 设置正文消息 setIcon() # 设置弹出对话框的图片 Ex.</description></item><item><title>PyQt5 Widgets：QLineEdit</title><link>https://lmingjian.github.io/docs/pythonqt/pyqt5-widgetsqlineedit/</link><pubDate>Wed, 25 Dec 2024 16:07:05 +0800</pubDate><guid>https://lmingjian.github.io/docs/pythonqt/pyqt5-widgetsqlineedit/</guid><description>概述 # QLineEdit 是 Qt 提供的一个文本组件，用户可以通过该组件输入文本信息。
支持的方法 # setText(str) # 设置普通文本 Text() # 返回普通文本 使用掩码限制输入格式 # ipLineEdit.setInputMask('000.000.000.000;_') macLineEdit.setInputMask('HH:HH:HH:HH:HH:HH;_') dateLineEdit.setInputMask('0000-00-00') licenseLineEdit.setInputMask('&amp;gt;AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;#') Ex.支持的掩码类型 # # 掩码类型 A ASCII字母字符是必须输入的(A-Z、a-z) a ASCII字母字符是允许输入的,但不是必需的(A-Z、a-z) N ASCII字母字符是必须输入的(A-Z、a-z、0-9) n ASII字母字符是允许输入的,但不是必需的(A-Z、a-z、0-9) X 任何字符都是必须输入的 x 任何字符都是允许输入的,但不是必需的 9 ASCII数字字符是必须输入的(0-9) 0 ASCII数字字符是允许输入的,但不是必需的(0-9) D ASCII数字字符是必须输入的(1-9) d ASCII数字字符是允许输入的,但不是必需的(1-9) # ASCI数字字符或加减符号是允许输入的,但不是必需的 H 十六进制格式字符是必须输入的(A-F、a-f、0-9) h 十六进制格式字符是允许输入的,但不是必需的(A-F、a-f、0-9) B 二进制格式字符是必须输入的(0,1) b 二进制格式字符是允许输入的,但不是必需的(0,1) &amp;gt; 所有的字母字符都大写 &amp;lt; 所有的字母字符都小写 ! 关闭大小写转换 \ 使用&amp;quot;\&amp;quot;转义上面列出的字符</description></item><item><title>PyQt5 Widgets：QInputDialog</title><link>https://lmingjian.github.io/docs/pythonqt/pyqt5-widgetsqinputdialog/</link><pubDate>Wed, 25 Dec 2024 16:06:59 +0800</pubDate><guid>https://lmingjian.github.io/docs/pythonqt/pyqt5-widgetsqinputdialog/</guid><description>概述 # QInputDialog 继承自 QDialog 提供了一种简单的对话框来获得用户的单个输入信息。
常用以下方法获取对话框的信息。
字符串型：QInputDialog.getText() int 类型数据：QInputDialog.getInt() double 类型数据：QInputDialog.getDouble() 下拉列表框的条目：QInputDialog.getItem() def getInteger(self): i, okPressed = QInputDialog.getInt(self, &amp;quot;Get integer&amp;quot;,&amp;quot;Percentage:&amp;quot;, 28, 0, 100, 1) if okPressed: print(i) def getDouble(self): d, okPressed = QInputDialog.getDouble(self, &amp;quot;Get double&amp;quot;,&amp;quot;Value:&amp;quot;, 10.50, 0, 100, 10) if okPressed: print( d) def getChoice(self): items = (&amp;quot;Red&amp;quot;,&amp;quot;Blue&amp;quot;,&amp;quot;Green&amp;quot;) item, okPressed = QInputDialog.getItem(self, &amp;quot;Get item&amp;quot;,&amp;quot;Color:&amp;quot;, items, 0, False) if ok and item: print(item) def getText(self): text, okPressed = QInputDialog.getText(self, &amp;quot;Get text&amp;quot;,&amp;quot;Your name:&amp;quot;, QLineEdit.</description></item><item><title>PyQt5 Widgets：QFileDialog</title><link>https://lmingjian.github.io/docs/pythonqt/pyqt5-widgetsqfiledialog/</link><pubDate>Wed, 25 Dec 2024 16:06:54 +0800</pubDate><guid>https://lmingjian.github.io/docs/pythonqt/pyqt5-widgetsqfiledialog/</guid><description>概述 # QFileDialog 是 Qt 的一个文件管理器组件，通过该组件，用户可用打开文件或目录。
调用文件对话框获取文件信息 # QFileDialog.getExistingDirectory() # 返回选中的文件夹路径 QFileDialog.getOpenFileName() # 返回选中的文件路径 QFileDialog.getOpenFileNames() # 返回选中的多个文件路径 QFileDialog.getSaveFileName() # 存储文件 返回选中的文件夹路径 # QFileDialog.getExistingDirectory(None, &amp;quot;请选择文件夹路径&amp;quot;, &amp;quot;D:\\Qt_ui&amp;quot;) QFileDialog.getExistingDirectory(self, &amp;quot;请选择文件夹路径&amp;quot;, &amp;quot;D:\\Qt_ui&amp;quot;) # 第一个参数,有self的话用self,没有的话用None # 第二个参数,设置窗口名 # 第三个参数,设置默认打开路径 获取单个文件的路径 # QFileDialog.getOpenFileName(myWin, directory='.', filter='Excel files(*.xlsx ; *.xls)') # 第一个参数: parent 用于指定父组件,PS: 很多Qt组件的构造函数都会有这么一个parent参数,并提供一个默认值0 # 第二个参数: caption 是对话框的标题 # 第三个参数: dir 是对话框显示时默认打开的目录,&amp;quot;.&amp;quot; 代表程序运行目录,&amp;quot;/&amp;quot; 代表当前盘符的根目录 # 第四个参数: filter 是对话框的后缀名过滤器,支持正则 # 第六个参数: options,是对话框的一些参数设定,比如只显示文件夹等 获取多个文件的路径 # QFileDialog.getOpenFileNames(None, &amp;quot;请选择要添加的文件&amp;quot;, path, &amp;quot;Text Files (*.</description></item><item><title>PyQt5 Widgets：QDialog</title><link>https://lmingjian.github.io/docs/pythonqt/pyqt5-widgetsqdialog/</link><pubDate>Wed, 25 Dec 2024 16:06:48 +0800</pubDate><guid>https://lmingjian.github.io/docs/pythonqt/pyqt5-widgetsqdialog/</guid><description>概述 # QDialog 是 Qt 中所有消息窗口的父类，其中包括多种窗口子类，如 QMessageBox，QFileDialog，QColorDialog，QFontDialog，QInputDialog 等。
PyQt5 中支持的方法 # # 方法 setWindowTitle() # 设置对话框标题 setWindowModality() # 设置窗口模态 # 可用属性 Qt.NonModal: 非模态,可以和程序的其他窗口进行交互 Qt.WindowModal: 窗口模态,程序在未处理玩当前对话框时,将阻止和对话框的父窗口进行交互 Qt.ApplicationModal: 应用程序模态,阻止和任何其他窗口进行交互</description></item></channel></rss>