PyQt5 - QWidgets部件进阶教程之行编辑

导言

该案例所含的独立视窗类,包括了不同选择的行编辑,该选择有限制输入和显示属性,这可以通过复合框中的项进行选择更改。集中体现这些,是为了帮助开发者选择适合的属性用于行编辑,并使得容易比较每种用户输入验证的效果。


定义窗口类

Window类继承自QWidget,包含一个构造器和一些槽,当在符合框内选择一个新的验证器时,这些槽用于更新其类型。Window构造器用于设置行编辑、验证器和复合框,将复合框信号链接到类中的槽,并在布局中排列子部件。我们开始创建一个容纳标签的组合框、复合框和行编辑,这样我们就能演示QLineEdit.echoMode属性。

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

import sys

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

        self.echoGroup = QGroupBox('Echo')
        self.echoLabel = QLabel('Mode:')
        self.echoComboBox = QComboBox()
        self.echoComboBox.addItem('Normal')
        self.echoComboBox.addItem('Password')
        self.echoComboBox.addItem('PasswordEchoOnEdit')
        self.echoComboBox.addItem('No Echo')
        self.echoLineEdit = QLineEdit()
        self.echoLineEdit.setPlaceholderText('Placeholder Text')
        self.echoLineEdit.setFocus()
  • 这里所有的部件都没有排列到布局,最终echoLabel、echoComboBox和echoLineEdit会放置到echoGroup的垂直布局。

下面我们构建组合框,并构建体现行编辑内容的QIntValidator和QDoubleValidator显示效果的部件集合。

        self.validatorGroup = QGroupBox('Validator')
        self.validatorLabel = QLabel('Type:')
        self.validatorComboBox = QComboBox()
        self.validatorComboBox.addItem('No validator')
        self.validatorComboBox.addItem('Integer validator')
        self.validatorComboBox.addItem('Double validator')
        self.validatorLineEdit = QLineEdit()
        self.validatorLineEdit.setPlaceholderText('Placeholder Text')

文本对齐方式通过其他部件组演示

        self.alignmentGroup = QGroupBox('Alignment')
        self.alignmentLabel = QLabel('Type:')
        self.alignmentComboBox = QComboBox()
        self.alignmentComboBox.addItem('Left')
        self.alignmentComboBox.addItem('Centered')
        self.alignmentComboBox.addItem('Right')
        self.alignmentLineEdit = QLineEdit()
        self.alignmentLineEdit.setPlaceholderText('Placeholder Text')

QLineEdit支持输入模板的使用,这只允许用户根据规范输入字符。我们构建一个部件组来演示预定义模板的选项。

        self.inputMaskGroup = QGroupBox('Input mask')
        self.inputMaskLabel = QLabel('Type:')
        self.inputMaskComboBox = QComboBox()
        self.inputMaskComboBox.addItem('No mask')
        self.inputMaskComboBox.addItem('Phone number')
        self.inputMaskComboBox.addItem('ISO date')
        self.inputMaskComboBox.addItem('License key')
        self.inputMaskLineEdit = QLineEdit()
        self.inputMaskLineEdit.setPlaceholderText('Placeholder Text')

QLineEdit其他有用的特性是可以设置它的内容为只读。

        self.accessGroup = QGroupBox('Access')
        self.accessLabel = QLabel('Read-only:')
        self.accessComboBox = QComboBox()
        self.accessComboBox.addItem('False')
        self.accessComboBox.addItem('True')
        self.accessLineEdit = QLineEdit()
        self.accessLineEdit.setPlaceholderText('Placeholder Text')

现在,所有的子部件构建完毕,我们将复合框的信号连接到Window对象。

        self.echoComboBox.activated.connect(self.echoChanged)
        self.validatorComboBox.activated.connect(self.validatorChanged)
        self.alignmentComboBox.activated.connect(self.alignmentChanged)
        self.inputMaskComboBox.activated.connect(self.inputMaskChanged)
        self.accessComboBox.activated.connect(self.accessChanged)
  • 每个链接都使用了QComboBox.activated()信号,这会用于改变相应槽的行编辑。

