How to run the program generated by pyuic4? - python

I'm new to PyQt though I know python a bit.. I wanted to Qt designer for GUI programming since it'll make my job easier. I've taken a simple dialog in Qt designer and converted using pyuic4.
from PyQt4 import QtCore, QtGui
class Ui_Form1(object):
def setupUi(self, Form1):
Form1.setObjectName("Form1")
Form1.resize(495, 364)
self.listWidget = QtGui.QListWidget(Form1)
self.listWidget.setGeometry(QtCore.QRect(60, 100, 221, 111))
self.listWidget.setObjectName("listWidget")
self.lineEdit = QtGui.QLineEdit(Form1)
self.lineEdit.setGeometry(QtCore.QRect(60, 250, 221, 26))
self.lineEdit.setObjectName("lineEdit")
self.pushButton = QtGui.QPushButton(Form1)
self.pushButton.setGeometry(QtCore.QRect(350, 170, 92, 28))
self.pushButton.setAutoDefault(False)
self.pushButton.setObjectName("pushButton")
self.retranslateUi(Form1)
QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL("clicked()"), self.listWidget.clear)
QtCore.QMetaObject.connectSlotsByName(Form1)
def retranslateUi(self, Form1):
Form1.setWindowTitle(QtGui.QApplication.translate("Form1", "Form1", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton.setText(QtGui.QApplication.translate("Form1", "X", None, QtGui.QApplication.UnicodeUTF8))
I want to run this program. How to run this program from this file by importing this? I know it's a very basic question.

You may pass -x parameter to pyuic. It will generate addtional code to make the script executable.
In real application you should better write a subclass of QMainWindow which could look like this:
# Store this code in the file MyMainWindow.py
from PyQt4.QtGui import *
class MyMainWindow(QMainWindow):
def __init__(self, ui_layout):
QMainWindow.__init__(self)
self.ui = ui_layout
ui_layout.setupUi(self)
And also create a main executable script in the same directory as MyMainWindow.py:
from PyQt4.QtGui import *
from MyMainWindow import *
from Form1 import * # replace Form1 the name of your generated file
import sys
app = QApplication(sys.argv)
window = MyMainWindow(Ui_Form1())
window.show()
sys.exit(app.exec_())
Then run this last script to launch the program.

Related

How to link Qt Designer button to a function in a separate file [duplicate]

This question already has answers here:
QtDesigner changes will be lost after redesign User Interface
(2 answers)
Closed 2 years ago.
I'm new to Python and I've searched for an answer but couldn't find it (or rather couldn't properly implement it).
I've generated a window with a few buttons in QtDesigner's file named "arch.ui", converted to arch.py.
As I'll be updating GUI occasionally, I don't want to create functions in arch.py, so I've created a main.py file for that.
I've a problem with linking button click to a function => I try to link "btnSource" (from arch.py) to function "printMe" (in main.py).
Obviously it doesn't work. Any help welcome.
Here is generated Designer file:
# Form implementation generated from reading ui file 'arch.ui'
#
# Created by: PyQt5 UI code generator 5.15.0
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(460, 233)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.btnSource = QtWidgets.QPushButton(self.centralwidget)
self.btnSource.setGeometry(QtCore.QRect(80, 60, 75, 23))
self.btnSource.setObjectName("btnSource")
self.lblSource = QtWidgets.QLabel(self.centralwidget)
self.lblSource.setGeometry(QtCore.QRect(180, 60, 511, 21))
self.lblSource.setObjectName("lblSource")
self.lblTarget = QtWidgets.QLabel(self.centralwidget)
self.lblTarget.setGeometry(QtCore.QRect(180, 120, 481, 16))
self.lblTarget.setObjectName("lblTarget")
self.btnTarget = QtWidgets.QPushButton(self.centralwidget)
self.btnTarget.setGeometry(QtCore.QRect(80, 120, 75, 23))
self.btnTarget.setObjectName("btnTarget")
self.btnGo = QtWidgets.QPushButton(self.centralwidget)
self.btnGo.setGeometry(QtCore.QRect(280, 120, 75, 23))
self.btnGo.setObjectName("btnGo")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 460, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.btnSource.setText(_translate("MainWindow", "Source"))
self.lblSource.setText(_translate("MainWindow", "TextLabel"))
self.lblTarget.setText(_translate("MainWindow", "TextLabel"))
self.btnTarget.setText(_translate("MainWindow", "Target"))
self.btnGo.setText(_translate("MainWindow", "Go"))
And here is my main.py file:
from PyQt5 import QtCore, QtGui, QtWidgets
from arch import Ui_MainWindow
import sys
app = QtWidgets.QApplication(sys.argv)
class myWindow(Ui_MainWindow):
def __init__(self):
super(myWindow, self).__init__()
self.btnSource.clicked.connect(self.btnSource.printMe)#
def printMe(self):
print('blah blah blah')
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
tl;dr
Subclass from both QMainWindow and Ui_MainWindow, and call setupUi from there; then create an instance of myWindow:
class MyWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super(MyWindow, self).__init__()
self.setupUi(self)
self.btnSource.clicked.connect(self.printMe)
def printMe(self):
print('blah blah blah')
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
mainWindow = MyWindow()
mainWindow.show()
sys.exit(app.exec_())
Explanation
Your code doesn't work for many reasons; while the main problem might be that you actually never created an instance of myWindow (about that, you should always use capitalized names for classes), making it completely useless, it wouldn't have worked anyway.
That's because you should not subclass from the ui class object, but from the QWidget descendant (QMainWindow, in your case) you're going to use.
The ui_* objects created from pyuic are only intended as a high level (and unmodified) interface to create the UI on top of a QWidget subclass.
Calling setupUi(something) actually creates all child widgets for the widget something, sets the layout and, possibly, automatically connects to slots with a compatible name, but that's all: in fact, if you closely look at the code from the ui file, it actually does nothing besides setupUi and retranslateUi (nor it should!): there's not even an __init__!
If you need to add interaction and create connections from signals to slot/functions, you should use the single/multiple inheritance approaches as explained in the official guide about using Designer with PyQt; the only other possibility is to use loadUi (while still subclassing from the base class) with the source .ui file:
from PyQt5 import QtWidgets, uic
class MyWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi('path/to/gui.ui', self)
self.someWidget.someSignal.connect(self.someSlot)
# ...
def someSlot(self, signalArguments, [...]):
# do something...
PS: for various reasons, it's usually better to run a QApplication only if the script is the one that's been run (hence the if __name__ ...), mostly because there should be just only one QApplication instance for every running program; in any case, it shouldn't be created before the class declarations (unless, you really know what you're doing); it's not a big deal in your case, but, as usual, better safe than sorry.

