I'm using PyQt4 using Qt designer. This is the first time I've used it so I'm just getting my head round a few things but this has me stumped.
The problem I'm having is that once the UI window has been defined and created, I try to call a function to update a UI element and it produces a "not defined" error.
However, if I place the same code in the block of code where the element is initially defined, it works fine.
I have written an example below to show what I mean more clearly.
The problem is I need to call to update the lcd number from a different module which contains a function that is called when a button is clicked.
To show this, I've made a form with an lcdnumber (lcd1) and a pushbutton (button1) in qtdesigner, compiled the code in the file "testui.py", which creates the class "MainWindow".
In a.py, I have put:
import testui as interface
import sys
import b
from PyQt4 import QtCore, QtGui
ui= interface.Ui_MainWindow()
def updateui():
for i in range(0, 100):
ui.lcd1.setProperty("value", i)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
test = QtGui.QMainWindow()
ui.setupUi(test)
ui.lcd1.setProperty("value", 1)
ui.button1.clicked.connect(b.updatelcd)
test.show()
app.exec_()
This opens the window, and sets the initial state and connects the button to a function in b.py.
In b.py, I have put:
from a import updateui
def updatelcd():
updateui()
When I click the button this calls the function in a.py, which leads to the error:
"Module has no attribute lcd1"
This has been confusing me for a while because ui.lcd1.setProperty works in the main loop!
It must be something fundamentally wrong with what I'm doing but I can't work it out.
Any ideas appreciated
Thanks
You are doing kind of circular imports which is by itself not a very good idea.
What happens here is:
When you import a's updateui
the ui variable is not imported to be.
The ui variable may be gloabal, but only in your a module.
So when you call the function updatelcd
in b
which calls updateui
that was imported from a
you get a NameError
for lcd1
because ui was not initialized.
Actually I am not that sure why it does not complain about ui in the first place. It might be that python imported the knowledge that there was a global variable ui defined in a.
Instead of just importing the function 'updateuifrom
ain
band including
bin
a` you should think about how you could achieve your goal without circular imports.
You should think about not only having modules but also classes. Make it object oriented.
So what you could do:
1. Create a class in your b-module which does everything the way your module does now.
2. Make a constructor that takes the interface.Ui_MainWindow()
as an argument and stores it.
3. On this you will then tater be able to do your updatelcd(without going to any methods defined in a)
4. Create an instance of your b-class in your a-module. On this instance you can call your function that updates the lcd.
This is what code for your b-class could look like
class B:
__init__(self, mainWindow):
self.mainWindow = mainWindow
def updatelcd(self):
for i in range(0, 100):
self.mainWindow.lcd1.setProperty("value", i)
So module a will look something like this:
import testui as interface
import sys
import b
from PyQt4 import QtCore, QtGui
ui= interface.Ui_MainWindow()
thing = b.B(ui)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
test = QtGui.QMainWindow()
ui.setupUi(test)
ui.lcd1.setProperty("value", 1)
ui.button1.clicked.connect(thing.updatelcd())
test.show()
app.exec_()