Reputation: 21
I am trying to create a UI for a text game.
This works fine, however I wanted to create my own simple print function to print to the parts of the UI (in the example the QLabel) this works, if the function is in the UI file but when I move the functions to another file, I get
"AttributeError: type object 'Window' has no attribute 'label'"
even though my IDE says Window.label exists before running it.
Is this some quirk or QT? or am I making a mistake?
UI.py
import sys
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class Window(QWidget):
def __init__(self):
super().__init__()
self.show()
import game
self.label = QLabel("Text")
self.label.setAlignment(Qt.AlignCenter | Qt.AlignTop)
self.output = QTextEdit()
self.output.setReadOnly(True)
grid = QGridLayout()
grid.setSpacing(10)
grid.addWidget(self.label,0,0,1,10)
grid.addWidget(self.output,1,0,10,10)
self.setLayout(grid)
game.Game.test()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Window()
sys.exit(app.exec_())
Game.py
from UI import Window
class Game():
def print_UI(self,*Args, **Kwargs):
Window.setup.output.insertPlainText(*Args, **Kwargs)
def print_label(self,*Args, **Kwargs):
Window.label.setText(*Args, **Kwargs)
def test():
Game.print_label("HI")
Upvotes: 0
Views: 4094
Reputation: 499
You can pass window object as a parameter to the constructor of Game instead of importing game in Window class and importing Window again in game as that was leaving the label member uninitialized
UI.py
import sys
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import game
class Window(QWidget):
def __init__(self):
super().__init__()
self.show()
self.label = QLabel("Text")
self.label.setAlignment(Qt.AlignCenter | Qt.AlignTop)
self.output = QTextEdit()
self.output.setReadOnly(True)
grid = QGridLayout()
grid.setSpacing(10)
grid.addWidget(self.label,0,0,1,10)
grid.addWidget(self.output,1,0,10,10)
self.setLayout(grid)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Window()
game.Game(ex).test()
sys.exit(app.exec_())
game.py
class Game():
def __init__(self,window):
self.Window = window
def print_UI(self,*Args, **Kwargs):
self.Window.setup.output.insertPlainText(*Args, **Kwargs)
def print_label(self,*Args, **Kwargs):
self.Window.label.setText(*Args, **Kwargs)
def test(self):
self.print_label("HI")
Upvotes: 2
Reputation: 2061
I believe the issue is that you're trying to do object-oriented programming, but not actually doing object-oriented programming. For instance, you're trying to use your Window
class within Game.py
's Game
class by just importing it and calling its functions. Instead, what you've got to do is use inheritance. Namely, your Game.py
's Game
class should inherit from your UI.py
's Window
class.
Change your Game.py
to the following:
from UI import Window
class Game(Window): # Game is inheriting from Window
def __init__(self):
Window.__init__(self) # Game is inheriting Window class attributes & functions
def print_UI(self,*Args, **Kwargs):
self.setup.output.insertPlainText(*Args, **Kwargs) # self refers to Game as well as Window class
def print_label(self,*Args, **Kwargs):
self.label.setText(*Args, **Kwargs) # self refers to Game as well as Window class
def test():
Game.print_label("HI")
Instead of using Window.__init__(self)
, you can check out an explanation of the super()
function.
Upvotes: 0