我们为每个分组框的复合框、行编辑和标签设置布局,先从echoGroup布局开始:

        self.echoLayout = QGridLayout()
        self.echoLayout.addWidget(self.echoLabel, 0, 0)
        self.echoLayout.addWidget(self.echoComboBox, 0, 1)
        self.echoLayout.addWidget(self.echoLineEdit, 1, 0, 1, 2)
        self.echoGroup.setLayout(self.echoLayout)

其他布局构造与此类似:

        self.validatorLayout = QGridLayout()
        self.validatorLayout.addWidget(self.validatorLabel, 0, 0)
        self.validatorLayout.addWidget(self.validatorComboBox, 0, 1)
        self.validatorLayout.addWidget(self.validatorLineEdit, 1, 0, 1, 2)
        self.validatorGroup.setLayout(self.validatorLayout)

        self.alignmentLayout = QGridLayout()
        self.alignmentLayout.addWidget(self.alignmentLabel, 0, 0)
        self.alignmentLayout.addWidget(self.alignmentComboBox, 0, 1)
        self.alignmentLayout.addWidget(self.alignmentLineEdit, 1, 0, 1, 2)
        self.alignmentGroup.setLayout(self.alignmentLayout)

        self.inputMaskLayout = QGridLayout()
        self.inputMaskLayout.addWidget(self.inputMaskLabel, 0, 0)
        self.inputMaskLayout.addWidget(self.inputMaskComboBox, 0, 1)
        self.inputMaskLayout.addWidget(self.inputMaskLineEdit, 1, 0, 1, 2)
        self.inputMaskGroup.setLayout(self.inputMaskLayout)

        self.accessLayout = QGridLayout()
        self.accessLayout.addWidget(self.accessLabel, 0, 0)
        self.accessLayout.addWidget(self.accessComboBox, 0, 1)
        self.accessLayout.addWidget(self.accessLineEdit, 1, 0, 1, 2)
        self.accessGroup.setLayout(self.accessLayout)

最后,我们将每个分组框放置到网格布局并设置视窗标题:

        self.Layout = QGridLayout()
        self.Layout.addWidget(self.echoGroup, 0, 0)
        self.Layout.addWidget(self.validatorGroup, 1, 0)
        self.Layout.addWidget(self.alignmentGroup, 2, 0)
        self.Layout.addWidget(self.inputMaskGroup, 0, 1)
        self.Layout.addWidget(self.accessGroup, 1, 1)
        self.setLayout(self.Layout)

        self.setWindowTitle('Line Edits')

当用户改变复合框时,槽响应发射的信号。当Echo group复合框改变时,调用echoChanged()槽:

    def echoChanged(self, index):
        if index == 0:
            self.echoLineEdit.setEchoMode(QLineEdit.Normal)
        elif index == 1:
            self.echoLineEdit.setEchoMode(QLineEdit.Password)
        elif index == 2:
            self.echoLineEdit.setEchoMode(QLineEdit.PasswordEchoOnEdit)
        elif index == 3:
            self.echoLineEdit.setEchoMode(QLineEdit.NoEcho)
  • 在组框内使用echo mode,该槽更新行编辑。

