我想在messagebox不關閉整個應用程式的情況下通過按鈕點擊觸發,我在之前的專案中設法做到了這一點,但這一次,行為真的出乎意料。一旦我點擊ok或 上的十字符號messagebox,應用程式也會關閉,沒有任何錯誤。這是最小的例子
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.set_and_load_ui()
def set_and_load_ui(self):
self.ui = QUiLoader().load('main.ui', self)
def trigger_messagebox(self):
self.messagebox()
def messagebox(self,x=""):
msg = QMessageBox(self)
msg.setIcon(QMessageBox.Information)
msg.setText("{}".format(x))
msg.setInformativeText("test")
msg.setWindowTitle("test")
msg.exec_()
app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.ui.show()
# mainWindow.trigger_messagebox() #this is fine
mainWindow.ui.mainmenuButton.clicked.connect(lambda: mainWindow.trigger_messagebox()) #this is not fine
exit_code = (app.exec_())
只是為了檢查,如果訊息框本身導致了問題,我嘗試直接在我的代碼上呼叫它,但結果很好,但是當我嘗試通過單擊按鈕觸發它時卻沒有
uj5u.com熱心網友回復:
問題與 QUiLoader 使用給定的父級作為引數加載 UI 的事實有關,并且由于 UI 已經是 QMainWindow,因此您實際上是將 QMainWindow 加載到另一個不受支持的 QMainWindow 中:QMainWindows 是非常特殊的 QWidget 型別,并且旨在用作頂級小部件。
我不清楚靜默退出的技術原因,但這肯定與加載的視窗實際上有一個父視窗(MainWindow實體)有關,即使沒有顯示該父視窗(因為您顯示的是ui)。
不幸的是,與 PyQt 不同(通過uic.loadUi函式),PySide 沒有提供將 UI 檔案“安裝”到現有實體的方法,因此如果您想繼續使用 PySide,只有兩個選擇:
不要在 Designer 中使用主視窗,而是使用普通小部件(Designer 的“新表單”對話框中的“小部件”),使用
QUiLoader并使用setCentralWidget()(這是強制性的,因為檔案還指出,“創建一個主視窗”不支持沒有中央小部件的視窗"):self.ui = QUiLoader().load('main.ui', self) self.setCentralWidget(self.ui)這種方法的缺點是您不能再在 Designer 中使用主視窗功能(因此,沒有選單、狀態欄、停靠小部件或工具列)。
使用pyside-uic生成python代碼并使用多重繼承方式“安裝”;以下假設您將 ui 檔案匯出為
mainWindow.py:from mainWindow import ui_mainWindow class MainWindow(QtWidgets.QMainWindow, ui_mainWindow): def __init__(self): super(MainWindow, self).__init__() self.setupUi(self) # no "set_and_load_ui" self.mainmenuButton.clicked.connect(self.trigger_messagebox) # ... app = QtWidgets.QApplication(sys.argv) mainWindow = MainWindow() mainWindow.show() exit_code = (app.exec_())如您所見,現在您可以直接訪問小部件(沒有
ui物件)。這種方法的缺點是你必須記住每次修改相關ui時總是生成python檔案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/340116.html
