《快速掌握PyQt5》技巧篇

本文分享了PyQt5的多个实用技巧,包括创建无边框窗口并实现拖拽、动态增删控件、QTableWidget单元格文本居中、线程中获取窗口控件内容、窗口屏幕居中显示及文本浏览框滑动条自动下滑等,帮助开发者提高界面设计效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

技巧篇

在这里笔者会放上各种各样的PyQt5小技巧,方便快速查阅。大家可以直接用Ctrl+F来进行搜索(Mac上为Command+F),看看有没有自己需要的。

《快速掌握PyQt5》专栏已整理成书出版,书名为《PyQt编程快速上手》,详情请见该链接。感谢大家一直以来的支持!祝大家PyQt用得越来越顺!

拖曳无边框窗口

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget


class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.setWindowFlag(Qt.FramelessWindowHint)  # 1
        self.start_x = None
        self.start_y = None

    def mousePressEvent(self, event):               # 2
        if event.button() == Qt.LeftButton:
            self.start_x = event.x()
            self.start_y = event.y()

    def mouseMoveEvent(self, event):                # 3
        if not self.start_x or not self.start_y:
            return

        dis_x = event.x() - self.start_x
        dis_y = event.y() - self.start_y
        self.move(self.x() + dis_x, self.y() + dis_y)

    def mouseReleaseEvent(self, event):
        self.start_x = None
        self.start_y = None


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

1. 调用窗口的setWindowFlag方法并传入Qt.FramelessWindowHint即可取消窗口边框。

2. 获取鼠标按下时的坐标位置(相对于窗口左上角)。

3. 当鼠标处于按下状态并开始移动时,鼠标离窗口左上角的位置会不断更新并保存在event.x()和event.y()中。我们将更新后的x和y值不断减去鼠标按下时的坐标位置,就可以知道鼠标移动的距离。最后再调用move方法将窗口当前坐标加上移动距离即可。

动态增加和删除控件

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QVBoxLayout, QHBoxLayout


class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()

        self.label_list = []                                # 1
        for i in range(5):
            label = QLabel(str(i+1))
            label.setAlignment(Qt.AlignCenter)
            self.label_list.append(label)

        self.add_btn = QPushButton('增加文本')              # 2
        self.minus_btn = QPushButton('删除文本')
        self.add_btn.clicked.connect(self.add_slot)
        self.minus_btn.clicked.connect(self.minus_slot)

        self.v_layout = QVBoxLayout()                      # 3
        h_layout = QHBoxLayout()
        all_v_layout = QVBoxLayout()

        for l in self.label_list:
            self.v_layout.addWidget(l)
        h_layout.addWidget(self.add_btn)
        h_layout.addWidget(self.minus_btn)
        all_v_layout.addLayout(self.v_layout)
        all_v_layout.addLayout(h_layout)
        self.setLayout(all_v_layout)

    def add_slot(self):                                     # 4
        label = QLabel(str(len(self.label_list)+1))
        label.setAlignment(Qt.AlignCenter)
        self.label_list.append(label)
        self.v_layout.addWidget(label)

    def minus_slot(self):                                   # 5
        if len(self.label_list) == 1:
            return

        label = self.label_list.pop()
        label.deleteLater()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

1. 首先实例化五个QLabel控件,并添加到self.label_list列表中,动态增删的关键其实就是这个列表。

2. 实例化两个按钮分别用于增加和删除QLabel控件。

3. self.v_layout垂直布局管理器用于布局各个QLabel控件,h_layout管理器用于摆放两个按钮,而all_v_layout用于总体布局。这里之所以要将v_layout作为成员变量是因为我们在增加QLabel控件时需要使用到。

4. add_slot槽函数用于增加QLabel控件,每实例化一个QLabel,我们就将其添加到self.label_list列表和self.v_layout布局管理器中。

5. minus_slot槽函数用于删除末尾的QLabel控件。如果控件数量只剩一个,那么就不允许删除,否则调用列表的pop()方法获取到最后一个QLabel控件,然后调用deleteLater()方法删除即可。

PS:

在动态增删控件时如果想要自动调整窗口大小,我们可以添加以下代码:

from PyQt5.QtWidgets import QLayout
all_v_layout.setSizeConstraint(QLayout.SetFixedSize)

QTableWidget单元格文本居中

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QTableWidget, QTableWidgetItem, QHeaderView, \
                            QPushButton, QVBoxLayout