update a python ui without rewrite all the button event

I'm looking for a better way to handle python UI "update" from QtDesigner without overwrite button event. The workflow I got now is:
Design UI layout in QtDesigner
convert .ui to .py by pyuic5
adding button event in .py file
excute .py to see window and button action
So if my UI keep changing the design, how do I keep all the button event I add into .py without being overwrite after convert? Thank you.
Answer my own question, what I found is have three python files. Main.py, CallUI.py and MainWindow.py. (Named as you want.)
So you can keep regenerate UI and override MainWindow.py without clear button event you wrote.
1.Main.py is the one to launch everything, name == "main". Call CAllUI.py's setup function.
#Main.py
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
import CallUI
def setUp():
CallUI.setUpWindow()
raw_input()
if __name__ == "__main__":
setUp()
2.CallUI.py is the one to use "QtWidgets.QApplication(sys.argv)" to show UI and add button click functions.
#CallUI.py
import sys
from MainWindow import Ui_Dialog
from PyQt5 import QtCore, QtGui, QtWidgets
import os
class CallUI(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
self.setUpBtnconnect()
def setUpBtnconnect(self):
self.ui.pushButton.clicked.connect(self.myFunction)
def myFunction(self):
os.system("ipconfig")
raw_input()
def setUpWindow():
app = QtWidgets.QApplication(sys.argv)
nowWindow = CallUI()
nowWindow.show()
sys.exit(app.exec_())
3.MainWindow.py is the one you converted from pyuic5, it's describe all the UI layout.
#MainWindow.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("MainWindow")
Dialog.resize(466, 417)
self.centralwidget = QtWidgets.QWidget(Dialog)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(160, 260, 75, 23))
self.pushButton.setObjectName("pushButton")
self.menubar = QtWidgets.QMenuBar(Dialog)
self.menubar.setGeometry(QtCore.QRect(0, 0, 466, 21))
self.menubar.setObjectName("menubar")
self.statusbar = QtWidgets.QStatusBar(Dialog)
self.statusbar.setObjectName("statusbar")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
self.pushButton.setText(_translate("MainWindow", "PushButton"))

