警告
本节包含从C++自动翻译成Python的代码片段,可能包含错误。
旋转框示例#
旋转框示例展示了如何在Qt中使用多种不同类型的旋转框,从简单的QSpinBox
小部件到一个更复杂的编辑器,如QDateTimeEdit
小部件。
示例由一个用于显示Qt中可用的不同旋转框小部件的单一Window
类组成。
窗口类定义#
Window
类继承自QWidget
,包含用于提供交互功能的两个槽
class Window(QWidget): Q_OBJECT # public Window(QWidget parent = None) # public slots def changePrecision(decimals): def setFormatString(formatString): # private def createSpinBoxes(): def createDateTimeEdits(): def createDoubleSpinBoxes(): meetingEdit = QDateTimeEdit() doubleSpinBox = QDoubleSpinBox() priceSpinBox = QDoubleSpinBox() scaleSpinBox = QDoubleSpinBox() spinBoxesGroup = QGroupBox() editsGroup = QGroupBox() doubleSpinBoxesGroup = QGroupBox() meetingLabel = QLabel() groupSeparatorSpinBox = QSpinBox() groupSeparatorSpinBox_d = QDoubleSpinBox()
私有函数用于设置窗口中每种类型的旋转框。我们使用成员变量来跟踪各种小部件,以便在有需要时重新配置它们。
窗口类实现#
构造函数仅调用私有函数来设置示例中使用的不同类型的旋转框,并将每个组放置在布局中
def __init__(self, parent): super().__init__(parent) createSpinBoxes() createDateTimeEdits() createDoubleSpinBoxes() layout = QHBoxLayout() layout.addWidget(spinBoxesGroup) layout.addWidget(editsGroup) layout.addWidget(doubleSpinBoxesGroup) setLayout(layout) setWindowTitle(tr("Spin Boxes"))
我们使用布局来管理窗口子小部件的排列,并更改窗口标题。
createSpinBoxes()
函数构建一个QGroupBox
并将三个带有描述性标签的QSpinBox
小部件放置在内,以表示它们所期望的输入类型。
def createSpinBoxes(self): spinBoxesGroup = QGroupBox(tr("Spinboxes")) integerLabel = QLabel(tr("Enter a value between "() "%1 and %2:").arg(-20).arg(20)) integerSpinBox = QSpinBox() integerSpinBox.setRange(-20, 20) integerSpinBox.setSingleStep(1) integerSpinBox.setValue(0)
第一个旋转框展示了使用QSpinBox
的最简单方法。它接受从-20到20的值,当前值可以通过箭头按钮或上下键增加或减少1,默认值为0。
第二个旋转框使用了更大的步长,并显示后缀以提供有关数字表示的数据类型的更多信息
zoomLabel = QLabel(tr("Enter a zoom value between "() "%1 and %2:").arg(0).arg(1000)) zoomSpinBox = QSpinBox() zoomSpinBox.setRange(0, 1000) zoomSpinBox.setSingleStep(10) zoomSpinBox.setSuffix("%") zoomSpinBox.setSpecialValueText(tr("Automatic")) zoomSpinBox.setValue(100)
此旋转框也显示了一个特殊的值而不是它定义的最小值。这意味着它永远不会显示0%,而是当选择最小值时显示“自动”。
第三个旋转框展示了如何使用前缀
priceLabel = QLabel(tr("Enter a price between "() "%1 and %2:").arg(0).arg(999)) priceSpinBox = QSpinBox() priceSpinBox.setRange(0, 999) priceSpinBox.setSingleStep(1) priceSpinBox.setPrefix("$") priceSpinBox.setValue(99)
为了简化,我们展示了一个带有前缀但没有后缀的旋转框。同时也可以同时使用两者。
groupSeparatorSpinBox = QSpinBox() groupSeparatorSpinBox.setRange(-99999999, 99999999) groupSeparatorSpinBox.setValue(1000) groupSeparatorSpinBox.setGroupSeparatorShown(True) groupSeparatorChkBox = QCheckBox() groupSeparatorChkBox.setText(tr("Show group separator")) groupSeparatorChkBox.setChecked(True) groupSeparatorChkBox.toggled.connect(groupSeparatorSpinBox, QSpinBox.setGroupSeparatorShown) hexLabel = QLabel(tr("Enter a value between "() "%1 and %2:").arg('-' + QString.number(31, 16)).arg(QString.number(31, 16))) hexSpinBox = QSpinBox() hexSpinBox.setRange(-31, 31) hexSpinBox.setSingleStep(1) hexSpinBox.setValue(0) hexSpinBox.setDisplayIntegerBase(16) spinBoxLayout = QVBoxLayout() spinBoxLayout.addWidget(integerLabel) spinBoxLayout.addWidget(integerSpinBox) spinBoxLayout.addWidget(zoomLabel) spinBoxLayout.addWidget(zoomSpinBox) spinBoxLayout.addWidget(priceLabel) spinBoxLayout.addWidget(priceSpinBox) spinBoxLayout.addWidget(hexLabel) spinBoxLayout.addWidget(hexSpinBox) spinBoxLayout.addWidget(groupSeparatorChkBox) spinBoxLayout.addWidget(groupSeparatorSpinBox) spinBoxesGroup.setLayout(spinBoxLayout)
函数的其余部分设置组框的布局,并将每个小部件放置在内。
函数 createDateTimeEdits()
构建了一个带选择框的另一个分组框,用于编辑日期和时间。
def createDateTimeEdits(self): editsGroup = QGroupBox(tr("Date and time spin boxes")) dateLabel = QLabel() dateEdit = QDateEdit(QDate.currentDate()) dateEdit.setDateRange(QDate(2005, 1, 1), QDate(2010, 12, 31)) dateLabel.setText(tr("Appointment date (between %0 and %1):") .arg(dateEdit.minimumDate().toString(Qt.ISODate)) .arg(dateEdit.maximumDate().toString(Qt.ISODate)))
第一个选择框是一个 QDateEdit
小部件,可以接受使用 QDate 值指定的给定范围内的日期。当光标处于相关部分时,可以使用箭头按钮和上下键来增加和减少年、月和日的值。
第二个选择框是一个 QTimeEdit
小部件
timeLabel = QLabel() timeEdit = QTimeEdit(QTime.currentTime()) timeEdit.setTimeRange(QTime(9, 0, 0, 0), QTime(16, 30, 0, 0)) timeLabel.setText(tr("Appointment time (between %0 and %1):") .arg(timeEdit.minimumTime().toString(Qt.ISODate)) .arg(timeEdit.maximumTime().toString(Qt.ISODate)))
时间允许的值使用 QTime 值定义。
第三个选择框是一个 QDateTimeEdit
小部件,可以显示日期和时间值,我们在其上方放置一个标签以指示会议允许的时间范围。这些小部件会在用户更改格式字符串时更新。
meetingLabel = QLabel() meetingEdit = QDateTimeEdit(QDateTime.currentDateTime())
日期时间编辑器使用的格式字符串,同样也显示在标签的字符串中,是从组合框中的一组字符串中选择的
formatLabel = QLabel(tr("Format string for the meeting date "() "and time:")) formatComboBox = QComboBox() formatComboBox.addItem("yyyy-MM-dd hh:mm:ss (zzz 'ms')") formatComboBox.addItem("hh:mm:ss MM/dd/yyyy") formatComboBox.addItem("hh:mm:ss dd/MM/yyyy") formatComboBox.addItem("hh:mm:ss") formatComboBox.addItem("hh:mm ap") formatComboBox.textActivated.connect( self.setFormatString)
来自此组合框的信号连接到 Window
类(稍后显示)中的槽。
editsLayout = QVBoxLayout() editsLayout.addWidget(dateLabel) editsLayout.addWidget(dateEdit) editsLayout.addWidget(timeLabel) editsLayout.addWidget(timeEdit) editsLayout.addWidget(meetingLabel) editsLayout.addWidget(meetingEdit) editsLayout.addWidget(formatLabel) editsLayout.addWidget(formatComboBox) editsGroup.setLayout(editsLayout)
分组框中的每个子小部件都放置在布局中。
每当用户在组合框中选择新的格式字符串时,都会调用 setFormatString()
槽。使用信号传递的原始字符串设置 QDateTimeEdit
小部件的显示格式
def setFormatString(self, formatString): meetingEdit.setDisplayFormat(formatString)
根据可见的部分,我们设置一个新的日期或时间范围,并更新相关的标签,以提供用户相关的信息
if meetingEdit.displayedSections() QDateTimeEdit.DateSections_Mask: meetingEdit.setDateRange(QDate(2004, 11, 1), QDate(2005, 11, 30)) meetingLabel.setText(tr("Meeting date (between %0 and %1):") .arg(meetingEdit.minimumDate().toString(Qt.ISODate)) .arg(meetingEdit.maximumDate().toString(Qt.ISODate))) else: meetingEdit.setTimeRange(QTime(0, 7, 20, 0), QTime(21, 0, 0, 0)) meetingLabel.setText(tr("Meeting time (between %0 and %1):") .arg(meetingEdit.minimumTime().toString(Qt.ISODate)) .arg(meetingEdit.maximumTime().toString(Qt.ISODate)))
当格式字符串更改时,将会有适当的标签和日期、时间或两种类型的输入的小部件。
函数 createDoubleSpinBoxes()
构建了三个用于输入双精度浮点数的选取框
def createDoubleSpinBoxes(self): doubleSpinBoxesGroup = QGroupBox(tr("Double precision spinboxes")) precisionLabel = QLabel(tr("Number of decimal places "() "to show:")) precisionSpinBox = QSpinBox() precisionSpinBox.setRange(0, 100) precisionSpinBox.setValue(2)
在构建 QDoubleSpinBox
小部件之前,我们创建了一个选择框来控制它们显示的小数位数。默认情况下,以下选取框中只显示两位小数,每个都相当于由函数 createSpinBoxes()
创建的分组中的选取框。
第一个双精度选取框显示了一个基本的双精度选取框,其范围、步长和默认值与 createSpinBoxes()
函数中的第一个选取框相同
doubleLabel = QLabel(tr("Enter a value between "() "%1 and %2:").arg(-20).arg(20)) doubleSpinBox = QDoubleSpinBox() doubleSpinBox.setRange(-20.0, 20.0) doubleSpinBox.setSingleStep(1.0) doubleSpinBox.setValue(0.0)
但是,此选取框也允许输入非整数值。
第二个选取框显示一个后缀,并显示一个特殊值而不是最小值
scaleLabel = QLabel(tr("Enter a scale factor between "() "%1 and %2:").arg(0).arg(1000.0)) scaleSpinBox = QDoubleSpinBox() scaleSpinBox.setRange(0.0, 1000.0) scaleSpinBox.setSingleStep(10.0) scaleSpinBox.setSuffix("%") scaleSpinBox.setSpecialValueText(tr("No scaling")) scaleSpinBox.setValue(100.0)
第三个选取框显示一个前缀而不是后缀
priceLabel = QLabel(tr("Enter a price between "() "%1 and %2:").arg(0).arg(1000)) priceSpinBox = QDoubleSpinBox() priceSpinBox.setRange(0.0, 1000.0) priceSpinBox.setSingleStep(1.0) priceSpinBox.setPrefix("$") priceSpinBox.setValue(99.99) precisionSpinBox.valueChanged.connect(
我们将指定精度的 QSpinBox
小部件连接到 Window
类的槽。
spinBoxLayout = QVBoxLayout() spinBoxLayout.addWidget(precisionLabel) spinBoxLayout.addWidget(precisionSpinBox) spinBoxLayout.addWidget(doubleLabel) spinBoxLayout.addWidget(doubleSpinBox) spinBoxLayout.addWidget(scaleLabel) spinBoxLayout.addWidget(scaleSpinBox) spinBoxLayout.addWidget(priceLabel) spinBoxLayout.addWidget(priceSpinBox) spinBoxLayout.addWidget(groupSeparatorChkBox) spinBoxLayout.addWidget(groupSeparatorSpinBox_d) doubleSpinBoxesGroup.setLayout(spinBoxLayout)
函数其余部分将每个小部件放置在一个用于组框的布局中。
当用户更改精度微调框中的值时,将调用 changePrecision()
槽。
def changePrecision(self, decimals): doubleSpinBox.setDecimals(decimals) scaleSpinBox.setDecimals(decimals) priceSpinBox.setDecimals(decimals)
此函数仅使用由信号提供的整数来指定每个 QDoubleSpinBox
小部件的十进制位数。每当它们的 decimals
属性更改时,这些将会自动更新。