在python中,我创建了一个类"ScrollMessageBoxShowRC",它接收三个参数(见下文(:
result = ScrollMessageBoxShowRC(QMessageBox.Information, '', '')
result.exec_()
最初,我用单独的";无";作为论据。只要它只接收到";无";,我可以如下调整类的大小:self.setStyleSheet("QScrollArea{最小宽度:410像素;最小高度:600像素}"(,见下图:
class ScrollMessageBoxShowRC(QMessageBox):
def __init__(self, *args, **kwargs):
QMessageBox.__init__(self, *args, **kwargs)
self.setWindowTitle("Contacts to view or to delete.")
scroll = QScrollArea(self)
scroll.setWidgetResizable(True)
self.content = QWidget()
scroll.setWidget(self.content)
lay = QVBoxLayout(self.content)
lay.setStyleSheet("min-width: 100px;");
dlts = {}
self.x = {}
for rc in dbaccess.allRC():
dlt = QCheckBox('delete', self)
dlt.stateChanged.connect(partial(self.btnstateDel, dlt, dlts))
dlt.setObjectName(rc[9])
qb = QPushButton(rc[9], self)
qb.released.connect(partial(self.button_releasedRC, rc[9]))
lay.addWidget(qb)
lay.addWidget(dlt)
self.buttonClicked.connect(self.msgButtonClickDel)
self.layout().addWidget(scroll, 0, 0, 1, self.layout().columnCount())
self.setStyleSheet("QScrollArea{min-width:410 px; min-height: 600px}")
def btnstateDel(self, dlt, dlts):
dlts[dlt.objectName()] = False
if dlt.isChecked:
dlts[dlt.objectName()] = True
self.x = dlts
def msgButtonClickDel(self, i):
if i.text() == "OK":
dbaccess.deleteRCs(self.x)
def button_releasedRC(self, nameshow):
pass
由于我将参数更改为QMessageBox.Information、"、",设置Widget大小的样式表似乎不再那么活跃了。我不知道为什么会这样。有人能告诉我我可能忽略了什么吗?
QMessageBox是一种特殊类型的QDialog,它在执行时创建自己的布局。当在没有参数的情况下创建时,它的行为几乎像一个基本的QDialog,但一旦添加了元素(最重要的是图标(,内部布局就会优先,在某些情况下,它也会被完全删除或重新创建。
由于QMessageBox通常是一个方便的简单类,并且这里使用的唯一实际特定功能似乎是图标,因此根本没有必要使用它。
可以使用基本的QDialog,并且可以使用样式加载图标,就像QMessageBox一样。然后可以使用QDialogButtonBox添加按钮。
class ScrollMessageBoxShowRC(QDialog):
def __init__(self, *args, **kwargs):
QDialog.__init__(self, *args, **kwargs)
layout = QGridLayout(self)
icon = self.style().standardIcon(
QStyle.SP_MessageBoxInformation, None, self)
iconSize = self.style().pixelMetric(
QStyle.PM_MessageBoxIconSize, None, self)
self.iconLabel = QLabel(pixmap=icon.pixmap(iconSize, iconSize))
layout.addWidget(self.iconLabel, 0, 0,
alignment=Qt.AlignLeft|Qt.AlignTop)
self.scroll = QScrollArea()
layout.addWidget(self.scroll, 0, 1)
# ...
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok)
layout.addWidget(self.buttonBox,
layout.rowCount(), 0, 1, layout.columnCount())
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.reject)
def accept(self):
dbaccess.deleteRCs(self.x)
super().accept()
QMessageBox的图标列在QStyle的StandardPixmap
枚举中。
其他重要说明:
- 您不应该对按钮使用字符串匹配,特别是如果名称是由库设置的:"OK";在其他系统中可以是不同的字符串(例如,在我的计算机上,"k"是小写的(
- 即使您部分使用本地
dlts
,实际上您总是在更新self.x
,这使得拥有两个字典并将它们发送到连接函数是毫无意义的 - 每当释放按钮时都会发出
released
信号,这也可能发生在用户按下按钮上的鼠标并在按住鼠标的同时将鼠标移动到外部时;改为使用clicked
isChecked
是一个函数,您应该使用if dlt.isChecked():
,或者更好的dlts[dlt.objectName()] = dlt.isChecked()
,而不是每次在实际检查之前都将其设置为False
stateChanged
用于可部分检查的三态复选框;如果您只需要一个布尔值,请使用toggled
- 对于直接(不像线程中那样排队(连接到行为已知且特定于这些信号发送器的函数的基本信号,可以使用
self.sender()
而不是部分;通过这种方式,您还可以直接使用信号参数,而不是查询属性;如果您对参数不感兴趣,请在函数签名中忽略它;不过,始终要小心使用sender()
# ...
self.dlts = {}
for rc in dbaccess.allRC():
dlt = QCheckBox('delete', self)
dlt.toggled.connect(self.btnstateDel)
dlt.setObjectName(rc[9])
qb = QPushButton(rc[9], self)
qb.clicked.connect(self.button_releasedRC)
lay.addWidget(qb)
lay.addWidget(dlt)
def btnstateDel(self, checked):
self.dlts[self.sender().objectName()] = checked
def button_releasedRC(self):
nameshow = self.sender()
# ...