Can't define Ui_MainWindow in pyqt - python-3.x

When ever I try to compile the following code I get the error:
class MyApp(QtGui.QMainWindow, Ui_MainWindow):
NameError: name 'Ui_MainWindow' is not defined
My code is:
import sys
import clientGUI
from PyQt4 import QtCore, QtGui
class MyApp(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
clientGUI.Ui_MainWindow.__init__(self)
self.setupUi(self)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())

It looks like Ui_MainWindow is defined in clientGUI, so you need to reference it as
class MyApp(QtGui.QMainWindow, clientGUI.Ui_MainWindow):
...
Or you can import it as:
from clientGUI import Ui_MainWindow
and then use this name in code.
See more info about modules in Python 3 tutorial

Related

pyqt5 button click not working from my second window

i am stuck in call function from pushButton.
in my project:
app.py, which is the main file to run the project.
ui_mainWindow.py is the file consist of tab widget.
Account.py is the converted file from account.ui
main_Account.py is the file where i import Account.py file.
account_handler.py is the file where consist of functions.
now when i run my project by running app.py ,it will show all contents of ui_mainWindow.py .now if i choose account tab from tabwidget than it will show all contents of mainAccount.py. now if i hit a button from mainAccount.py than function will be call from account_handler.py.
everything working fine but while i hut pushButton nothin happen.
this is my previous post : PyQt5 push button method called from separate python file ,
i follow this separately and this working fine, but in my project samecode not working. can anyone tell me where i am wrong!
app.py
from importlib import reload
import PyQt5.QtCore as QtCore
from PyQt5.uic import loadUi
from PyQt5.QtWidgets import QMainWindow,QApplication
import sys
import files.interfaces.ui_mainWindow
import files.interfaces.dashboard
reload(files.interfaces.dashboard)
import files.main_Interfaces.mainAccount
reload(files.main_Interfaces.mainAccount)
import files.interfaces.account2
reload(files.interfaces.account2)
class MainWindow(QMainWindow, files.interfaces.ui_mainWindow.Ui_MainWindow):
def __init__(self):
# Base class
QMainWindow.__init__(self)
self.ui = files.interfaces.ui_mainWindow.Ui_MainWindow()
self.ui.setupUi(self)
self.setWindowTitle("PORTFOLIO ACCOUNTING")
# import tab1
self.TabWidget = QtWidgets.QWidget()
ui = files.interfaces.dashboard2.Ui_Form()
ui.setupUi(self.TabWidget)
self.ui.tabWidget.insertTab(0, self.TabWidget, "Dashboard")
# import tab2
self.TabWidget = QtWidgets.QWidget()
ui = files.main_Interfaces.mainAccount.MainWindow()
ui.setupUi(self.TabWidget)
self.ui.tabWidget.insertTab(1, self.TabWidget, "Account")
def main():
app = QtWidgets.QApplication(sys.argv)
app.setApplicationName("Portfolio Accounting")
application = MainWindow()
application.show()
app.exec_()
if __name__ == '__main__':
main()
main_Account.py
from PyQt5 import QtCore, QtGui, QtWidgets
from files.interfaces.account import Ui_Form
from event_handler.account_EventHndler import function2
class MainWindow(QtWidgets.QMainWindow,Ui_Form):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.pushButton_2.clicked.connect(function1)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
account_handler.py
def function1():
print("function called")
You code is a bit confusing since you use the same class names in different modules and there is an inconsistencies between the names of the modules you are importing and the names of the .py files you provided but I'm assuming that files.main_Interfaces.mainAccount.MainWindow refers to mainWindow in main_Account.py. In that case, in app.MainWindow.__init__ tab2 should probably be something like
# import tab2
self.TabWidget = files.main_Interfaces.mainAccount.MainWindow()
self.ui.tabWidget.insertTab(1, self.TabWidget, "Account")

Python: Access class method variable from another file

