Unable to acesse QWidget in UI file, PySide - python

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

get button text using sender() always return error — 'NoneType' object has no attribute 'text'

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_()

Pyside2 second window(QDialog) closes the main one

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

Access data from the parent window in a child window in PyQt

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

Attribute Error: module attribute not found in defined class

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?

PyQt: Trying to display SQLite DB in QTableView: 'argument 1 has unexpected type 'PyQt4.QtCore.pyqtWrapperType'

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?

Categories