My code was created with PyQt4 and I want to convert it to PyQt5.
I have tried some scripts to convert the code; but, nothing changed except the name.
What do I need to change manually in order to make the code work with PyQt5?
Here is the first part of my code:
import sys
from pymaxwell import *
from numpy import *
from PyQt4 import QtGui, QtCore, uic
from PyQt4.QtGui import QMainWindow, QApplication
from PyQt4.QtCore import *
from PyQt4.phonon import Phonon
from ffmpy import FFmpeg
import os
import app_window_dark
import about
uifile = 'Ui/app_window_dark.ui'
aboutfile = 'Ui/about.ui'
Ui_MainWindow, QtBaseClass = uic.loadUiType(uifile)
Ui_Dialog= uic.loadUiType(uifile)
class About(QtGui.QMainWindow, about.Ui_Dialog):
def __init__(self, parent=None):
super(About, self).__init__()
QtGui.QMainWindow.__init__(self, parent)
Ui_Dialog.__init__(self)
self.setWindowModality(QtCore.Qt.ApplicationModal)
point = parent.rect().bottomRight()
global_point = parent.mapToGlobal(point)
self.move(global_point - QPoint(395, 265))
self.setupUi(self)
class MyApp(QtGui.QMainWindow, app_window_dark.Ui_MainWindow):
def __init__(self):
super(MyApp, self).__init__()
QtGui.QMainWindow.__init__(self)
self.ui = Ui_MainWindow.__init__(self)
self.setupUi(self)
self.about_btn.clicked.connect(self.popup)
#prev next
self.btn_next.clicked.connect(self.renderSet)
self.btn_prev.clicked.connect(self.renderSet)
and also this code:
if __name__ == "__main__":
app = QApplication(sys.argv)
#style = QApplication.setStyle('plastique')
window = MyApp()
window.setFixedSize(750, 320)
window.show()
sys.exit(app.exec_())
The main change from Qt4 to Qt5 and hence from PyQt4 to PyQt5 is the rearrangement of certain classes so that the Qt project is scalable and generates a smaller executable.
The QtGui library was divided into 2 submodules: QtGui and QtWidgets, in the second only the widgets, namely QMainWindow, QPushButton, etc. And that is the change you must make:
[...]
from PyQt5 import QtGui, QtCore, uic, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtCore import *
[...]
Ui_MainWindow, QtBaseClass = uic.loadUiType(uifile)
Ui_Dialog= uic.loadUiType(uifile)
class About(QtWidgets.QMainWindow, about.Ui_Dialog):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)
self.setWindowModality(QtCore.Qt.ApplicationModal)
point = parent.rect().bottomRight()
global_point = parent.mapToGlobal(point)
self.move(global_point - QPoint(395, 265))
class MyApp(QtWidgets.QMainWindow, app_window_dark.Ui_MainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.setupUi(self)
self.about_btn.clicked.connect(self.popup)
#prev next
self.btn_next.clicked.connect(self.renderSet)
self.btn_prev.clicked.connect(self.renderSet)
Note: Phonon does not exist in PyQt5, you must use QtMultimedia, an accurate solution you can find it in the following answer: Phonon class not present in PyQt5
Related
Program
import sys
import os
from PyQt5 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import *
from PySide2 import *
from ui_test import *
class MainThread(QThread):
def __init__(self):
super(MainThread,self).__init__()
def run(self):
self.task()
def task(self):
while True:
com="runnning"
print(com)
startexecution = MainThread()
class main(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.ti = Ui_MainWindow()
self.ti.setupUi(self)
self.ti.run_btn.clicked.connect(self.starttask)
self.ti.close.clicked.connect(self.close)
self.show()
def starttask(self):
startexecution.start()
if __name__=="__main__":
app =QApplication(sys.argv)
window = main()
sys.exit(app.exec_())
It is an example of the problem I am facing in my original program
MainThread class run is the main program that runs in the backend and the main class runs GUI in frontend. I want to show the output generated by the backend program in textbrowser of my UI as an output
I want to change the UI without opening new windows. The problem is that when I do this on widgets then the app is not frameless. When I do it without widgets I have no idea how to change the UI.
Without widget
import sys, time, os
from PyQt5 import uic
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QPixmap
import sqlite3
class LoginMenu(QWidget):
def __init__(self):
super(LoginMenu, self).__init__()
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
uic.loadUi("LoginMenu.ui",self)
self.clicked = False
def mousePressEvent(self, event):
self.old_pos = event.screenPos()
def mouseMoveEvent(self, event):
if self.clicked:
dx = self.old_pos.x() - event.screenPos().x()
dy = self.old_pos.y() - event.screenPos().y()
self.move(self.pos().x() - dx, self.pos().y() - dy)
self.old_pos = event.screenPos()
self.clicked = True
return QWidget.mouseMoveEvent(self, event)
app = QApplication(sys.argv)
log = LoginMenu()
log.show()
sys.exit(app.exec())
with widgets to run app
import sys, time, os
from PyQt5 import uic
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QPixmap
class LogMenu(QWidget):
def __init__(self):
super(LogMenu, self).__init__()
uic.loadUi("LoginMenu.ui",self)
self.SignUp.clicked.connect(self.gotoReg)
def gotoReg(self):
reg=Register()
widget.addWidget(reg)
widget.setCurrentIndex(widget.currentIndex()+1)
class Register(QWidget):
def __init__(self):
super(Register, self).__init__()
uic.loadUi("SignUp.ui",self)
#main
app = QApplication(sys.argv)
widget = QtWidgets.QStackedWidget()
log=LogMenu()
reg=Register()
widget.addWidget(log)
widget.addWidget(reg)
widget.show()
try:
sys.exit(app.exec())
except:
print("Exiting")
sry for my eng if sth i wrote sth bad
tbh idk how to make it frameless with widgets and draggable with clicking and holding the app or switchable without using widget to run it
in principal I reopen my question some days ago:
where-do-i-write-the-class-for-a-single-promoted-qwidget-from-qt-designer
The solution works, but I run into 2 more questions
if I want to change the text in the class neuLabel, how do i adress the class out of main program?
Additional information for minimal example as required:
I have a qt designer main window, named testpromote.ui. It contains only one label. Text is "MyLabel", the name is neuLabel and it is promoted as neulabel.
I need 2 .py files in one directory.
First the main testpromote.py
import sys
import os
from PyQt5 import uic
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import * #QPainter
import neulabel
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
uifile_1 = os.path.join(CURRENT_DIR, "testpromote.ui")
form_1, base_1 = uic.loadUiType(uifile_1)
class myApp(base_1, form_1):
def __init__(self):
super(base_1,self).__init__()
self.setupUi(self)
# ??????????????
#neuLabel.setText(neuLabel,"from main")
# ??????????????
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = myApp() #Dialog()
ex.show()
sys.exit(app.exec_())
2nd file is neulabel.py
from PyQt5.QtWidgets import *
from PyQt5 import uic
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import *
from PyQt5.QtGui import * #QPainter
class neuLabel(QLabel):
def __init__(self,parent=None):
super().__init__(parent)
self.setAcceptDrops(True)
self.setText("from code")
print("the new pixmap?", self.text())
My aim is to change the text of the label out of the main program testpromote.py
I do not understand, how to import the neulabel.py, so that i could change the text of the label.I tried it with "neuLabel.setText(neuLabel,"from main")", but this doesn't work. I tried it with other code too, but not succesfully. (This is marked within the # ????????? lines)
To see, if the text in the label changes, I added in neulabel.py the
self.setText() statement, but the text does not change in the window.
(i hope, it is clearer now)
I have a multi-windowed PyQt5 (Python 3.6.2 with Qt 5.9.0) application which works perfectly when run in a standard desktop (i.e. window managed) environment. My target platform is an embedded device (Raspberry Pi, i.MX6, etc. for example), where I won't be using the X11 window system. I'm currently testing the embedded device with the eglfs platform, which doesn't support multiple windows. I'm considering either using the QtWayland platform, or modifying my approach to use a QtStackedWidget to contain the 'windows' as individual pages within the stack.
How can I modify the below high-level windowed application to leverage a QStackedWidget arrangement, to facilitate a multi-paged application in a windowless environment?
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
from ui_Main import Ui_Main
from ui_Window1 import Ui_Window1
from ui_Window2 import Ui_Window2
class Main(QMainWindow, Ui_Main):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
self.setupUi(self)
#Initialisation functions
self.PushButton1.clicked.connect(self.OpenWindow1)
self.PushButton2.clicked.connect(self.OpenWindow2)
def OpenWindow1(self):
showWindow1.show()
def OpenWindow2(self):
showWindow2.show()
class Window1(QMainWindow, Ui_Window1):
def __init__(self, parent=None):
super(Window1, self).__init__(parent)
self.setupUi(self)
class Window2(QMainWindow, Ui_Window2):
def __init__(self, parent=None):
super(Window2, self).__init__(parent)
self.setupUi(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
showMain = Main()
showWindow1 = Window1()
showWindow2 = Window2()
showMain.show()
app.exec_()
I've used a QStackedLayout to nest each of the 'windows' within a single page, and then consolidated each of the setupUI() functions of the external .py files into a single external file. The below files reflect this approach, using the sample multi-window example posted in my question.
ui_Main.py:
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
class Ui_Main(QtWidgets.QWidget):
def setupUi(self, Main):
Main.setObjectName("Main")
Main.resize(800, 480)
self.QtStack = QtWidgets.QStackedLayout()
self.stack1 = QtWidgets.QWidget()
self.stack2 = QtWidgets.QWidget()
self.stack3 = QtWidgets.QWidget()
self.Window1UI()
self.Window2UI()
self.Window3UI()
self.QtStack.addWidget(self.stack1)
self.QtStack.addWidget(self.stack2)
self.QtStack.addWidget(self.stack3)
def Window1UI(self):
self.stack1.resize(800, 480)
#PushButton1#
self.PushButton1 = QtWidgets.QPushButton(self.stack1)
self.PushButton1.setText("BUTTON 1")
self.PushButton1.setGeometry(QtCore.QRect(10, 10, 100, 100))
#PushButton2#
self.PushButton2 = QtWidgets.QPushButton(self.stack1)
self.PushButton2.setText("BUTTON 2")
self.PushButton2.setGeometry(QtCore.QRect(150, 150, 100, 100))
def Window2UI(self):
self.stack2.resize(800, 480)
self.stack2.setStyleSheet("background: red")
def Window3UI(self):
self.stack3.resize(800, 480)
self.stack3.setStyleSheet("background: blue")
Main.py:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
from ui_Main import Ui_Main
class Main(QMainWindow, Ui_Main):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
self.setupUi(self)
self.PushButton1.clicked.connect(self.OpenWindow1)
self.PushButton2.clicked.connect(self.OpenWindow2)
def OpenWindow1(self):
self.QtStack.setCurrentIndex(1)
def OpenWindow2(self):
self.QtStack.setCurrentIndex(2)
if __name__ == '__main__':
app = QApplication(sys.argv)
showMain = Main()
sys.exit(app.exec_())
I have written the following python program using pyqt4. It is a simple program to show icon in a window.
from PyQt4.QtGui import *
from PyQt4 import QtGui, QtCore
import sys
class Main(QtGui.QMainWindow):
def __init__(self, parent = None):
super(Main, self).__init__(parent)
self.centralWidget=QWidget()
self.setCentralWidget(self.centralWidget)
w=QGridLayout()
size=128
icon=QIcon()
mode=QIcon.Selected
state=QIcon.Off
pixma = QPixmap('a.png')
icon.addPixmap(pixma,mode,state)
label=QLabel()
label.setPixmap(icon.pixmap(size,mode,state))
w.addWidget(label,0,0,0,1)
self.centralWidget.setLayout(w)
self.resize(self.minimumSizeHint())
although mode is set to selected but I do not see the icon to be selected.
It shows me a selected icon when I write the code in the following way:
from PyQt4.QtGui import *
from PyQt4 import QtGui, QtCore
import sys
class Main(QtGui.QMainWindow):
def __init__(self, parent = None):
super(Main, self).__init__(parent)
self.centralWidget=QWidget()
self.setCentralWidget(self.centralWidget)
w=QGridLayout()
size=128
icon=QIcon()
mode=QIcon.Selected
state=QIcon.Off
pixma = QPixmap('a.png')
icon.addPixmap(pixma,mode,state)
label=QLabel()
#CHANGED CODE
label.setPixmap(icon.pixmap(size,QIcon.Selected,state))
w.addWidget(label,0,0,0,1)
self.centralWidget.setLayout(w)
self.resize(self.minimumSizeHint())
what might be the issue?