I have a PyQt5 GUI code and it has a Ui_MainWindow class and this class has a setupUI method. Here is my gui.py:
import io
import sys
import os
import core as c
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1022, 637)
MainWindow.setMinimumSize(QtCore.QSize(1022, 637))
MainWindow.setMaximumSize(QtCore.QSize(1022, 637))
font = QtGui.QFont()
font.setKerning(False)
MainWindow.setFont(font)
MainWindow.setMouseTracking(True)
MainWindow.setFocusPolicy(QtCore.Qt.NoFocus)
.
.
.
self.lineEditSiteX = QtWidgets.QLineEdit(self.centralwidget)
self.actionCalculate.triggered.connect(c.cal) # Here is where I'm stuck!!!!!!!!!!!!!!!!!!!!
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication.instance()
if app is None:
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
In the comment above I'm trying to call a function from another file named core.py as as follows:
import gui
def cal():
val = gui.Ui_MainWindow().lineEditSiteX.value()
return val ** (1/val*2)
I simply want when someone clicks on Calculte the lineEdit value will be accessed through the core.py file. But it gives me an attributeError. How can I do it?
You have 2 errors:
Business logic should not depend on the GUI but the GUI should only use business logic.
PyQt recommends creating a class that inherits from the appropriate widget and using the class generated by Qt Designer (for more information read here).
Considering the above, the solution is:
core.py
def cal(val):
return val ** (1/val*2)
gui.py
import io
import sys
import os
import core as c
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
# ...
self.lineEditSiteX = QtWidgets.QLineEdit(self.centralwidget)
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(self, parent)
self.setupUi(self)
self.actionCalculate.triggered.connect(self.on_actionCalculate)
#QtCore.pyqtSlot()
def on_actionCalculate(self):
try:
val = float(self.lineEditSiteX.text())
except ValueError:
print("error")
finally:
res = c.cal(val)
print(res)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication.instance()
if app is None:
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

Start the script in PyQt5 and python3 [duplicate]

I have created a form using PyQt4 which has a push button. On this push button I want to call another python script which looks like this:
File1.py:
import sys
from PyQt4 import QtCore, QtGui
from file1_ui import Ui_Form
class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = MyForm()
myapp.show()
sys.exit(app.exec_())
File1_ui.py
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName(_fromUtf8("Form"))
Form.resize(400, 300)
self.pushButton = QtGui.QPushButton(Form)
self.pushButton.setGeometry(QtCore.QRect(120, 200, 95, 20))
self.pushButton.setObjectName(_fromUtf8("pushButton"))
self.retranslateUi(Form)
QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8("clicked()")), Form.close)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton.setText(QtGui.QApplication.translate("Form", "Close", None, QtGui.QApplication.UnicodeUTF8))
File2.py
import sys
from PyQt4 import Qt
from taurus.qt.qtgui.application import TaurusApplication
app = TaurusApplication(sys.argv)
panel = Qt.QWidget()
layout = Qt.QHBoxLayout()
panel.setLayout(layout)
from taurus.qt.qtgui.panel import TaurusForm
panel = TaurusForm()
model = [ 'test/i1/1/%s' % p for p in props ]
panel.setModel(model)
panel.show()
sys.exit(app.exec_())
File1_ui.py is created from the Qtdesigner and then I am using File1.py to execute it.So File2.py when executed alone opens up a panel and displays few attributes.I want this script to be called on the button click in the first form(file1.py) which I created using Qtdesigner.Could you let me know how I could achieve this functionality.Thanks.
You will need to make some modifications to File2.py to make the appropriate calls depending on whether it is running standalone or not. When you are launching the script via File1.py there will already be a QApplication instance with event loop running, so trying to create another and run its event loop will cause problems.
Firstly, move the core part of your script into its own function. This will allow you to easily call it from File1.py. You can then handle the case where the script is running standalone and needs to create a QApplication instance and start its event loop. (I am not familiar the the taurus library you are using, but you can probably substitute TaurusApplication for QtGui.QApplication)
File2.py:
import sys
from PyQt4 import QtCore, QtGui
def runscript():
panel = QtGui.QWidget()
layout = QtGui.QHBoxLayout(panel)
return panel # Must return reference or panel will be deleted upon return
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
panel = runscript()
panel.show()
sys.exit(app.exec_())
Assuming your files are in the same directory you can simply write import File2 and use File2.runscript() to run your code. You then just need to connect the function to your pushbuttons clicked() signal to run it. The only problem here is that the reference to the QWidget returned from the runscript() function will be lost (and the object deleted) if you connect directly to runscript(). For this reason I created a method launch_script() which saves a reference in MyForm.
File1.py:
import sys
from PyQt4 import QtCore, QtGui
from file1_ui import Ui_Form
import File2
class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
# This is a bit of a hack.
self.ui.pushButton.clicked.connect(self.launch_script)
def launch_script(self):
self.panel = File2.runscript()
self.panel.show()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = MyForm()
myapp.show()
sys.exit(app.exec_())
I don't use Qt Designer, so I don't know the correct way to go about connecting the signal to launch_script(). The code I have written should work, but obviously violates OOP principles and is dependent on the name of the pushbutton widget assigned by the software.

Python pyqt interface code not running