class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(500, 300)

        self.table = QTableWidget()                           # 1
        self.set_table_properties()
        self.btn = QPushButton('文本居中')                     # 2
        self.btn.clicked.connect(self.center_slot)

        v_layout = QVBoxLayout()
        v_layout.addWidget(self.table)
        v_layout.addWidget(self.btn)
        self.setLayout(v_layout)

    def set_table_properties(self):
        """设置表格属性"""
        self.table.setColumnCount(3)
        self.table.setRowCount(6)
        self.table.setHorizontalHeaderLabels(['标题1', '标题2', '标题3'])
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.table.verticalHeader().setHidden(True)

        for row in range(self.table.rowCount()):
            for col in range(self.table.columnCount()):
                self.table.setItem(row, col, QTableWidgetItem(f'({row}, {col})'))

    def center_slot(self):
        """文本居中槽函数"""
        for row in range(self.table.rowCount()):
            for col in range(self.table.columnCount()):
                self.table.item(row, col).setTextAlignment(Qt.AlignCenter)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

1. 实例化一个表格控件,然后在set_table_property函数中笔者设置了表格的相关属性:

  • 设置表格列数和行数为3和6
  • 设置表格标题字段名称为'标题1',‘标题2’,‘标题3’
  • 拉伸各列,使表格填充窗口
  •  将表格左边自带的序列号隐藏
  • 设置各个单元格内容

2. 点击按钮后可以让文本居中。在center_slot槽函数中循环各个单元格,然后对每个单元格调用setTextAlignment方法并传入Qt.AlignCenter即可。

在线程中获取窗口控件内容

import sys
from PyQt5.QtCore import QThread
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLineEdit, QLabel, QVBoxLayout, QHBoxLayout


class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.line = QLineEdit()
        self.btn = QPushButton('开始爬取')
        self.btn.clicked.connect(self.start_slot)

        h_layout = QHBoxLayout()
        v_layout = QVBoxLayout()
        h_layout.addWidget(QLabel('网址:'))
        h_layout.addWidget(self.line)
        v_layout.addLayout(h_layout)
        v_layout.addWidget(self.btn)
        self.setLayout(v_layout)

        self.crawl_thread = CrawlThread(self)           # 1

    def start_slot(self):                               # 2
        self.crawl_thread.start()


class CrawlThread(QThread):
    def __init__(self, demo):                            # 3
        super(CrawlThread, self).__init__()
        self.demo = demo

    def run(self):                                       # 4
        url = self.demo.line.text().strip()
        print(f'要爬取的网址为:{url}')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

1. 实例化线程,注意此时我们需要把当前窗口类实例(也就是self)传入。

2. 按钮所连接的槽函数用来启动线程。

3. 给线程的初始化函数添加一个参数,用来获取窗口类实例。

4. 接着我们就可以在run函数中获取窗口上任何一个控件及其内容了。

窗口在屏幕居中显示

import sys
from PyQt5.QtWidgets import QApplication, QWidget


class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(100, 100)
        self.center()

    def center(self):
        # 1
        desktop = QApplication.desktop()
        d_width = desktop.width()
        d_height = desktop.height()

        # 2
        pos_x = d_width/2 - self.frameGeometry().width()/2
        pos_y = d_height/2 - self.frameGeometry().height()/2

        # 3
        self.move(int(pos_x), int(pos_y))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

1. 获取屏幕宽高。

2. 屏幕中心的坐标是(d_width/2, d_height/2),但是我们知道窗口的锚点是在左上角,如果直接将移动到该坐标的话,窗口整体会出现在屏幕的右下方:

所以我们应该要将窗口往左上角移动下,横向移动距离是窗口宽度的一半,纵向移动距离是窗口高度的一半,这样就没问题了:

3. 调用move函数将窗口移动到指定位置,接收的参数为int类型。

有关窗口坐标的更多知识点,请阅读第十六章 窗口坐标

浏览框滑动条自动下滑到底

import sys
from PyQt5.QtGui import QTextCursor
from PyQt5.QtWidgets import QApplication, QWidget, QTextEdit, QTextBrowser, QPushButton, QHBoxLayout, QVBoxLayout


class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        # 1
        self.edit = QTextEdit()
        self.browser = QTextBrowser()
        self.add_btn = QPushButton('添加')

        # 2
        self.add_btn.clicked.connect(self.add_text)

        h_layout = QHBoxLayout()
        v_layout = QVBoxLayout()
        h_layout.addWidget(self.edit)
        h_layout.addWidget(self.browser)
        v_layout.addLayout(h_layout)
        v_layout.addWidget(self.add_btn)
        self.setLayout(v_layout)

    def add_text(self):
        text = self.edit.toPlainText()
        self.browser.append(text)
        self.browser.moveCursor(QTextCursor.End)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

1. 实例化一个QTextEdit文本编辑框控件、一个QTextBrowser文本浏览框控件以及一个按钮。

2. 进行信号和槽连接操作:每次点击按钮后,编辑框的文本就会被添加到浏览框中。在槽函数中的moveCursor(QTextCursor.End)方法是重点,每当浏览框中新增信息后,该方法都会将滑动条滑到最底部。

待更新

如果大家有想要了解的小技巧,可以在评论区留言。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

la_vie_est_belle

谢谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值