当验证组复合框改变时,调用validatorChanged()槽:

    def validatorChanged(self, index):
        if index == 0:
            self.validatorLineEdit.setValidator(0)
        elif index == 1:
            self.validatorLineEdit.setValidator(QIntValidator(self.validatorLineEdit))
        elif index == 2:
            self.validatorLineEdit.setValidator(QDoubleValidator(-999.0, 999.0, 2, self.validatorLineEdit))

        self.validatorLineEdit.clear()
  • 该槽为行编辑创建了一个新的验证器,并通过调用QLineEdit.setValidator(0) 移除了使用中的验证器。我们清除行编辑来确保新的验证器初始下赋予有效的输入。
    def alignmentChanged(self, index):
        if index == 0:
            self.alignmentLineEdit.setAlignment(Qt.AlignLeft)
        elif index == 1:
            self.alignmentLineEdit.setAlignment(Qt.AlignCenter)
        elif index == 2:
            self.alignmentLineEdit.setAlignment(Qt.AlignRight)
  • 这会改变行编辑中的文本与对应选择的描述方式相同。
    def inputMaskChanged(self, index):
        if index == 0:
            self.inputMaskLineEdit.setInputMask('')
        elif index == 1:
            self.inputMaskLineEdit.setInputMask('+99 99 99 99 99;_')
        elif index == 2:
            self.inputMaskLineEdit.setInputMask('0000-00-00')
            self.inputMaskLineEdit.setText('00000000')
            self.inputMaskLineEdit.setCursorPosition(0)
        elif index == 3:
            self.inputMaskLineEdit.setInputMask('>AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;#')
  • 在相关复合框中的每个输入,都与输入模板相关。我们通过调用QLineEdit.setMask()函数设置一个合适的字符串模板,模板禁止空字符。
    def accessChanged(self, index):
        if index == 0:
            self.accessLineEdit.setReadOnly(False)
        elif index == 1:
            self.accessLineEdit.setReadOnly(True)
  • 通过设置QLineEdit.setReadOnly(),简单关联了复合框中False和True输入,这允许用户开启或关闭行编辑的输入。

最终代码

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