I have written a python 3.4 code which uses pyqt4 GUI modules but when i run the module it does not show anything kindly help
import sys
from PyQt4 import QtGui,QtCore
class window(QtGui.QMainWindow):
def _init_(self):
super(Window, self)._init_()
self.setGeometry(50,50,500,300)
self.setWindowTitle("Tallman Server")
self.setWindowIcon(QtGui.QIcon("tracking.png"))
self.home()
def home():
btn=QtGui.QPushButton("Quit",self)
btn.clicked.connect(QtCore.QCoreApplication.instance().quit)
self.show()
def run():
app=QtGui.QApplication(sys.argv)
GUI=window()
sys.exit(app.exec_())
run()
Firstly, the function's name is __init__ instead of _init_.
Secondly, you have to add the self parameter to home().
Those changes will solve your problem.
Modified code:
import sys
from PyQt4 import QtGui,QtCore
class window(QtGui.QMainWindow):
def __init__(self):
super(window, self).__init__()
self.setGeometry(50,50,500,300)
self.setWindowTitle("Tallman Server")
self.setWindowIcon(QtGui.QIcon("tracking.png"))
self.home()
def home(self):
btn=QtGui.QPushButton("Quit",self)
btn.clicked.connect(QtCore.QCoreApplication.instance().quit)
self.show()
def run():
app=QtGui.QApplication(sys.argv)
GUI=window()
sys.exit(app.exec_())
run()

Why does pyqtSlot decorator cause "TypeError: connect() failed"?

I have this Python 3.5.1 program with PyQt5 and a GUI created from a QtCreator ui file where the pyqtSlot decorator causes "TypeError: connect() failed between textChanged(QString) and edited()".
In the sample code to reproduce the problem I have 2 custom classes: MainApp and LineEditHandler. MainApp instantiates the main GUI (from the file "mainwindow.ui") and LineEditHandler handles a QLineEdit object. LineEditHandler reason to exist is to concentrate the custom methods that relate mostly to the QLineEdit object in a class. Its constructor needs the QLineEdit object and the MainApp instance (to access other objects/properties when needed).
In MainApp I connect the textChanged signal of the QLineEdit to LineEditHandler.edited(). If I don't decorate LineEditHandler.edited() with pyqtSlot() everything works fine. If I do use #pyqtSlot() for the method, the code run will fail with "TypeError: connect() failed between textChanged(QString) and edited()". What am I doing something wrong here?
You can get the mainwindow.ui file at: https://drive.google.com/file/d/0B70NMOBg3HZtUktqYVduVEJBN2M/view
And this is the sample code to generate the problem:
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import *
from PyQt5.QtCore import pyqtSlot
Ui_MainWindow, QtBaseClass = uic.loadUiType("mainwindow.ui")
class MainApp(QMainWindow, Ui_MainWindow):
def __init__(self):
# noinspection PyArgumentList
QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
# Instantiate the QLineEdit handler.
self._line_edit_handler = LineEditHandler(self, self.lineEdit)
# Let the QLineEdit handler deal with the QLineEdit textChanged signal.
self.lineEdit.textChanged.connect(self._line_edit_handler.edited)
class LineEditHandler:
def __init__(self, main_window, line_edit_obj):
self._line_edit = line_edit_obj
self._main_window = main_window
# FIXME The pyqtSlot decorator causes "TypeError: connect() failed between
# FIXME textChanged(QString) and edited()"
#pyqtSlot(name="edited")
def edited(self):
# Copy the entry box text to the label box below.
self._main_window.label.setText(self._line_edit.text())
def main():
app = QApplication(sys.argv)
window = MainApp()
window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Why do you want to use #pyqtSlot?
The reason it fails is that LineEditHandler is not a QObject. What #pyqtSlot does is basically creating a real Qt slot instead of internally using a proxy object (which is the default behavior without #pyqtSlot).
I don't know what was wrong, but I found a workaround: Connect the textChanged signal to a pyqtSlot decorated MainApp method that calls LineEditHandler.edited():
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import *
from PyQt5.QtCore import pyqtSlot
Ui_MainWindow, QtBaseClass = uic.loadUiType("mainwindow.ui")
class MainApp(QMainWindow, Ui_MainWindow):
def __init__(self):
# noinspection PyArgumentList
QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
# Instantiate the QLineEdit handler.
self._line_edit_handler = LineEditHandler(self, self.lineEdit)
self.lineEdit.textChanged.connect(self._line_edited)
#pyqtSlot(name="_line_edited")
def _line_edited(self):
self._line_edit_handler.edited()
class LineEditHandler:
def __init__(self, main_window, line_edit_obj):
self._line_edit = line_edit_obj
self._main_window = main_window
def edited(self):
# Copy the entry box text to the label box below.
self._main_window.label.setText(self._line_edit.text())
def main():
app = QApplication(sys.argv)
window = MainApp()
window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

Resources