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