【问题标题】:QMessageBox add custom button and keep openQMessageBox 添加自定义按钮并保持打开状态
【发布时间】:2019-07-02 15:54:10
【问题描述】:

我想向 QMessagebox 添加一个自定义按钮,该按钮打开一个 matplotlib 窗口,以及一个 Ok 按钮供用户在想要关闭它时单击

我目前有一些工作,但我希望这两个按钮做单独的事情而不是打开窗口。

我知道我可以创建一个包含所需结果的对话框窗口,但我想知道如何使用 QMessageBox。

import sys
from PyQt5 import QtCore, QtWidgets

def main():
    app = QtWidgets.QApplication(sys.argv)
    msgbox = QtWidgets.QMessageBox()
    msgbox.setWindowTitle("Information")
    msgbox.setText('Test')
    msgbox.addButton(QtWidgets.QMessageBox.Ok)
    msgbox.addButton('View Graphs', QtWidgets.QMessageBox.YesRole)

    bttn = msgbox.exec_()

    if bttn:
        print("Ok")
    else:
        print("View Graphs")
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

想要的结果:

确定按钮 - 关闭 QMessageBox

查看图形按钮 - 打开 matplotlib 窗口并保持 QMessageBox 处于打开状态,直到用户单击确定

【问题讨论】:

    标签: python python-3.x pyqt pyqt5 qmessagebox


    【解决方案1】:

    IMO 有点老套,但添加 View Graphs 按钮后,您可以断开其 clicked 信号并将其重新连接到您选择的插槽,例如

    import sys
    from PyQt5 import QtCore, QtWidgets
    
    def show_graph():
        print('Show Graph')
    
    def main():
        app = QtWidgets.QApplication(sys.argv)
        msgbox = QtWidgets.QMessageBox()
        msgbox.setWindowTitle("Information")
        msgbox.setText('Test')
        msgbox.addButton(QtWidgets.QMessageBox.Ok)
    
        yes_button = msgbox.addButton('View Graphs', QtWidgets.QMessageBox.YesRole)
        yes_button.clicked.disconnect()
        yes_button.clicked.connect(show_graph)
    
        bttn = msgbox.exec_()
    
        if bttn:
            print("Ok")
        sys.exit(app.exec_())
    
    if __name__ == "__main__":
        main()
    

    【讨论】:

      【解决方案2】:

      QMessageBox 和所有 QDialogs 一样,会阻塞所有内容,直到返回 exec_(),但它也会自动将所有按钮连接到接受/拒绝信号,在任何情况下都返回 exec_()

      您的代码可能的解决方案是:

      app = QtWidgets.QApplication(sys.argv)
      msgbox = QtWidgets.QMessageBox()
      # the following is if you need to interact with the other window
      msgbox.setWindowModality(QtCore.Qt.NonModal)
      msgbox.addButton(msgbox.Ok)
      viewGraphButton = msgbox.addButton('View Graphs', msgbox.ActionRole)
      # disconnect the clicked signal from the slots QMessageBox automatically sets
      viewGraphButton.clicked.disconnect()
      
      # this is just an example, replace with your matplotlib widget/window
      graphWidget = QtWidgets.QWidget()
      
      viewGraphButton.clicked.connect(graphWidget.show)
      msgbox.button(msgbox.Ok).clicked.connect(graphWidget.close)
      # do not use msgbox.exec_() or it will reset the window modality
      msgbox.show()
      sys.exit(app.exec_())
      

      也就是说,在sys.exit(app.exec_()) 调用之外(如“之前”)使用QDialog.exec_() 时要小心,因为如果您不知道自己在做什么,它可能会导致意外行为。

      【讨论】:

      • 有没有办法将 QMessageBox 推回来?当我打开图形窗口时,QMessageBox 总是在顶部,在我关闭它之前不会让我点击图形窗口
      • 这很奇怪,在我的测试(Linux 和 Wine)中,使用简单的 QWidget,也可以与其他小部件进行交互。在 Windows 或 MacOS 上,窗口可能保持模态,但如代码中所示设置模态应该可以防止这种情况。您是否在没有任何父母的情况下离开了消息框,并且您确定您使用的是 show() 而不是 exec_()
      【解决方案3】:

      好吧,首先你不要在 QtCore 中使用任何东西,所以不需要导入它。这应该可以帮助您了解您需要做什么。我稍微调整了一下,我不得不添加 2 个 sys.exits,或者当你按下 View Graphs 时,由于你当前的设置方式,程序刚刚挂起。如果您不选择调整此代码流,则将 sys.exit 从 if/else 中拉出,并将其放在 if/else 之后——没有必要的冗余代码没有意义

      from sys import exit as sysExit
      
      from PyQt5.QtWidgets import QApplication, QMessageBox
      
      def Main():
          msgbox = QMessageBox()
          msgbox.setWindowTitle("Information")
          msgbox.setText('Test')
          msgbox.addButton(QMessageBox.Ok)
          msgbox.addButton('View Graphs', QMessageBox.YesRole)
      
          bttn = msgbox.exec_()
      
          if bttn == QMessageBox.Ok:
              print("Ok")
              sysExit()
          else:
              print("View Graphs")
              sysExit()
      
      if __name__ == "__main__":
          MainThred = QApplication([])
      
          MainApp = Main()
      
          sysExit(MainThred.exec_())
      

      也就是你的非冗余 if/else 如下所示

          if bttn == QMessageBox.Ok:
              print("Ok")
          else:
              print("View Graphs")
      
          sysExit()
      

      【讨论】:

      • 当您点击“查看图表”按钮时,QMessageBox 仍然关闭
      猜你喜欢
      • 1970-01-01
      • 2011-05-19
      • 1970-01-01
      • 2020-10-26
      • 2011-07-28
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多