在上一篇里,实现的模态对话框的功能就是修改数据显示的格式,并进行提交后验证。在未应用该对话框之前,用户不能与对话框的父窗口以及父窗口的兄弟窗口就行交互,这样就保证了应用程序相关部分的状态不会在该对话框关闭之前改变。
可是如果我们想并不确定这一次的设置效果如何,需要多次调整设置的时候,模态对话框就显得不那么方便了。 这时候就可以利用非模态对话框,点击“应用”(apply)按钮来预览设置修改后的结果。
一般来说,模态对话框含有“接受”(accept)按钮和“拒绝”(reject)按钮;非模态对话框则含有“应用”(apply)按钮。
同样的目的,这次是非模态对话框。
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class MainWindow(QWidget):
def __init__(self,parent=None):
QWidget.__init__(self,parent)
button = QPushButton("click me",self)
button.clicked.connect(self.setNumberFormat)
self.format = dict(thousandsseparator=',',decimalmarker='.',decimalplaces=2,rednegatives=True)
def setNumberFormat(self):
dialog = Intelligent(self.format,self)
self.connect(dialog,SIGNAL('changed'),self.refreshTable)
dialog.show()
def refreshTable(self):
print 1
class Intelligent(QDialog):
def __init__(self,format,parent=None):
super(Intelligent,self).__init__(parent)
self.setAttribute(Qt.WA_DeleteOnClose) # ensure the dialog box can be detele while you click the 'close'
punctuationRe = QRegExp(r"[ ,;:.]")
thousandsLabel = QLabel("&Thousands separator")
self.thousandsEdit = QLineEdit(format["thousandsseparator"])
thousandsLabel.setBuddy(self.thousandsEdit)
self.thousandsEdit.setMaxLength(1) #the new function setMaxLength
self.thousandsEdit.setValidator(
QRegExpValidator(punctuationRe, self)) #set the check
decimalMarkerLabel = QLabel("Decimal &marker")
self.decimalMarkerEdit = QLineEdit(format["decimalmarker"])
decimalMarkerLabel.setBuddy(self.decimalMarkerEdit)
self.decimalMarkerEdit.setMaxLength(1)
self.decimalMarkerEdit.setValidator(
QRegExpValidator(punctuationRe, self))
self.decimalMarkerEdit.setInputMask("X") # the new function ,set the input,and the X means anything
decimalPlacesLabel = QLabel("&Decimal places")
self.decimalPlacesSpinBox = QSpinBox()
decimalPlacesLabel.setBuddy(self.decimalPlacesSpinBox)
self.decimalPlacesSpinBox.setRange(0,6)
self.decimalPlacesSpinBox.setValue(format['decimalplaces'])
self.redNegativesCheckBox = QCheckBox("&Red negative numbers")
self.redNegativesCheckBox.setChecked(format["rednegatives"])
buttonBox = QDialogButtonBox(QDialogButtonBox.Apply|QDialogButtonBox.Close|QDialogButtonBox.Ok)
self.format = format
layout = QGridLayout()
layout.addWidget(thousandsLabel,0,0)
layout.addWidget(self.thousandsEdit,0,1)
layout.addWidget(decimalMarkerLabel,1,0)
layout.addWidget(self.decimalMarkerEdit,1,1)
layout.addWidget(decimalPlacesLabel,2,0)
layout.addWidget(self.decimalPlacesSpinBox,2,1)
layout.addWidget(self.redNegativesCheckBox,3,0,1,2)
layout.addWidget(buttonBox,4,0,1,2)
self.setLayout(layout)
self.connect(buttonBox.button(QDialogButtonBox.Apply),SIGNAL("clicked()"),self.apply) self.connect(buttonBox,SIGNAL("rejected()"),self,SLOT("reject()"))
self.connect(buttonBox,SIGNAL("accepted()"),self,SLOT("accept()"))
self.setWindowTitle("Set Number Format (Mode;ess)")
def apply(self):
thousands = unicode(self.thousandsEdit.text())
decimal = unicode(self.decimalMarkerEdit.text())
if thousands == decimal:
QMessageBox.warning(self,"Format Error",
"The thousands separator and the decimal marker"
"must be different.")
self.thousandsEdit.selectAll()
self.thousandsEdit.setFocus()
return
if len(decimal) == 0:
QMessageBox.warning(self,"Format Error",
"the decimal marker may nor be empty.")
self.decimalMarkerEdit.selectAll()
self.decimalMarkerEdit.setFocus()
return
self.format['thousandsseparator'] = thousands
self.format['decimalmarker'] = decimal
self.format['decimalplaces'] = \
self.decimalPlacesSpinBox.value()
self.format['rednegatives'] = \
self.redNegativesCheckBox.isChecked()
self.emit(SIGNAL("changed"))
app = QApplication(sys.argv)
widget = MainWindow()
widget.show()
app.exec_()