PyQt Call Function Does Not Work

So I am using QT to create a GUI in Python.
I have created the *.ui code and converted it to *.py
The next step is to create a line of code in python to call the newley converted *.py code.
This is the converted .ui code now in .py:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(383, 54)
self.label = QtWidgets.QLabel(Dialog)
self.label.setGeometry(QtCore.QRect(40, 10, 61, 16))
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(270, 10, 75, 23))
self.pushButton.setObjectName("pushButton")
self.lineEdit = QtWidgets.QLineEdit(Dialog)
self.lineEdit.setGeometry(QtCore.QRect(110, 10, 113, 20))
self.lineEdit.setObjectName("lineEdit")
self.retranslateUi(Dialog)
self.pushButton.clicked.connect(self.lineEdit.clear)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.label.setText(_translate("Dialog", "Enter Text"))
self.pushButton.setText(_translate("Dialog", "Clear"))
Now I am creating a call function, this is the part that does not seem to work. I have written the code and can not see any error at all. If anyone could help it would be truly appreciated:
import sys
from FirstApp import *
class MyForm(QtGui.QDialog):
def _init_(self,parent=none):
QtGui.QWidget._init_(self,parent)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
if _name_ == "_main_":
app = QtGui.QApplication(sys.argv)
myapp = MyForm()
myapp.show()
sys.exit(app.exec_())
p.s
This is all for my online degree, unfortunately we have no tutors and have to seek online help when we get stuck. This is why I am creating this GUI this way.
The second part is quite buggy, try this one :
from PyQt5 import QtWidgets
from FirstApp import *
import sys
class MyForm(QtWidgets.QDialog):
def __init__(self, parent=None):
QtWidgets.QDialog.__init__(self, parent)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
myapp = MyForm()
myapp.show()
sys.exit(app.exec())
(be careful about double underscores everywhere, or None not none)
I'm aware this is an older question, but I happened to stumble across it and am aware of an easier way. In my case, I was able to convert the *.ui file into an *.py file using pyside2. By navigating to the folder the the *.ui file is in and then running this on the command line
pyside2-uic <name_of_ui_file> <name_of_*.ui_file>.py
an *.py file will be generated in that folder as well.
For example, if my *.ui file was called 'form.ui' and placed on my desktop. I would CD into my desktop and then run
pyside2-uic form.ui > form.py
and form.py would be generated inside of my folder.

Does PYQT5 support all python libraries?

I am new to python and GUI programming as well.
I need to build a front-end GUI application and for the back - end application I have already built in python 2.7.
My question is, if I develop a front end application in PyQT, will I be able to integrate the python code in that (or) will the PYQT support python modules like socket, threading etc.?
PyQt doesn't handle the back-end code. It is used to set up hooks so that when a user interacts with the GUI, some code is launched in Python.
In other words, yes, you'll be able to implement things like threading.
Here's an example where I'm clicking a button which has a 'hook' to launch a process. In this case, I'm launching the process in another thread so that the GUI doesn't freeze up.
import sys
import time
import threading
import datetime as dt
# Import from qtpy if you're running Anaconda3
from qtpy import QtCore, QtGui, QtWidgets
# Import from PyQt5 otherwise
# from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.resize(500, 220)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(400, 180, 93, 28))
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(10, 10, 471, 141))
font = QtGui.QFont()
font.setPointSize(20)
self.label.setFont(font)
self.label.setAlignment(QtCore.Qt.AlignCenter)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtCore.QCoreApplication.translate("MainWindow", "MainWindow", None))
self.pushButton.setText(QtCore.QCoreApplication.translate("MainWindow", "Start", None))
self.label.setText(QtCore.QCoreApplication.translate("MainWindow", "", None))
def main():
# Continually update LineEdit with the time when the button is pressed
# We can do this without freezing the GUI by launching update_time()
# in another thread
ui.pushButton.clicked.connect(lambda: threading.Thread(target=update_time).start())
def update_time():
while True:
current_time_text = dt.datetime.now().strftime('%b %d %Y %I:%M:%S %p')
ui.label.setText(current_time_text)
time.sleep(.01)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
main()
sys.exit(app.exec_())

Qt Framework, PyQt5 and AttributeError: 'MyApp' object has no attribute 'myAttribute'

