# QT 界面

  • PyQt 是 GPLv3 协议,大意是你的程序中用了它,你的程序就要开源,如果闭源商用就会违反协议(后果自负,脸皮够厚无所谓)。除非你搞封装动态加载那一套来强行规避。
  • PySide 是 LGPL 协议,如果你只是作为库用用它,你的程序还是可以闭源商用。

# 安装 PySide2

pip install pyside2

# 界面设计师 Qt Designer

路径:\Pyhton\Lib\site-packages\PySide2\designer.exe

# 动态加载 UI 文件

有了界面定义文件,我们的 Python 程序就可以从文件中加载 UI 定义,并且动态 创建一个相应的窗口对象。

from PySide2.QtWidgets import QApplication, QMessageBox
from PySide2.QtUiTools import QUiLoader

class Stats:
    def __init__(self):
        # 从文件中加载UI定义

        # 从 UI 定义中动态 创建一个相应的窗口对象
        # 注意:里面的控件对象也成为窗口对象的属性了
        # 比如 self.ui.button , self.ui.textEdit
        self.ui = QUiLoader().load('main.ui')
        self.ui.pushButton.clicked.connect(self.事件方法)

    def 事件方法(self):
        #事件方法
app = QApplication([])
stats = Stats()
stats.ui.show()
app.exec_()

# 转化 UI 文件为 Python 代码

pyside2-uic main.ui > ui_main.py
点击查看代码
from PySide2.QtWidgets import QApplication,QMainWindow
from ui_main import Ui_MainWindow

class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        # 使用ui文件导入定义界面类
        self.ui = Ui_MainWindow()
        # 初始化界面
        self.ui.setupUi(self)

        # 使用界面定义的控件,也是从ui里面访问
        self.ui.webview.load('http://www.baidu.com')

app = QApplication([])
mainw = MainWindow()
mainw.show()
app.exec_()

# 按钮 QPushButton

信号:被点击

button.clicked.connect(事件函数名)

方法:改变文本

button.setText(文本内容)

# 标签 QLabel

方法:改变文本
代码中可以使用 setText 方法来改变标签文本内容

button.setText(text)

# 单行文本框 QLineEdit

信号:文本被修改
当文本框中的内容被键盘编辑,被点击就会发出 textChanged 信号,可以这样指定处理该信号的函数

edit.textChanged.connect(事件方法)

方法:获取文本
通过 text 方法获取编辑框内的文本内容

text = edit.text()

方法:设置提示
通过 setPlaceholderText 方法可以设置提示文本内容

edit.setPlaceholderText('提示内容')

方法:设置文本
通过 setText 方法设置编辑框内的文本内容为参数里面的文本字符串

edit.setText("文本")

原来的所有内容会被清除

方法:清除所有文本
clear 方法可以清除编辑框内所有的文本内容

edit.clear()

方法:拷贝文本到剪贴板
copy 方法可以清除编辑框内所有的文本内容

edit.copy()

方法:粘贴剪贴板文本
paste 方法可以把剪贴板内容,拷贝到编辑框当前光标所在处

edit.paste()

# 多行纯文本框 QPlainTextEdit

信号:文本被修改
当文本框中的内容被键盘编辑,被点击就会发出 textChanged 信号,可以这样指定处理该信号的函数

edit.textChanged.connect(handleTextChange)

信号:光标位置改变
当文本框中的光标位置变动,就会发出 cursorPositionChanged 信号,可以这样指定处理该信号的函数

edit.cursorPositionChanged.connect(handleChanged)

方法:获取文本
通过 toPlainText 方法获取编辑框内的文本内容

text = edit.toPlainText()

方法:设置提示
通过 setPlaceholderText 方法可以设置提示文本内容

edit.setPlaceholderText('请在这里输入薪资表')

方法:设置文本
通过 setPlainText 方法设置编辑框内的文本内容为参数里面的文本字符串

edit.setPlainText('''文本内容''')

