I have created a PyQt MainWindow app and I have also created 2 PyQt dialogs in PyQt designer, then a "calling" .pyw program, problem is that when I try open the different dialogs, it only opens one dialog.
how do I explicitly set/link a dialog to a class:
import sys
from MainApp import *
from Dialog1 import *
from Dialog2 import *
from PyQt4 import Qt, QtGui
class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
QtCore.QObject.connect(self.ui.pushButton1, QtCore.SIGNAL('clicked()'), self.openDialog1)
QtCore.QObject.connect(self.ui.pushButton2, QtCore.SIGNAL('clicked()'), self.openDialog2)
def openDialog1(self):
editDialog = Dialog1()
editDialog.exec_()
def openDialog2(self):
editDialog = Dialog2()
editDialog.exec_()
class Dialog1(QtGui.QDialog):
isEdit = False
def __init__(self, studentId=0, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
class Dialog2(QtGui.QDialog):
isEdit = False
def __init__(self, studentId=0, 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_())
Be default it loads Dialog2, If I comment out this line:
from Dialog2 import **
Then it loads Dialog1, I want to explicitly set which dialog it loads
Github link
Your import:
from Dialog1 import *
from Dialog2 import *
It is equivalent to:
from Dialog1 import Ui_Dialog
from Dialog2 import Ui_Dialog
so in the end Ui_Dialog will refer to the design of Dialog2.py and that's the reason why only the second form is shown.
The solution is to differentiate both imports and for this you can use: as
import sys
from MainApp import *
from Dialog1 import Ui_Dialog as Ui_Dialog1 # change this line
from Dialog2 import Ui_Dialog as Ui_Dialog2 # change this line
from PyQt4 import Qt, QtGui
class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
[...]
def openDialog1(self):
editDialog = Dialog1()
editDialog.exec_()
def openDialog2(self):
editDialog = Dialog2()
editDialog.exec_()
class Dialog1(QtGui.QDialog):
isEdit = False
def __init__(self, studentId=0, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_Dialog1() # change this line
self.ui.setupUi(self)
class Dialog2(QtGui.QDialog):
isEdit = False
def __init__(self, studentId=0, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_Dialog2() # change this line
self.ui.setupUi(self)
Related
I have a project with following structure:
main.py
from . import dialog_util
from . import Ui_MainWindow
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setupUi(self)
self.btn_new.clicked.connect(self.openDialogBox)
def openDialogBox(self):
self.dialog = dialog_util.CustomDialog()
self.dialog.exec()
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWindow = MainWindow()
sys.exit(app.exec())
dialog_util.py
from . import Ui_CustomDialog
class CustomDialog(QDialog, Ui_CustomDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.setWindowFlags(Qt.FramelessWindowHint)
self.setAttribute(Qt.WA_TranslucentBackground)
UI for main window and dialog box are in Ui_MainWindow.py and Ui_CustomDialog.py respectively. How can I add a shadow effect to the dialog box?
I want to change border radius of my PushButton lesson1
Tried to create a class Button with setStyleSheet in __init__ and create an object.
import sys
from pyto import *
from PyQt5 import QtCore, QtGui, QtWidgets
class MyWin(QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.lesson1 = Button()
class Button(QtWidgets.QPushButton):
def __init__(self, parent = None):
super(Button, self).__init__(parent)
self.setStyleSheet('border-radius: 15px;')
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
myapp = MyWin()
myapp.show()
sys.exit(app.exec_())
No errors, but setStyleSheet doesn't work.
The code self.ui.lesson1 = Button() does not replace the self.ui.lesson1 created by Qt Designer, it only causes the new Button() to be assigned to the name self.ui.lesson1. So if you want to set the stylesheet it is not necessary to create another class:
# ...
class MyWin(QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
# self.ui.lesson1 = Button()
self.ui.lesson1.setStyleSheet('border-radius: 15px; background-color: red;')
# ...
I have added the background color to make the radius visible.
I have made a big app importing a big number of dialogs all in main app(main loop).These dialogs import time is pretty long so i made a splash screen but ofcourse splash screen in main loop is blocked from the long time imports.The think i'm not getting is that i cant move the imports in main loop because i get an error from classes creating the ui , witch running as the code is checked from interpreter.
Here the sample code:
from PyQt5 import QtCore, QtGui, QtWidgets, QtPrintSupport
from PyQt5.QtWidgets import QDialog,QWidget,QApplication, QInputDialog, QLineEdit, QFileDialog,QProgressDialog, QMainWindow, QFrame,QSplashScreen
from PyQt5.QtCore import QThread , pyqtSignal,Qt
from PyQt5.QtGui import QIcon,QPainter,QPixmap
#here the slow import dialogs
from ui import Ui_MainWindow,HoverButton
from dialog1 import Ui_Dialog
from dialog2 import Ui_Dialog2
from dialog3 import Ui_dialog3
from dialog4 import Ui_Dialog4
from dialog5 import Ui_dialog5
from dialog6 import Ui_dialog6
#....... and so on
###after class methods###
class Dialog1(QtWidgets.QDialog,Ui_Dialog): #fuel button prompt dialog for inputs
def __init__(self,parent=None):
super(Dialog1, self).__init__(parent)
self.setupUi(self)
class Dialog2(QtWidgets.QDialog,Ui_Dialog2): #all errors dialog
def __init__(self,parent=None):
super(Dialog2, self).__init__(parent)
self.setupUi(self)
class Dialog3(QtWidgets.QDialog,Ui_dialog3): #that might take a while dialog
def __init__(self,parent=None):
super(Dialog3, self).__init__(parent)
self.setupUi(self)
class Dialog4(QtWidgets.QDialog,Ui_Dialog4): #input gross weight dialog
def __init__(self,parent=None):
super(Dialog4, self).__init__(parent)
self.setupUi(self)
class Dialog5(QtWidgets.QDialog,Ui_dialog5): #map viewer specifications dialog
def __init__(self,parent=None):
super(Dialog5, self).__init__(parent)
self.setupUi(self)
#etc
###MAIN GUI###
class mainProgram(QtWidgets.QMainWindow, Ui_MainWindow): #main window
def __init__(self, parent=None):
super(mainProgram, self).__init__(parent)
self.setupUi(self)
self.dialog = Dialog1(self)
self.dialog2 = Dialog2(self)
self.dialog3 = Dialog3(self)
self.dialog3.close()
self.dialog4 = Dialog4(self)
self.dialog5 = Dialog5(self)
self.dialog6 = Dialog6(self)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
splash_pix = QPixmap('loading.jpg')
splash_pix.scaled(200, 400, QtCore.Qt.KeepAspectRatio)
splash = QSplashScreen(splash_pix,Qt.WindowStaysOnTopHint)
splash.setMask(splash_pix.mask())
splash.show()
app.processEvents()
nextGui = mainProgram()
# nextGui.setWindowFlags(QtCore.Qt.FramelessWindowHint)
splash.finish(nextGui)
nextGui.showMaximized()
sys.exit(app.exec_())
Assuming that the only problem is the large number of dialogues and not that each dialogue itself has a task that consumes a lot of time so a possible option is to load each dialog every T ms so in the interim time the QSplashScreen works correctly.
# ...
###MAIN GUI###
class mainProgram(QtWidgets.QMainWindow, Ui_MainWindow):
loadFinished = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(mainProgram, self).__init__(parent)
self.setupUi(self)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self._T_dialogs = iter(
enumerate((Dialog1, Dialog2, Dialog3, Dialog4, Dialog5, Dialog6))
)
self._timer = QtCore.QTimer(self, timeout=self.create_dialogs, interval=100)
self._timer.start()
#QtCore.pyqtSlot()
def create_dialogs(self):
try:
i, T = next(self._T_dialogs)
w = T(self)
setattr(self, "dialog{}".format(i), w)
except StopIteration:
self._timer.stop()
self.showMaximized()
self.loadFinished.emit()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
splash_pix = QtGui.QPixmap("loading.jpg")
splash_pix.scaled(200, 400, QtCore.Qt.KeepAspectRatio)
splash = QtWidgets.QSplashScreen(splash_pix, QtCore.Qt.WindowStaysOnTopHint)
splash.setMask(splash_pix.mask())
splash.show()
nextGui = mainProgram()
nextGui.loadFinished.connect(splash.close)
sys.exit(app.exec_())
So my problem is the following:
I have a program that I created in QT Designer and added some code in Python.
There is an main window and two windows wich appear when you click an button in the window before.
The List Widget is in the second window:
Hope with this picture you can understand what I mean
So now I want to add some Items to my list widget.
def add_number_to_list(self):
self.ui.list_of_numbers.addItem('test')
So I call this function on another place but it didn't happen anything.
If I add an print command, to test if the function works: The print is showed. But nothing appears in the list widget...
What is wrong?
import sys
from PyQt4 import QtGui
import p_design, p_edit_numbers, p_add_number
number_to_add = ''
class Example(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = p_design.Ui_MainWindow()
self.ui.setupUi(self)
self.ui.manually_alarm.clicked.connect(self.alarm)
self.ui.edit_numbers.clicked.connect(self.open_edit_numbers)
def alarm(t1,t2):
#send sms to numbers
print('ALARM!')
def open_edit_numbers(self):
self.test = EditNumbers(self)
self.test.show()
class EditNumbers(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = p_edit_numbers.Ui_MainWindow()
self.ui.setupUi(self)
self.ui.add_number.clicked.connect(self.open_add_number)
### Problem! ###
def add_number_to_list(self):
self.ui.list_of_numbers.addItems('test')
################
def open_add_number(self):
self.t3 = AddNumber(self)
self.t3.show()
class AddNumber(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = p_add_number.Ui_MainWindow()
self.ui.setupUi(self)
self.ui.add.clicked.connect(self.add_number)
def add_number(self):
global number_to_add
editnumbers=EditNumbers()
editnumbers.add_number_to_list()
def main():
app = QtGui.QApplication(sys.argv)
form = Example()
form.show()
sys.exit(app.exec_())
main()
Example code I am using:
import sys
from PyQt5 import QtCore
from PyQt5 import QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.open_about = False
self.openAction = QtWidgets.QAction('About', self)
self.openAction.triggered.connect(self.aboutDialog)
menuBar = self.menuBar()
fileMenu = menuBar.addMenu('&File')
fileMenu.addAction(self.openAction)
self.calendar = QtWidgets.QCalendarWidget(self)
self.setCentralWidget(self.calendar)
def about_state_upd(self, value):
self.open_about = value
def aboutDialog(self):
self._about = AboutDialog(self)
self._about.exec_()
def hideEvent(self, hideEvent):
if self.open_about == True:
self._about.setVisible(False)
def showEvent(self, showEvent):
if self.open_about == True:
if self._about.isHidden() == True:
self._about.setModal(True)
self._about.setVisible(True)
class AboutDialog(QtWidgets.QDialog):
def __init__(self, parent):
super(AboutDialog, self).__init__(parent)
self.setMinimumSize(400, 350)
self.parent().about_state_upd(True)
def closeEvent(self, closeEvent):
self.parent().about_state_upd(False)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
app_window = MainWindow()
app_window.showMaximized()
sys.exit(app.exec_())
This code basically works, but seems very complicated. Is there a simpler / cleaner way to make it so that when the modal QDialog is open, if the QMainWindow is minimized, the QDialog also gets minimized too (and reverse when QMainWindow is restored)?
Code is running on KDE Neon (Kubuntu-based distro).
May be you can use this: http://korbinin.blogspot.fr/search/label/minimize%20button
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MainForm(QDialog):
def __init__(self, fn=None,parent=None):
super(MainForm, self).__init__(parent,\
flags=Qt.WindowMinimizeButtonHint|Qt.WindowMaximizeButtonHint)
Thanks to the people on the PyQt Mailing list, I managed to get a workaround for KDE. Instead of using exec_(), I am just using show() - then I use setDisabled() on QMainWindow to make dialog act in a modal fashion. Here is a (very quick and basic) example for anyone interested:
import sys
from PyQt5 import QtCore
from PyQt5 import QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.openAction = QtWidgets.QAction('About', self)
self.openAction.triggered.connect(self.aboutDialog)
menuBar = self.menuBar()
fileMenu = menuBar.addMenu('&File')
fileMenu.addAction(self.openAction)
self.calendar = QtWidgets.QCalendarWidget(self)
self.setCentralWidget(self.calendar)
def aboutDialog(self):
self._about = AboutDialog(self)
self.setDisabled (True)
self._about.show()
def enableWidgets(self):
self.setDisabled(False)
class AboutDialog(QtWidgets.QDialog):
def __init__(self, parent):
super(AboutDialog, self).__init__(parent)
self.setMinimumSize(400, 350)
def closeEvent(self, parent):
self.parent().enableWidgets()
def changeEvent(self, event):
if event.type() == QtCore.QEvent.WindowStateChange:
if self.windowState() & QtCore.Qt.WindowMinimized:
self.parent().showMinimized()
else:
self.parent().showMaximized()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
app_window = MainWindow()
app_window.showMaximized()
sys.exit(app.exec_())
Link to PyQt Mailing List posts.