AttributeError: 'PySide.QtGui.QWidget' object has no attribute 'test_button'
I get this error when run the following code
test.py.
from PySide import QtGui, QtCore, QtUiTools
module_dir = os.path.dirname('__file__')
ui_file_path = module_dir + '/test.ui'
def call_ui():
loader = QtUiTools.QUiLoader()
ui_file = QtCore.QFile(ui_file_path)
ui_file.open(QtCore.QFile.ReadOnly)
ui = loader.load(ui_file)
ui_file.close()
return ui
class TestUI(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.ui = call_ui()
self.setCentralWidget(self.ui)
self.ui.test_button.clicked.connected(self.test)
def test(self):
print "Testing....."
def main():
app = QtGui.QApplication(sys.argv)
win = TestUI()
win.show()
main()
test.ui file has a push button called test_button
You can't construct path of UI file in this way:
os.path.dirname('__file__')
will always return empty string, and ui_file_path will be '/test.ui'.
Correct way:
module_dir = os.path.dirname(__file__)
ui_file_path = os.path.join(module_dir, 'test.ui')
But when QUiLoader.load failed, it raises RuntimeError (tested on PySide 1.2.1). Is there a ui file on your root file system?
Related
Using Qt Designer created a Push Button, then code:
# import ...
class Test:
def __init__(self):
qfile = QFile("test.ui")
qfile.open(QFile.ReadOnly)
qfile.close()
self.ui = QUiLoader().load(qfile)
self.ui.pushButton.clicked.connect(self.buttonClicked)
def buttonClicked(self):
print(self.ui.sender().text())
app = QApplication([])
test = Test()
test.ui.show()
app.exec_()
When I clicked the button, getting error message:
AttributeError: 'NoneType' object has no attribute 'text'
How can I get the button text?
The sender() method returns the object that emitted the signal if where it is invoked is a method that is called asynchronously, also only the sender() of the class to which the method belongs will be valid.
Considering the above, the Test class must be a QObject, and its sender() method must be invoked:
import os
from PySide2 import QtCore, QtWidgets, QtUiTools
CURRENT_DIRECTORY = os.path.dirname(os.path.realpath(__file__))
class Test(QtCore.QObject):
def __init__(self):
super().__init__()
filename = os.path.join(CURRENT_DIRECTORY, "test.ui")
qfile = QtCore.QFile(filename)
qfile.open(QtCore.QFile.ReadOnly)
qfile.close()
self.ui = QtUiTools.QUiLoader().load(qfile)
self.ui.pushButton.clicked.connect(self.buttonClicked)
#QtCore.Slot()
def buttonClicked(self):
print(self.sender().text())
if __name__ == "__main__":
app = QtWidgets.QApplication([])
test = Test()
test.ui.show()
app.exec_()
import sys
from PySide2.QtCore import QFile
from PySide2.QtWidgets import QApplication, QMainWindow
from PySide2.QtUiTools import QUiLoader
class MyMainWindow(QMainWindow):
def __init__(self):
super().__init__()
loader = QUiLoader()
self.ui = loader.load("mainWindow.ui", self)
self.ui.pushButton_call_dialog.clicked.connect(self.call_dialog)
self.ui.close()
self.ui.show()
def call_dialog(self):
loader = QUiLoader()
self.dialog = loader.load("dialog.ui")
self.dialog.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyMainWindow()
window.show
sys.exit(app.exec_())
Hi everyone,
any idea why the second (dialog) window closes the entire application?
Of course, it is not a crash since i'm getting a message saying:
Process finished with exit code 0
Thanks for your help
You could handle your QDialog on a separate class, and then make them interact only, the structure might change a bit, but you can see if it's a viable answer:
import sys
from PySide2.QtWidgets import *
class MyWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
button = QPushButton("Dialog")
button.clicked.connect(self.open_dialog)
self.setCentralWidget(button)
def open_dialog(self):
dialog = MyDialog()
dialog.show()
dialog.exec_()
class MyDialog(QDialog):
def __init__(self):
QDialog.__init__(self)
button = QPushButton("Close")
button.clicked.connect(self.close_dialog)
layout = QHBoxLayout()
layout.addWidget(button)
self.setLayout(layout)
def close_dialog(self):
self.close()
if __name__ == "__main__":
app = QApplication()
m = MyWindow()
m.show()
sys.exit(app.exec_())
Just notice that you should include the setUp step on each class.
Hope it helps.
To put the dialog into a separate class didn't work for either.
Every time the Dialog.close() event was called, it closes the whole application.
What worked for me, was to use hide() instead
I have two windows (App.py and ChildApp.py) and .ui files for both with same name.
App.py:
import sys
from PyQt4 import QtCore, QtGui, uic
from ChildApp import ChildApp
qtCreatorFile = "App.ui" # Enter file here.
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
class App(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
self.message = None
self.child_window = ChildApp()
self.pushButton.clicked.connect(self.sendMessage)
def sendMessage(self):
self.message = self.lineEdit.text()
self.child_window.show()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = App()
window.show()
sys.exit(app.exec_())
ChildApp.py:
import sys
from PyQt4 import QtCore, QtGui, uic
qtCreatorFile = "ChildApp.ui" # Enter file here.
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
class ChildApp(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
self.pushButton.clicked.connect(self.alertmessage)
def alertmessage(self):
message = "test"
self.label.setText("Message : "+message)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = ChildApp()
window.show()
sys.exit(app.exec_())
In Main.py file I have a variable self.message.
When I click on the button "Do something with text", text in the textbox is assigned to self.message and the child window is opened.
Now in the child window, when I click on button "Show message", the method alertmessage() is called, where it sets message = "text".
This variable message must be assigned to value of self.message from MainApp.py.
Please help
Thank you
Call the child that way:
self.child_window = ChildApp(parent=self)
Define the child app this way:
class ChildApp(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self, parent):
self.parent = parent
you can use the parent variables through self.parent.whatever
It must work, but I wouldn't advise this because you are not supposed to know the fields of the parent form the child.
I don't think you can get local data from the parent. I would do the following:
Use a signal to update the child when the text is changed in the lineEdit:
self.lineEdit.textChanged.connect(self.updateChild)
Add this function in the main window:
def updateChild(self):
self.child_window.setMessage(self.lineEdit.text())
and keep the variable self._message updated in the child window:
def setMessage(self, message):
self._message=message
so that whenever you need this variable, it is up to date
I am trying to make simple Gui using pyqt and qtdesigner in Anaconda python 2.7.
I am calling a method from inside __init__ function. It returns attribute not found error.
Here is my code:
import sys, os
from PyQt5 import QtCore, QtGui, uic, QtWidgets
from awesim.pymosim import set_pars
dir_path = os.path.dirname(os.path.realpath(__file__))
qtCreatorFile = os.path.join(dir_path , 'SimpleDymolaRun.ui' )
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
class MyApp(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent = None, name = None):
QtWidgets.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
self.updateParameters.clicked.connect(self.Update)
def Update(self):
dir_path = os.path.dirname(os.path.realpath(__file__))
dsin = os.path.join(dir_path, 'dsin.txt')
value_dict = {'a':1, 'b':2}
set_pars(value_dict, dsin = os.path.join(dir_path, dsin.txt))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
I get following error:-
Traceback:
window = Myapp()
in __init__
self.updateParameters.clicked.connect(self.Update)
AttributeError : 'MyApp' object has no attribute 'Update'
Am I missing something crucial in definition of init. I tried suggestions in some other answers on SO, but solution mentioned therein did not work for me.
What is it that I am doing wrong?
Ok, I fixed it, make sure to call the class with Model()
However, the below code does not work, and results in segfault for some reason. I fixed it by putting the DB and model stuff directly into the main GUI class.
I have a Ui element called table, and following code:
import sqlite3
from PyQt4 import QtCore
from PyQt4 import QtGui
from PyQt4 import QtSql
from PyQt4.Qt import *
from ui.mainWindow import *
class Database(QtSql.QSqlDatabase) :
def __init__(self, parent = None):
super(Database, self).__init__(parent)
self.addDatabase("QSQLITE")
self.setDatabaseName('/db/daily.sql')
self.open()
class Model(QtSql.QSqlTableModel):
def __init__(self, parent = None, db=Database()):
super(Model, self).__init__(parent)
self.setTable('body')
self.select()
class Gui(QtGui.QMainWindow):
def __init__(self, parent = None):
QtGui.QWidget.__init__(self,parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.tableModel = Model()
self.ui.table.setModel(self.tableModel)
self.ui.table.show()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = Gui()
myapp.show()
sys.exit(app.exec_())
And get the following error:
TypeError: QTableView.setModel(QAbstractItemModel): argument 1 has unexpected type 'PyQt4.QtCore.pyqtWrapperType'
If I set up the Database and Model directly in the Gui class, the program starts, but the table is empty (DB is populated).
What causes this error?