原来的所有内容会被清除

方法:在末尾添加文本
通过 appendPlainText 方法在编辑框末尾添加文本内容

edit.appendPlainText('文本内容')

方法:清除所有文本
clear 方法可以清除编辑框内所有的文本内容

edit.clear()

方法:拷贝文本到剪贴板
copy 方法可以清除编辑框内所有的文本内容

edit.copy() 方法:粘贴剪贴板文本
paste 方法可以把剪贴板内容,拷贝到编辑框当前光标所在处

edit.paste()

# 组合选择框

信号:选项改变
如果用户操作修改了 QComboBox 中的选项就会发出 currentIndexChanged 信号,可以这样指定处理该信号的函数

cbox.currentIndexChanged.connect(handleSelectionChange)

方法:添加一个选项
代码中可以使用 addItem 方法来添加一个选项到 末尾 ,参数就是选项文本

cbox.addItem('选项文本')

方法:添加多个选项
代码中可以使用 addItems 方法来添加多个选项到 末尾,参数是包含了多个选项文本的列表

cbox.addItems(['数据1','数据2','数据3'])

方法:清空选项
代码中可以使用 clear 方法来清空选项,也就是删除选择框内所有的选项

cbox.clear()

方法:获取当前选项文本
代码中可以使用 currentText 方法来获取当前 选中的选项 的文本

method = cbox.currentText()

# 列表 QListWidget

方法:添加一个选项
代码中可以使用 addItem 方法来添加一个选项到 末尾 ,参数就是选项文本

listWidget.addItem('byhy')

方法:添加多个选项
代码中可以使用 addItems 方法来添加多个选项到 末尾,参数是包含了多个选项文本的列表

listWidget.addItems(['数据1','数据2','数据3'])

方法:删除一个选项
代码中可以使用 takeItem 方法来删除 1 个选项,参数是该选项所在行

listWidget.takeItem(1)

就会删除第二行选项

方法:清空选项 代码中可以使用 clear 方法来清空选项,也就是删除选择框内所有的选项

listWidget.clear()

方法:获取当前选项文本
currentItem 方法可以得到列表当前选中项对象(QListWidgetItem) ,再调用这个对象的 text 方法,就可以获取文本内容

listWidget.currentItem().text()
就获取了 第1行,第1列 的单元格里面的文本。
listWidget.currentItem().text()

# 表格 QTableWidget

方法:获取所有行数
代码中可以使用 rowCount 方法来获取表格所有的函数

method = table.rowCount()

方法:获取当前选中是第几行
代码中可以使用 currentRow 方法来获取当前选中是第几行

method = table.currentRow()

提示

行数是从 0 开始的, 第一行的行数是 0

方法:插入一行
insertRow 方法可以在指定位置插入一行

table.insertRow(0)

就插入一行到第 1 行这个位置, 表格原来第 1 行(包括原来的第 1 行)以后的内容,全部往下移动一行。

table.insertRow(2)

就插入一行到第 3 行这个位置, 表格原来第 3 行(包括原来的第 3 行)以后的内容,全部往下移动一行。

方法:删除一行
removeRow 方法可以删除指定位置的一行

table.removeRow(0)

就删除第 1 行, 表格原来第 1 行以后的内容,全部往上移动一行。

table.removeRow(2)

就删除第 3 行, 表格原来第 3 行以后的内容,全部往上移动一行。

方法:获取某个单元格文本的内容
item 方法可以指定位置的单元格对象(QTableWidgetItem) ,再调用这个对象的 text 方法,就可以获取文本内容

table.item(0,0).text()

就获取了 第 1 行,第 1 列 的单元格里面的文本。

table.item(2,4).text()

就获取了 第 3 行,第 5 列 的单元格里面的文本。

# 单选按钮 和 按钮组 QRadioButton

