常用控件3

大家可以先根据我们网站自学。

如果自学速度慢、难点搞不定,欢迎来报 `实战班` 学习。
白月黑羽 1对1 直播讲解答疑,大量练习实战,学习效果是自学没法比的。

点击这里查看实战班介绍 咨询微信:18502556834

单选按钮 和 按钮组

QRadioButton 是单选按钮,如下图所示

image

官网介绍

说明

同一个父窗口 里面的多个单选按钮,只能选中一项。

如果你有多组单选按钮, 每组都应该有不同的父控件,或者不同的Layout。

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

具体内容,点击这里,查看视频讲解

信号:选中状态改变

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

buttongroup.buttonClicked.connect(handleButtonClicked)

然后,在处理函数中调用QButtonGroup对象的 checkedButton() 函数,返回值就是被选中的按钮对象。

再调用这个返回的按钮对象的 text() 方法得到界面文本,就可以知道是哪个选项被选中了。

勾选按钮 和 按钮组

QCheckBox 是勾选按钮,如下图所示

image

官网介绍

说明

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

信号:选中状态改变

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

buttongroup.buttonClicked.connect(handleButtonClicked)

然后,在处理函数中调用QButtonGroup对象的 checkedButton() 函数,返回值就是被选中的按钮对象。

再调用这个返回的按钮对象的 text() 方法得到界面文本,就可以知道是哪个选项被选中了。

tab页控件

我们可以通过tab页控件把界面分为好几各页面,如下所示

image

通过Qt designer 只需要拖拽控件到各个页面即可。

要修改tab页的标题,可以先点击该tab页,然后在下图所示处修改

image


tab页中布局Layout

如果我们要在tab页上布局, 你可能会在对象查看器总直接右键点击该tab,可以你会发现 右键菜单里面没有布局项。

这是 Qt designer 非常坑爹的地方,我当时足足花了一个小时才找到方法。

  1. 首先需要你在tab页上添加一个控件

  2. 然后点击 在对象查看器 右键点击上层 TabWidget ,这时,你就会发现有布局菜单了

点击这里,看视频讲解tab页中布局Layout

进度条

QProgressBar 是进度条,如下图所示

qt0001

官网介绍

说明

进度条也是一个常用的控件,当程序需要做一件比较耗费时间的任务(比如统计数据,下载文件等)时,可以用来向用户指示操作的进度。

而且有了进度显示,用户就知道应用程序仍在运行,并没有出问题。

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

class Stats():
    def __init__(self):
        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.progressBar.setValue(i)
            self.ongoing = False

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

        # 通常任务执行比较耗时,应该在新的线程中进行
        # 否则会阻塞主线程显示界面
        worker = Thread(target=workerThreadFunc)
        worker.start()

app = QApplication([])
stats = Stats()
stats.window.show()
app.exec_()

上面的代码,运行时,会有很多告警,因为我们在新线程中操作界面对象,容易出问题。

更合理的方法是通过信号,在线程之间传递信息,对界面的操作都在主线程中完成。

如下

from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton,  QProgressBar,QMessageBox
from time import sleep
from threading import  Thread
from PySide2.QtCore import Signal,QObject

# 信号库
class SignalStore(QObject):
    # 定义一种信号
    progress_update = Signal(int)
    # 还可以定义其他作用的信号

# 实例化
so = SignalStore()

class Stats():
    def __init__(self): 
        # 连接信号到处理的slot函数
        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)
                # 发出信息,通知主线程进行进度处理
                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_()

数字输入框

QSpinBox 是数字输入框,可以输入或使用上下箭头选择数字,如下图所示

qt0001

官网介绍

获取数字

通过 value 方法获取编辑框内的文本内容,比如

number = box.value()

注意:返回的是整数对象,不是字符串

方法:设置数字

通过 setValue 方法可以设置提示文本内容,比如

box.setValue(100)

选择文件框

QFileDialog 类可以用来选择文件或者目录,如下图所示

image

官网介绍

选择目录

通过 getExistingDirectory 静态方法 选择目录。

该方法,第一个参数是父窗口对象,第二个参数是选择框显示的标题。

比如

filePath = QFileDialog.getExistingDirectory(self.ui, "选择存储路径")

返回值即为选择的路径字符串。

如果用户点击了 选择框的 取消选择按钮,返回 空字符串。

选择单个文件

通过 getOpenFileName 静态方法 可以设置提示文本内容,比如

filePath, _  = QFileDialog.getOpenFileName(
            self.ui,             # 父窗口对象
            "选择你要上传的图片", # 标题
            r"d:\\data",        # 起始目录
            "图片类型 (*.png *.jpg *.bmp)" # 选择类型过滤项,过滤内容在括号中
        )

因为该方法返回的是一个元组,第一个元素是选择的文件路径,第二个元素是文件类型,如果你只想获取文件路径即可,可以采用上面的代码写法。

如果用户点击了 选择框的 取消选择按钮,返回 空字符串。

选择多个文件

如果要选择多个文件,使用 getOpenFileNames 静态方法

filePaths, _  = QFileDialog.getOpenFileNames(
            self.ui,             # 父窗口对象
            "选择你要上传的图片", # 标题
            r"d:\\data",        # 起始目录
            "图片类型 (*.png *.jpg *.bmp)" # 选择类型过滤项,过滤内容在括号中
        )

上例中 filePaths 对应的返回值是一个列表,里面包含了选择的文件。

如果用户点击了 选择框的 取消选择按钮,返回 空列表。

提示框

QMessageBox 类可以用来弹出各种提示框

官网介绍

该类可以通过一系列静态方法,显示 如下弹出框

  • 错误报告

image

使用 critical 方法

QMessageBox.critical(
    self.ui,
    '错误',
    '请选择爬取数据存储路径!')
  • 警告

image

使用 warning 方法

QMessageBox.warning(
    self.ui,
    '阅读太快',
    '阅读客户协议必须超过1分钟')
  • 信息提示

image

使用 information 方法

QMessageBox.information(
    self.ui,
    '操作成功',
    '请继续下一步操作')

也可以使用 about 方法

QMessageBox.about(
    self.ui,
    '操作成功',
    '请继续下一步操作')
  • 确认继续

image

使用 question 方法

choice = QMessageBox.question(
    self.ui,
    '确认',
    '确定要删除本文件吗?')

if choice == QMessageBox.Yes:
    print('你选择了yes')
if choice == QMessageBox.No:
    print('你选择了no')

菜单

可以在 Qt Designer上很方便的添加菜单,如下所示

image

点击菜单的信号是 triggered, 处理点击菜单的的代码如下

self.ui.actionOpenFile.triggered.connect(self.openPageFile)

状态栏

官网介绍

要在状态栏显示文本信息,只需要调用 QStatusBar 的 showMessage 方法

self.ui.statusbar.showMessage(f'打开文件{filePath}')

剪贴板

官网介绍

from PySide2.QtGui import QGuiApplication

cb = QGuiApplication.clipboard()
# 获取剪贴板内容
originalText = cb.text()
# 设置剪贴板内容
clipboard.setText(newText)

上一页
下一页