Last week I started to learn Python and I developed some command line apps. Now I would like to develop apps with GUI. I searched in internet and I found a project that fits my needs: Qt Project (http://qt-project.org) and PyQt (http://www.riverbankcomputing.com/software/pyqt/intro). I installed Qt 5.3.2 Open Source, SIP 4.16.4, PyQt5 5.3.2 on Mac OS X 10.10 and python 2.7.6. After some troubles on installing Qt and PyQt, finally I managed to make them work. If I open example projects from PyQt example folder the gui appears without any problems. So I created my GUI with Qt Creator and then I used pyuic5 to generate python code. This is what pyuic5 created (file name "myapp_auto.py"):
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file '/Users/andrea/Developer/Qt/mainwindow.ui'
#
# Created: Mon Nov 17 14:20:14 2014
# by: PyQt5 UI code generator 5.3.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(400, 300)
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setObjectName("centralWidget")
self.ok = QtWidgets.QPushButton(self.centralWidget)
self.ok.setGeometry(QtCore.QRect(140, 120, 115, 32))
self.ok.setAccessibleName("")
self.ok.setObjectName("ok")
self.text = QtWidgets.QLabel(self.centralWidget)
self.text.setGeometry(QtCore.QRect(100, 70, 181, 16))
self.text.setAccessibleName("")
self.text.setAlignment(QtCore.Qt.AlignCenter)
self.text.setObjectName("text")
self.time = QtWidgets.QDateTimeEdit(self.centralWidget)
self.time.setGeometry(QtCore.QRect(100, 180, 194, 24))
self.time.setAccessibleName("")
self.time.setObjectName("time")
MainWindow.setCentralWidget(self.centralWidget)
self.menuBar = QtWidgets.QMenuBar(MainWindow)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 400, 22))
self.menuBar.setObjectName("menuBar")
self.menuMyApp = QtWidgets.QMenu(self.menuBar)
self.menuMyApp.setObjectName("menuMyApp")
self.menuEdit = QtWidgets.QMenu(self.menuBar)
self.menuEdit.setObjectName("menuEdit")
MainWindow.setMenuBar(self.menuBar)
self.mainToolBar = QtWidgets.QToolBar(MainWindow)
self.mainToolBar.setObjectName("mainToolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)
self.statusBar = QtWidgets.QStatusBar(MainWindow)
self.statusBar.setObjectName("statusBar")
MainWindow.setStatusBar(self.statusBar)
self.menuBar.addAction(self.menuMyApp.menuAction())
self.menuBar.addAction(self.menuEdit.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.ok.setText(_translate("MainWindow", "Ok"))
self.text.setText(_translate("MainWindow", "I\'m a GUI"))
self.menuMyApp.setTitle(_translate("MainWindow", "MyApp"))
self.menuEdit.setTitle(_translate("MainWindow", "Edit"))
After that I added a new python file where I put my code; this is what i wrote (file name "myapp.py"):
#!/usr/bin/env python
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from myapp_auto import Ui_MainWindow
import sys
import time
class MyApp(Ui_MainWindow):
parse_triggered = pyqtSignal()
def __init__(self, parent=None, name=None):
Ui_MainWindow.__init__(self)
if __name__ == "__main__":
app = QApplication(sys.argv)
MainWindow = QMainWindow()
ui = MyApp()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Then, I run myapp.py and I verified that all GUI elements appeared to be where they should be. Well...now arrive my issue: I tried to access with code the "time" element in MainWindow modifying init def thus:
def __init__(self, parent=None, name=None):
Ui_MainWindow.__init__(self)
# Set the date to now
now = QDateTime()
now.setTime_t(int(time.time()))
self.time.setDateTime(now)
But the compiler shows alway this error:
AttributeError: 'MyApp' object has no attribute 'time'
This happen even if I try to access any other element ("ok", "text").
Will surely be a stupid mistake but I just can not figure out where I went wrong.
Thank you all guys!
Have a good day,
Andrea
You're not far off.
The MyApp class needs to inherit QMainWindow, and you don't need to use the time module. Try something like this:
class MyApp(QMainWindow, Ui_MainWindow):
parse_triggered = pyqtSignal()
def __init__(self, parent=None, name=None):
super(MyApp, self).__init__(parent)
self.setupUi(self)
# Set the date to now
self.time.setDateTime(QDateTime.currentDateTime())
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())

Categories

Resources