I want to create 2 windows the upper one needs to be a new project window and the lower one is the project GUI, I have created my lower window completely now I am planning to create a the upper window. How do I create my Upper(New project window)? Can I do it by including a function in my class and calling my function from my run()? or should I create a new class? I am completely confused help me!
My Lower Window(Main Project Code) Code:
class Softw(QtGui.QMainWindow, Doftw.Ui_MainWindow):
def __init__(self, parent=None):
super(Softw, self).__init__(parent)
self.setGeometry(50, 50, 700, 565)
self.setWindowTitle("Softy Softw")
-------------------------
--------(some Functions in Code)
And then finally my run() function which creates and calls the class
def run():
app=QtGui.QApplication(sys.argv)
GUI = Softw()
GUI.show()
sys.exit(app.exec_())
run()
If I do a new function in my class the window shows the upper window first then disappears and then shows the lower window:
def newProject(self):
window = QtGui.QWidget()
window.setGeometry(700,330,500,300)
window.setWindowTitle("New Project")
window.show()
I think the mistake is when to call the function when do I add my function call in this senario? In init method? or Somewhere else?
Thanks!
You can create QWidget using Qt Designer to every window that you want and then you can add them as a class to your file:
For example consider, you have created the .ui file for one window you want to create then convert it to .py using pyuic4 and then create your class like:
from Ui_created import the UI_class
class NewProject(QtGui.QMainWindow, Ui_class):
def __init__(self, parent = None):
super(NewProject, self).__init__(parent)
self.setupUi(self)
Now you can connect this to some button in the main class
Related
I have recently opted to learn programming using PyQt(6). I am trying to build a multi-tab main window where each tab is going to have their own functionality.
What I'm doing is that I designed my QMainWindow in QtDesigner and then used pyqt6.uic to import the .ui file, consequently accessing the widgets and views with findchild.
It is all going well If code like this, but the problem is that the great number of signals and slots in the code make the code very hard to debug and read after a short time.
I thought about defining each of these functionalities with their own class, but I could not make the connection between these sub classes and the main class.
I am not sure if that the correct approach to it, and if it is, then I probably miss a note or two with using multiple classes in PyQt.
Many thanks!
P.S.: I have updated the topic with a simple code to make my intention clearer Say I have main window with a tab widget consisting N tabs.
class UI(QMainWindow):
def __init__(self):
super(UI, self).__init__()
uic.loadUi('SO.ui', self)
#Instead of writing all the codes from tab1 to tabN. Use them in a clearer
#such as having their functionality in a different .py file.
#Maybe a way to inherit tab1 and tab2?
#Window runs via this method then.
class tab1(QMainWindow):
def __init__(self):
super(tab1, self).__init__()
uic.loadUi('SO.ui', self)
#signals and slots in Tab1 placed in a seperate .py file
class tab2(QMainWindow):
def __init__(self):
super(tab2, self).__init__()
uic.loadUi('SO.ui', self)
#signals and slots in Tab2 placed in a seperate .py file
Basically I have created a Dialog without buttons window as an alert box using Qt5 designer and compiled to Python using Pyuic5 which resulted into partial code as below:
class Ui_alertwindow(object):
def setupUi(self, alertwindow):
alertwindow.setObjectName("alertwindow")
alertwindow.resize(400, 300)
alertwindow.setStyleSheet("background:#222;")
# much more code
Later on, I will have to modify parts of this window which I could not using Qt5 designer, hence I created a separate class to make the changes, as below:
class alertWindowCustom(QDialog, Ui_alertwindow):
def __init__(self):
QDialog.__init__(self)
self.setupUi(self)
self.run()
def run(self):
print("Changes will be made here")
And then finally call this function in QMainWindow when a button is pressed:
def CreateAlertWindow(self):
alertWindow = alertWindowCustom()
alertWindowInput = alertWindow.exec_()
This creates a white dialog box while not responding and in the console I am getting below errors:
Changes will be made here
Unknown property justification
Unknown property justification
QBasicTimer::stop: Failed. Possibly trying to stop from a different thread
QBasicTimer::stop: Failed. Possibly trying to stop from a different thread
Can anyone tell me what is wrong here?
I am a beginner in python but my OOPS concept from Java and Android are strong enough to motivate me in making some tool in python.
I am using PyQt for developing the application. In my application there are lot of QTabWidget used and has lot of UI controls in each TAB widget. Please see the screenshot for the same.
All of the event control of entire tool i have kept in one single file but now i want to segregate it based on one individual python file per QTab for event control inside the Tab.
My project file architecture looks like :
I know this would be some really easy thing but considering my experience with Python i am finding it difficult. I would really appreciate example with code snippet. Since i am able to control real complicated QThread from seperate files but not able get how to do it for Ui controls.
I tried making a file for it like i made for Thread classes but end up with argument passing expection to super
from generated.MainGUI import Ui_MainWindow
class SemiAuto_Create_Load(QtGui.QMainWindow):
def __init__(self,parent=none):
super(SemiAuto_Create_Load, self).__init__()
self.ui = Ui_MainWindow
self.ui.setupUi(self)
self.connectControlEvents()
Tried : self.sacl = SemiAuto_Create_Load()
Exception :
TypeError: init() takes exactly 3 arguments (1 given)
Okay i got this working with changes in
Mainwindow.py
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent = None):
super(MainWindow, self).__init__(parent)
Profile().notify(None)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.connectButtons()
SemiAuto_Create_Load(self, self.ui)
And
SemiAuto_Create_Load
class SemiAuto_Create_Load(QtGui.QMainWindow):
def __init__(self, parent, ui):
super(SemiAuto_Create_Load, self).__init__(parent)
self.ui = ui
self.connectControlEvents()
def connectControlEvents(self):
self.ui.load_vsa_radio.clicked.connect(self.onLoad_vsa_radio)
self.ui.create_vsa_radio.clicked.connect(self.onCreate_vsa_radio)
Problem was passing the parameter with parent in init() and trying to get the object of MainGUI directly instead of as a parameter from MainWindow
I have a main window that creates modeless dialogs. That's working well, but the dialogs are always in front of the main window. Even if I go back to the main window and use it to give it focus, the dialogs always remain on top. I cannot slide the main window on top of the dialogs.
I'm passing the main window's self as the parent to the dialog.
#In my main window
self.beacon_dlg = dialog_beacon.BeaconDialog(self)
#In the dialog class
class BeaconDialog(QDialog, ui_dialog_beacon.Ui_Dlg_beacon_soh):
def __init__(self, parent):
super(BeaconDialog, self).__init__(parent)
self.setupUi(self)
Any idea how to allow the main window to be in front of the dialogs, and still close the dialog when the main window is closed (parent control)?
(I'm using PyQt 4.10 and Python 2.7 on Windows)
Thanks.
I ended up using the following and it seems to work, but not sure if it's the best method. Instead of using:
def __init__(self, parent):
super(BeaconDialog, self).__init__(parent)
I used:
def __init__(self, parent):
super(BeaconDialog, self).__init__()
thus not making the dialog a child of the main window. (I still passed the main window as an argument to the class for other reasons)
However then in order to have the dialog shutdown correctly I had to overload the main window's closeEvent() and shut down the dialog myself with:
def closeEvnet(self):
if (self.beacon_dlg) : self.beacon_dlg.reject()
From QDialog Class Reference: "A dialog is always a top-level widget, but if it has a parent, its default location is centered on top of the parent's top-level widget (if it is not top-level itself). It will also share the parent's taskbar entry."
You could try to use QWidget instead.
I'm trying to modify a program written using pyQt (specifically, Anki). I want the program to briefly flash a picture (stored as a file on my hard drive) and then continue running normally.
This code will be inserted at some arbitrary point in the program. This is an ad-hoc single-user patch to an existing program - it does not need to be fast or elegant or easily-maintained.
My problem is that I know very little about pyQt. Do I need to define an entire new "window", or can I just run some sort of "notification" function with an image inside it?
QSplashScreen will be useful for this. It is mainly used for displaying certain image/text while a program loads, but your case also looks ideal for this. You can close it with clicking on it, or additionally you can set a timer to auto-close it after some time.
Here is a simple example with a dialog that has one button. When pressed it'll show the image and close after 2 seconds:
import sys
from PyQt4 import QtGui, QtCore
class Dialog(QtGui.QDialog):
def __init__(self, parent=None):
super(Dialog, self).__init__(parent)
layout = QtGui.QVBoxLayout()
self.setLayout(layout)
self.b1 = QtGui.QPushButton('flash splash')
self.b1.clicked.connect(self.flashSplash)
layout.addWidget(self.b1)
def flashSplash(self):
# Be sure to keep a reference to the SplashScreen
# otherwise it'll be garbage collected
# That's why there is 'self.' in front of the name
self.splash = QtGui.QSplashScreen(QtGui.QPixmap('/path/to/image.jpg'))
# SplashScreen will be in the center of the screen by default.
# You can move it to a certain place if you want.
# self.splash.move(10,10)
self.splash.show()
# Close the SplashScreen after 2 secs (2000 ms)
QtCore.QTimer.singleShot(2000, self.splash.close)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
main = Dialog()
main.show()
sys.exit(app.exec_())