import sys

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

        self.echoGroup = QGroupBox('Echo')
        self.echoLabel = QLabel('Mode:')
        self.echoComboBox = QComboBox()
        self.echoComboBox.addItem('Normal')
        self.echoComboBox.addItem('Password')
        self.echoComboBox.addItem('PasswordEchoOnEdit')
        self.echoComboBox.addItem('No Echo')
        self.echoLineEdit = QLineEdit()
        self.echoLineEdit.setPlaceholderText('Placeholder Text')
        self.echoLineEdit.setFocus()

        self.validatorGroup = QGroupBox('Validator')
        self.validatorLabel = QLabel('Type:')
        self.validatorComboBox = QComboBox()
        self.validatorComboBox.addItem('No validator')
        self.validatorComboBox.addItem('Integer validator')
        self.validatorComboBox.addItem('Double validator')
        self.validatorLineEdit = QLineEdit()
        self.validatorLineEdit.setPlaceholderText('Placeholder Text')

        self.alignmentGroup = QGroupBox('Alignment')
        self.alignmentLabel = QLabel('Type:')
        self.alignmentComboBox = QComboBox()
        self.alignmentComboBox.addItem('Left')
        self.alignmentComboBox.addItem('Centered')
        self.alignmentComboBox.addItem('Right')
        self.alignmentLineEdit = QLineEdit()
        self.alignmentLineEdit.setPlaceholderText('Placeholder Text')

        self.inputMaskGroup = QGroupBox('Input mask')
        self.inputMaskLabel = QLabel('Type:')
        self.inputMaskComboBox = QComboBox()
        self.inputMaskComboBox.addItem('No mask')
        self.inputMaskComboBox.addItem('Phone number')
        self.inputMaskComboBox.addItem('ISO date')
        self.inputMaskComboBox.addItem('License key')
        self.inputMaskLineEdit = QLineEdit()
        self.inputMaskLineEdit.setPlaceholderText('Placeholder Text')

        self.accessGroup = QGroupBox('Access')
        self.accessLabel = QLabel('Read-only:')
        self.accessComboBox = QComboBox()
        self.accessComboBox.addItem('False')
        self.accessComboBox.addItem('True')
        self.accessLineEdit = QLineEdit()
        self.accessLineEdit.setPlaceholderText('Placeholder Text')

        self.echoComboBox.activated.connect(self.echoChanged)
        self.validatorComboBox.activated.connect(self.validatorChanged)
        self.alignmentComboBox.activated.connect(self.alignmentChanged)
        self.inputMaskComboBox.activated.connect(self.inputMaskChanged)
        self.accessComboBox.activated.connect(self.accessChanged)

        self.echoLayout = QGridLayout()
        self.echoLayout.addWidget(self.echoLabel, 0, 0)
        self.echoLayout.addWidget(self.echoComboBox, 0, 1)
        self.echoLayout.addWidget(self.echoLineEdit, 1, 0, 1, 2)
        self.echoGroup.setLayout(self.echoLayout)

        self.validatorLayout = QGridLayout()
        self.validatorLayout.addWidget(self.validatorLabel, 0, 0)
        self.validatorLayout.addWidget(self.validatorComboBox, 0, 1)
        self.validatorLayout.addWidget(self.validatorLineEdit, 1, 0, 1, 2)
        self.validatorGroup.setLayout(self.validatorLayout)

        self.alignmentLayout = QGridLayout()
        self.alignmentLayout.addWidget(self.alignmentLabel, 0, 0)
        self.alignmentLayout.addWidget(self.alignmentComboBox, 0, 1)
        self.alignmentLayout.addWidget(self.alignmentLineEdit, 1, 0, 1, 2)
        self.alignmentGroup.setLayout(self.alignmentLayout)

        self.inputMaskLayout = QGridLayout()
        self.inputMaskLayout.addWidget(self.inputMaskLabel, 0, 0)
        self.inputMaskLayout.addWidget(self.inputMaskComboBox, 0, 1)
        self.inputMaskLayout.addWidget(self.inputMaskLineEdit, 1, 0, 1, 2)
        self.inputMaskGroup.setLayout(self.inputMaskLayout)

        self.accessLayout = QGridLayout()
        self.accessLayout.addWidget(self.accessLabel, 0, 0)
        self.accessLayout.addWidget(self.accessComboBox, 0, 1)
        self.accessLayout.addWidget(self.accessLineEdit, 1, 0, 1, 2)
        self.accessGroup.setLayout(self.accessLayout)

        self.Layout = QGridLayout()
        self.Layout.addWidget(self.echoGroup, 0, 0)
        self.Layout.addWidget(self.validatorGroup, 1, 0)
        self.Layout.addWidget(self.alignmentGroup, 2, 0)
        self.Layout.addWidget(self.inputMaskGroup, 0, 1)
        self.Layout.addWidget(self.accessGroup, 1, 1)
        self.setLayout(self.Layout)

        self.setWindowTitle('Line Edits')

    def echoChanged(self, index):
        if index == 0:
            self.echoLineEdit.setEchoMode(QLineEdit.Normal)
        elif index == 1:
            self.echoLineEdit.setEchoMode(QLineEdit.Password)
        elif index == 2:
            self.echoLineEdit.setEchoMode(QLineEdit.PasswordEchoOnEdit)
        elif index == 3:
            self.echoLineEdit.setEchoMode(QLineEdit.NoEcho)

    def validatorChanged(self, index):
        if index == 0:
            self.validatorLineEdit.setValidator(0)
        elif index == 1:
            self.validatorLineEdit.setValidator(QIntValidator(self.validatorLineEdit))
        elif index == 2:
            self.validatorLineEdit.setValidator(QDoubleValidator(-999.0, 999.0, 2, self.validatorLineEdit))

        self.validatorLineEdit.clear()

    def alignmentChanged(self, index):
        if index == 0:
            self.alignmentLineEdit.setAlignment(Qt.AlignLeft)
        elif index == 1:
            self.alignmentLineEdit.setAlignment(Qt.AlignCenter)
        elif index == 2:
            self.alignmentLineEdit.setAlignment(Qt.AlignRight)

    def inputMaskChanged(self, index):
        if index == 0:
            self.inputMaskLineEdit.setInputMask('')
        elif index == 1:
            self.inputMaskLineEdit.setInputMask('+99 99 99 99 99;_')
        elif index == 2:
            self.inputMaskLineEdit.setInputMask('0000-00-00')
            self.inputMaskLineEdit.setText('00000000')
            self.inputMaskLineEdit.setCursorPosition(0)
        elif index == 3:
            self.inputMaskLineEdit.setInputMask('>AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;#')

    def accessChanged(self, index):
        if index == 0:
            self.accessLineEdit.setReadOnly(False)
        elif index == 1:
            self.accessLineEdit.setReadOnly(True)


app = QApplication(sys.argv)
win = Window()
win.show()
app.exec_()

最终效果

这里写图片描述

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值