[英]Import Modules in PyQt5
我在將帶有 PyQt5 的小部件添加到一個使用不同模塊的 QMainWindow 時遇到了一些問題。 基本上我的 GUI 有許多 windows 和小部件,我認為使用不同的模塊會更有條理。 但是,當我嘗試將一個小部件從一個模塊添加到主模塊時,它給了我一個錯誤,例如我嘗試導入的 class 未定義。
為簡化起見,下面您有一個非常簡單的測試,我嘗試過並得到與我的 GUI 腳本相同的錯誤。 我有兩個模塊,一個我稱為“main_gui_file”,另一個是“widget_file”。
此示例中的 main_gui_file 是我在屏幕中加載的 QMainWindow,我想在 self.grid_01 中添加一個小部件,調用模塊 widget_file 中的 function。
當我運行這個測試時,它給了我 NameError: name 'Add_Widgets' is not defined
下面你有兩個測試模塊
main_gui_file
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
from teste.widget_file import *
class Main_GUI(QMainWindow):
def __init__(self, *args, **kwargs):
super(Main_GUI, self).__init__(*args, **kwargs)
self.setGeometry(0, 0, 500, 500)
self.main_widget = QStackedWidget()
self.setCentralWidget(self.main_widget)
self.widget_01 = QWidget()
self.main_widget.addWidget(self.widget_01)
self.grid_01 = QGridLayout()
self.widget_01.setLayout(self.grid_01)
self.main_widget.setCurrentWidget(self.widget_01)
self.label1 = QLabel('a')
self.label2 = QLabel('b')
self.grid_01.addWidget(self.label1, 0, 0)
self.grid_01.addWidget(self.label2, 1, 0)
self.add_widgets = Add_Widgets()
self.add_widgets.add_widget()
app = QApplication(sys.argv)
window = Main_GUI()
window.show()
app.exec_()
小部件文件
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from teste.main_gui_file import *
class Add_Widgets(QMainWindow):
def __init__(self, *args, **kwargs):
super(Add_Widgets, self).__init__(*args, **kwargs)
self.main_gui = Main_GUI()
def add_widget(self):
self.label3 = QLabel('c')
self.main_gui.grid_01.addWidget(self.label3, 3, 0)
有誰知道為什么我在導入模塊時遇到這個麻煩? 謝謝
您的代碼中最重要的問題是您正在執行循環導入(這通常很糟糕)。
一般而言,這意味着在“發生”某些事情之前,它不會 go 進一步使用代碼。
這就是(幾乎)正在發生的事情:
main_gui_file
已加載,並在某個時刻嘗試從widget_file
導入widget_file
並嘗試從main_gui_file
加載main_gui_file
main_gui_file
處理,但widget_file
會嘗試gowidget_file
導入的main_gui_file
現在正在嘗試完成加載main_gui_file
還嘗試創建 Main_GUI 的實例,這Add_Widgets
Main_GUI
它存在於widget_file
中,但是此時尚未加載它,因為嘗試完成加載仍然占用了導入處理main_gui_file
Add_Widgets
但這還不夠。
甚至還有一個邏輯問題(正如@NaufanRusydaFaikar部分解釋的那樣):您正在嘗試在Add_Widgets
class 中創建Main_GUI
的新實例,這沒有多大意義,因為一個已經存在,而且instance 是您要添加小部件的那個。
此外,出於同樣的原因,如果您想將小部件添加到現有實例,您真的不應該創建新的 QMainWindow,因為您實際上不會使用它。
從您的代碼中,我真的不明白為什么您需要另一個文件來完成所有這些工作(您可能有充分的理由,但您的代碼沒有顯示任何內容),但我同意它建議進行以下修改:
main_gui_file.py:
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
from widget_file import *
class Main_GUI(QMainWindow):
def __init__(self, *args, **kwargs):
# ...
add_widget(self, self.grid_01)
小部件文件.py:
from PyQt5.QtWidgets import *
def add_widget(parent, layout): # <-- note that there's no "self"
parent.label3 = QLabel('c')
layout.addWidget(parent.label3, 3, 0)
如您所見, add_widget
現在是一個“孤兒” function (“孤兒”是指除了它所屬的模塊之外它沒有任何關系,這可以從它沒有縮進和第一個參數的事實中看出不是一個可以與之相關的self
論證)。
從技術上講,您甚至可以通過僅使用 layout 參數調用add_widget
並使用def add_widget(layout):
來執行相同的操作,但這會阻止您將label3
object 設置為主要 window 的屬性。
另一種更好的解決方案(也可以解決之前的邏輯問題)如下:
main_gui_file.py
# ...
class Main_GUI(QMainWindow):
def __init__(self, *args, **kwargs):
# ...
self.label3 = add_widget(self.grid_01)
但只要您在widget_file.py
中返回添加的小部件:
from PyQt5.QtWidgets import *
def add_widget(layout):
label = QLabel('c')
layout.addWidget(label, 3, 0)
return label
請注意,這不是一種非常優雅的做事方式,因為像這樣的單獨導入通常是為“普通”函數(通常為不需要實例參數的普通任務調用的“util”函數)完成的,並且,當處理這些類型的對象時,通常只要導入的對象是要為其創建實例的類,就會這樣做,但這確實是一個完全不同的問題。
首先,確保您的模塊目錄中有文件__init__.py
。 其次,從您的示例中,您嘗試導入放置在同一目錄中的兩個文件。 因此,嘗試導入相對路徑, from teste.widget_file import *
將是from.widget_file import *
和from teste.main_gui_file import *
將是from.main_gui_file import *
。
編輯:
為避免循環導入,我建議將您的代碼更改為
from PyQt5.QtCore import QObject
class Add_Widgets(QObject):
def __init__(self, parent, *args, **kwargs):
super(Add_Widgets, self).__init__(*args, **kwargs)
self.main_gui = parent
...
所以你可以通過創建 Add_Widgets 實例
class Main_GUI(QMainWindow):
def __init__(self, *args, **kwargs):
super(Main_GUI, self).__init__(*args, **kwargs)
...
self.add_widgets = Add_Widgets(self)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.