说明
同一个父窗口 里面的多个单选按钮,只能选中一项。 如果你有多组单选按钮, 每组都应该有不同的父控件,或者不同的 Layout。 通常建议:多组单选按钮,放到不同的 按钮组 QButtonGroup 中,按钮组就是父控件

方法:获取是否选中

radioButton.isChecked()

信号:选中状态改变
如果用户操作点击了按钮组 QButtonGroup 中的一个按钮, QButtonGroup 就会发出 buttonClicked 信号,可以这样指定处理该信号的函数

buttongroup.buttonClicked.connect(handleButtonClicked)

然后,在处理函数中调用 QButtonGroup 对象的 checkedButton() 函数,返回值就是被选中的按钮对象。
再调用这个返回的按钮对象的 text() 方法得到界面文本,就可以知道是哪个选项被选中了。

# 多选框 QCheckBox

说明
通常建议:多组勾选按钮,放到不同的 按钮组 QButtonGroup 中,按钮组就是父控件。

信号:选中状态改变
如果用户操作点击了按钮组 QButtonGroup 中的一个按钮, QButtonGroup 就会发出 buttonClicked 信号,可以这样指定处理该信号的函数

buttongroup.buttonClicked.connect(handleButtonClicked)

然后,在处理函数中调用 QButtonGroup 对象的 checkedButton() 函数,返回值就是被选中的按钮对象。
再调用这个返回的按钮对象的 text() 方法得到界面文本,就可以知道是哪个选项被选中了。

# 进度条 QProgressBar

说明
进度条也是一个常用的控件,当程序需要做一件比较耗费时间的任务(比如统计数据,下载文件等)时,可以用来向用户指示操作的进度。 而且有了进度显示,用户就知道应用程序仍在运行,并没有出问题。 QProgressBar 进度条把每个进度称之为一个 step(步骤)。 我们可以通过它的 setRange 方法设定步骤个数

progressBar.setRange(0,5)

就设定了,进度分为 5 步。 然后,通过 setValue 方法,指定当前完成到了哪一步 progressBar.setValue(3) 就表示完成了 3/5, 也就是 60%, 进度条就会显示 60%的进度。 可以使用 reset()将进度条倒退到开头。 有时候我们的任务没法知道完成了多少下载一个未知大小的文件。 这时,可以把 range 范围都设置为 0,这样,进度条会显示忙碌指示符,而不是显示进度百分比。

下面是一个进度条程序的示例代码

点击查看代码
from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton,  QProgressBar,QMessageBox
from time import sleep
from threading import  Thread

# 定义信号对象
from PySide2.QtCore import Signal,QObject
class SignalSrc(QObject):
    progress_update = Signal(int)

class Stats():
    def __init__(self):
        self.so = SignalSrc()
        # 连接信号到处理的slot函数
        self.so.progress_update.connect(self.setProgress)

        self.window = QMainWindow()
        self.window.resize(500, 400)
        self.window.move(300, 300)

        self.progressBar = QProgressBar(self.window)
        self.progressBar.resize(300, 20)
        self.progressBar.move(80, 30)
        # 进度是 0 - 5,
        self.progressBar.setRange(0,5)

        self.button = QPushButton('统计', self.window)
        self.button.move(80, 80)

        self.button.clicked.connect(self.handleCalc)

        # 统计进行中标记,不能同时做两个统计
        self.ongoing = False

    def handleCalc(self):
        def workerThreadFunc():
            self.ongoing = True
            for i in range(1,6):
                sleep(1)
                # 发出信息,通知主线程进行进度处理
                self.so.progress_update.emit(i)
            self.ongoing = False

        if self.ongoing:
            QMessageBox.warning(
                self.window,
                '警告','任务进行中,请等待完成')
            return

        worker = Thread(target=workerThreadFunc)
        worker.start()

    # 处理进度的slot函数
    def setProgress(self,value):
        self.progressBar.setValue(value)


app = QApplication([])
stats = Stats()
stats.window.show()
app.exec_()
最后更新: 2020/9/15 19:42:22