Issue
I made a minimum working environment for this question.
First I have this UI file (GDrive Link),which I'll later load in my UI.py., which I'll later load in my
The UI.py goes thus:
import sys
from PyQt6.QtWidgets import QMainWindow, QApplication, QPlainTextEdit
from PyQt6 import uic
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.ui = uic.loadUi(r"C:\Documents\Qt Designer\mwe.ui") # Change it to yoour own .ui
self.txtBox = self.findChild(QPlainTextEdit, 'plainTextEdit')
self.ui.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
import main
sys.exit(app.exec())
Essentially, what I want to do is to access this PlainTextEditor in main.py, becuase that's where I'll write the functions.
import UI
UI.Window.txtBox.insertPlainText('foo')
But when I try to run UI.py, I get this error:
Traceback (most recent call last):
File "C:\Users\Me\PycharmProjects\dynamic_ui_foo\UI.py", line 18, in <module>
import main
File "C:\Users\Me\PycharmProjects\dynamic_ui_foo\main.py", line 3, in <module>
UI.Window.txtBox.insertPlainText('foo')
AttributeError: type object 'Window' has no attribute 'txtBox'
It says Window doesn't have this attribute. How do I access the components from another module? And am I going in the right way by separating UI codes and function codes (I know the cross-importing looks terrible).
Solution
To illustrate your error message, consider the following example:
class bla:
def __init__(self):
self.foo = 'test'
print(bla.foo) # <-- results in your error
b = bla()
print(b.foo) # <-- this is what you would like to access
Right now you are trying to access txtBox of the class Window
, but you need to access txtBox from your instance window
.
However, I have doubts about it working in the way you do your imports. I would suggest to move
if __name__ == "__main__":
app = QApplication(sys.argv)
window = UI.Window()
sys.exit(app.exec())
to main.py. Use UI.py to only define the layout. Changing the text txtBox
can be implemented either as a method of Window
:
class Window(QMainWindow):
# init code
def change_content(self, content):
self.txtBox.insertPlainText(content)
Then in main you call that:
if __name__ == "__main__":
app = QApplication(sys.argv)
window = UI.Window()
window.change_content()
sys.exit(app.exec())
Of course you can use a more direct approach:
if __name__ == "__main__":
app = QApplication(sys.argv)
window = UI.Window()
window.txtBox.insertPlainText(content)
sys.exit(app.exec())
The last example seems to be easier. But that way, if you change txtBox to something else you need to keep in mind to also do changes in main.py
. With the first example you only have to do changes in UI.py
.
Edit:
Added missing argument self
. Thanks to musicamante for pointing that out.
Answered By - Flow
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.