1 回答

TA貢獻1943條經驗 獲得超7個贊
第二個示例不起作用,因為您試圖重寫該event方法,該方法僅適用于 QWidget 子類,而您Ui_MainWindow是一個簡單的 pythonobject子類,因此永遠不會調用它。
該event()方法由 Qt 在任何 QWidget 上調用,并且由于您在第一個示例中重寫了它,因此實際上調用了您的方法。在第二個示例中,您沒有重寫 QWidget event,但您只是創建了一個永遠不會被任何東西調用的函數。
理論上,您可以覆蓋對象event的方法(這就是所謂的“猴子修補”):MainWindowsetupUi
def setupUi(self, MainWindow):
# ...
MainWindow.event = self.event
但這是行不通的,因為self您在該函數中引用的實際上是實例Ui_MainWindow,而不是實際的 QMainWindow 實例。雖然您可以使用 lambda,并使用 MainWindow 實例添加參數,但我強烈建議您不要這樣做,下面的解釋將闡明為什么您不應該這樣做。
出于簡單的原因,做您想要實現的目標是沒有意義的:修改或嘗試模仿“pyuic”生成的文件的行為是**永遠**不應該做的事情。
不鼓勵編輯主要是因為每當您需要從設計器更改 UI 中的某些內容時,您最終都會嘗試將新生成的代碼(希望您同時沒有覆蓋該文件)與現有代碼集成,這將導致通常會導致大量錯誤、問題、崩潰和頭痛。
不鼓勵編輯或模仿,因為這使得實現簡單的類操作或覆蓋現有方法變得非常困難。另外,雖然我可以理解您有興趣研究它是如何工作的,但除了閱讀如何在 中創建界面之外setupUi,沒有什么可以學習的了。pyuic 文件僅用作“實用層”,以簡化 PyQt 中的編程,它們應始終僅按照有關使用 Designer 的官方指南中的建議進行導入和使用。
如果您想實現第一個示例的事件,您需要使用您自己的子類并使用上面鏈接中建議的方法之一。最常見且易于使用的是多重繼承方法:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QLineEdit, QFormLayout
from PyQt5.QtCore import Qt, QEvent
from ui_mainwindow import Ui_MainWindow
class Working(QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
def event(self, event):
if event.type() == QEvent.KeyPress:
if event.key() in (Qt.Key_Return, Qt.Key_Enter):
self.focusNextPrevChild(True)
return super().event(event)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
mainWindow = Working()
mainWindow.show()
sys.exit(app.exec_())
注意:我假設您已使用再次生成pyuic了該文件,并且該文件名為ui_mainwindow.py; 另請注意,如果您在設計器中使用 QMainWindow,則必須從同一類(QMainWindow,而不是 QWidget)繼承子類;最后,由于您已經從 QMainWindow和Ui_MainWindow 進行子類化,因此您必須創建 的實例Working,而不是 QMainWindow 之一,也不是 Ui_MainWindow 之一。
另一種可能性是使用該uic模塊,它允許直接導入.ui文件,而無需每次都重建整個界面。
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QLineEdit, QFormLayout
from PyQt5.QtCore import Qt, QEvent
from PyQt5.uic import loadUi
class Working(QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
loadUi('mainWindow.ui', self)
# ...
添加回答
舉報