Return 在 QDialog-PyQt5 上单击按钮 ID 而不是(接受、拒绝标志)
Return clicked button id instead of (accept, reject flags) on QDialog- PyQt5
总结:
我一直在我的应用程序中使用 QMessageBox(为此要求在关闭前保存项目、错误消息),现在我想要自定义样式(自定义标题栏、自定义按钮等),我发现用 QMessageBox 很难做到这一点,而且由于我也在我的应用程序中使用 QDialog(为此目的:从用户那里获取输入),我决定使用自定义 QDialog(在上面制作我自己的样式) 而不是 QMessageBox 用于这些所有先前的目的,因为它更容易自定义和创建我的样式。
问题:
我现在遇到的问题是:QDialog return 只有一个标志值 (0,1),具体取决于按钮角色 如果我只有 2 个按钮也没关系,但这里我有 3 个(保存,取消,关闭),保存将 return 1,关闭和取消都将 return 0。正如我所见,QMessageBox return 被点击的按钮的 ID。
一个例子(希望评论很好 :D):
from PyQt5.QtWidgets import *
class CustomDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Data will be lost")
label = QLabel("Are you sure you want close the app before saving?")
buttonBox = QDialogButtonBox()
buttonBox.addButton(QDialogButtonBox.Save)
buttonBox.addButton(QDialogButtonBox.Cancel)
buttonBox.addButton(QDialogButtonBox.Close)
layout = QVBoxLayout()
layout.addWidget(label)
layout.addWidget(buttonBox)
self.resize(300, 100)
self.setLayout(layout)
# These two lines, return 0 or 1.
buttonBox.rejected.connect(self.reject)
buttonBox.accepted.connect(self.accept)
class Window(QWidget):
def __init__(self):
super().__init__()
label = QLabel('Hello Dialog', self)
open_dialog_button = QPushButton('Open Dialog', self)
open_dialog_button.clicked.connect(self.showDialog)
open_message_box_button = QPushButton('Open Message Box', self)
open_message_box_button.clicked.connect(self.show_message_box)
layout = QVBoxLayout()
layout.addWidget(label)
layout.addWidget(open_dialog_button)
layout.addWidget(open_message_box_button)
self.setLayout(layout)
def showDialog(self):
self.dialog = CustomDialog(self)
btn_clicked = self.dialog.exec_() # dialog exec returns 0 or 1 (Save = 1, Close and Cancel returns 0)
# I want something like this.
if btn_clicked == QDialogButtonBox.Save:
print("Close.. After Saving...")
elif btn_clicked == QDialogButtonBox.Close:
print("Close.. Without saving")
else:
print("Cancel.. Don't exit the program")
def show_message_box(self):
msg = QMessageBox()
msg.setIcon(QMessageBox.Warning)
msg.setText("Are you sure you want close the app before saving?")
msg.setStandardButtons(QMessageBox.Close | QMessageBox.Save | QMessageBox.Cancel)
msg.setWindowTitle("Data will be lost")
btn_clicked = msg.exec_()
# Here i can do this.
if btn_clicked == QMessageBox.Save:
print("Close.. After Saving...")
elif btn_clicked == QMessageBox.Close:
print("Close.. Without saving")
else:
print("Cancel.. Don't exit the program")
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
win = Window()
win.resize(200, 200)
win.show()
sys.exit(app.exec_())
我找到了解决方案,它通过使用自定义信号和槽与我一起工作,但仍然不确定它是否好。等待批准,然后我可以将此解决方案标记为已接受。
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class CustomDialog(QDialog):
# Create a signal
signal = pyqtSignal(int)
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Data will be lost")
label = QLabel("Are you sure you want close the app before saving?")
self.buttonBox = QDialogButtonBox()
self.buttonBox.addButton(QDialogButtonBox.Save)
self.buttonBox.addButton(QDialogButtonBox.Cancel)
self.buttonBox.addButton(QDialogButtonBox.Close)
layout = QVBoxLayout()
layout.addWidget(label)
layout.addWidget(self.buttonBox)
self.resize(300, 100)
self.setLayout(layout)
# connect each button with custom slot
self.buttonBox.button(QDialogButtonBox.Save).clicked.connect(lambda: self.customSlot(QDialogButtonBox.Save))
self.buttonBox.button(QDialogButtonBox.Close).clicked.connect(lambda: self.customSlot(QDialogButtonBox.Close))
self.buttonBox.button(QDialogButtonBox.Cancel).clicked.connect(lambda: self.customSlot(QDialogButtonBox.Cancel))
# connect signal with buil-in function from QDialog (done())
# This done function will return <int> value and close the dialog.
self.signal.connect(self.done)
def customSlot(self, button_id):
# emit button's id
self.signal.emit(button_id)
class Window(QWidget):
def __init__(self):
super().__init__()
label = QLabel('Hello Dialog', self)
open_dialog_button = QPushButton('Open Dialog', self)
open_dialog_button.clicked.connect(self.showDialog)
layout = QVBoxLayout()
layout.addWidget(label)
layout.addWidget(open_dialog_button)
self.setLayout(layout)
def showDialog(self):
dialog = CustomDialog()
btn_clicked = dialog.exec_() # dialog exec returns button's id
# Now you can use the following lines of code
if btn_clicked == QDialogButtonBox.Save:
print("Close.. After Saving...")
elif btn_clicked == QDialogButtonBox.Close:
print("Close.. Without saving")
else:
print("Cancel.. Don't exit the program")
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
win = Window()
win.resize(200, 200)
win.show()
sys.exit(app.exec_())
总结:
我一直在我的应用程序中使用 QMessageBox(为此要求在关闭前保存项目、错误消息),现在我想要自定义样式(自定义标题栏、自定义按钮等),我发现用 QMessageBox 很难做到这一点,而且由于我也在我的应用程序中使用 QDialog(为此目的:从用户那里获取输入),我决定使用自定义 QDialog(在上面制作我自己的样式) 而不是 QMessageBox 用于这些所有先前的目的,因为它更容易自定义和创建我的样式。
问题:
我现在遇到的问题是:QDialog return 只有一个标志值 (0,1),具体取决于按钮角色 如果我只有 2 个按钮也没关系,但这里我有 3 个(保存,取消,关闭),保存将 return 1,关闭和取消都将 return 0。正如我所见,QMessageBox return 被点击的按钮的 ID。
一个例子(希望评论很好 :D):
from PyQt5.QtWidgets import *
class CustomDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Data will be lost")
label = QLabel("Are you sure you want close the app before saving?")
buttonBox = QDialogButtonBox()
buttonBox.addButton(QDialogButtonBox.Save)
buttonBox.addButton(QDialogButtonBox.Cancel)
buttonBox.addButton(QDialogButtonBox.Close)
layout = QVBoxLayout()
layout.addWidget(label)
layout.addWidget(buttonBox)
self.resize(300, 100)
self.setLayout(layout)
# These two lines, return 0 or 1.
buttonBox.rejected.connect(self.reject)
buttonBox.accepted.connect(self.accept)
class Window(QWidget):
def __init__(self):
super().__init__()
label = QLabel('Hello Dialog', self)
open_dialog_button = QPushButton('Open Dialog', self)
open_dialog_button.clicked.connect(self.showDialog)
open_message_box_button = QPushButton('Open Message Box', self)
open_message_box_button.clicked.connect(self.show_message_box)
layout = QVBoxLayout()
layout.addWidget(label)
layout.addWidget(open_dialog_button)
layout.addWidget(open_message_box_button)
self.setLayout(layout)
def showDialog(self):
self.dialog = CustomDialog(self)
btn_clicked = self.dialog.exec_() # dialog exec returns 0 or 1 (Save = 1, Close and Cancel returns 0)
# I want something like this.
if btn_clicked == QDialogButtonBox.Save:
print("Close.. After Saving...")
elif btn_clicked == QDialogButtonBox.Close:
print("Close.. Without saving")
else:
print("Cancel.. Don't exit the program")
def show_message_box(self):
msg = QMessageBox()
msg.setIcon(QMessageBox.Warning)
msg.setText("Are you sure you want close the app before saving?")
msg.setStandardButtons(QMessageBox.Close | QMessageBox.Save | QMessageBox.Cancel)
msg.setWindowTitle("Data will be lost")
btn_clicked = msg.exec_()
# Here i can do this.
if btn_clicked == QMessageBox.Save:
print("Close.. After Saving...")
elif btn_clicked == QMessageBox.Close:
print("Close.. Without saving")
else:
print("Cancel.. Don't exit the program")
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
win = Window()
win.resize(200, 200)
win.show()
sys.exit(app.exec_())
我找到了解决方案,它通过使用自定义信号和槽与我一起工作,但仍然不确定它是否好。等待批准,然后我可以将此解决方案标记为已接受。
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class CustomDialog(QDialog):
# Create a signal
signal = pyqtSignal(int)
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Data will be lost")
label = QLabel("Are you sure you want close the app before saving?")
self.buttonBox = QDialogButtonBox()
self.buttonBox.addButton(QDialogButtonBox.Save)
self.buttonBox.addButton(QDialogButtonBox.Cancel)
self.buttonBox.addButton(QDialogButtonBox.Close)
layout = QVBoxLayout()
layout.addWidget(label)
layout.addWidget(self.buttonBox)
self.resize(300, 100)
self.setLayout(layout)
# connect each button with custom slot
self.buttonBox.button(QDialogButtonBox.Save).clicked.connect(lambda: self.customSlot(QDialogButtonBox.Save))
self.buttonBox.button(QDialogButtonBox.Close).clicked.connect(lambda: self.customSlot(QDialogButtonBox.Close))
self.buttonBox.button(QDialogButtonBox.Cancel).clicked.connect(lambda: self.customSlot(QDialogButtonBox.Cancel))
# connect signal with buil-in function from QDialog (done())
# This done function will return <int> value and close the dialog.
self.signal.connect(self.done)
def customSlot(self, button_id):
# emit button's id
self.signal.emit(button_id)
class Window(QWidget):
def __init__(self):
super().__init__()
label = QLabel('Hello Dialog', self)
open_dialog_button = QPushButton('Open Dialog', self)
open_dialog_button.clicked.connect(self.showDialog)
layout = QVBoxLayout()
layout.addWidget(label)
layout.addWidget(open_dialog_button)
self.setLayout(layout)
def showDialog(self):
dialog = CustomDialog()
btn_clicked = dialog.exec_() # dialog exec returns button's id
# Now you can use the following lines of code
if btn_clicked == QDialogButtonBox.Save:
print("Close.. After Saving...")
elif btn_clicked == QDialogButtonBox.Close:
print("Close.. Without saving")
else:
print("Cancel.. Don't exit the program")
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
win = Window()
win.resize(200, 200)
win.show()
sys.exit(app.exec_())