I have generated my UI with Qt Designer:
like this
I have used the .ui file with the following python code:
Ui_MainWindow, QtBaseClass = uic.loadUiType("vault.ui")
Ui_Credentials, QtBaseClass = uic.loadUiType("credentials.ui")
class Credentials(QMainWindow):
def __init__(self):
super(Credentials, self).__init__()
self.ui = Ui_Credentials()
self.ui.setupUi(self)
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.load.clicked.connect(self.loadVault)
self.ui.next.clicked.connect(self.next)
self.controller = CLI(....)
self.loadVault()
def loadVault(self):
self.ui.vault.clear()
vaults = self.controller.listVaults()
for vault in vaults:
item = QListWidgetItem(vault)
self.ui.vault.addItem(item)
def next(self):
print(self.ui.vault.currentItem().text())
window = Credentials()
window.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
I have tried to change the window when the button next is pressed by created a new class and using a different ui file.
I found this stackoverflow post where this is a similar problem but the code is this post doesn't use a .ui and I did not manage to have a working code with .ui file. I have succeeded to have a new window when I don't use my ui file.
Someone know how can I deal with this ? Is it not adviced to use .ui file?
The solution that I propose is similar to my previous answer, the objective is to change the graphical part so we will use the function setupUI () that generates that part.
When we press the next button, you must change it back with that function.
Ui_MainWindow, _ = uic.loadUiType("vault.ui")
Ui_Credentials, _ = uic.loadUiType("credentials.ui")
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.startMainWindow()
def startMainWindow(self):
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.next.clicked.connect(self.startCredentials)
def startCredentials(self):
self.ui = Ui_Credentials()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
Related
I started out with PyQt5 recently. I wanted to create a custom widget and then insert it into the main window of an application.
The custom Widget:
class ScoreCard(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ScoreCard, self).__init__(parent=parent)
self.setWindowFlags(QtCore.Qt.CustomizeWindowHint)
self.pressing = False
self.init_ui()
self.show()
def init_ui(self):
# Layout in here
And this is the main Application:
from PyQt5.QtWidgets import *
from scorecard import ScoreCard
import sys
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUi()
self.show()
def initUi(self):
self.setGeometry(300,300,800,700)
window_layout = QVBoxLayout()
recent_playcard = ScoreCard()
window_layout.addWidget(recent_playcard)
self.setLayout(window_layout)
if __name__ == "__main__":
app = QApplication(sys.argv)
execute = MainWindow()
sys.exit(app.exec_())
Why is it that whenever I run the main Application, the custom widget appears in another window? I even tried removing the frame and setting the parent to none, but none of that changed this behavior. How do I fix this?
Looks like I mixed up QMainWindow and QDialog I should be using a central widget for the main application instead of setting a layout..
I'm building a plugin for QGIS using PyQGIS and PyQt5. I want to work with multiple windows. After clicking a button, a new window should open. Ideally, it should overlap window 1. After editing in window 2, it should go back to window 1.
My previous code is like this:
class MainWindow(QDialog):
def __init__(self):
super(MainWindow, self).__init__()
loadUi(r"test1.ui", self)
self.button.clicked.connect(self.gotoScreen2)
def gotoScreen2(self):
screen2=Screen2()
widget.addWidget(screen2)
widget.setCurrentIndex(widget.currentIndex()+1)
class Screen2(QDialog):
def __init__(self):
super(Screen2,self).__init__()
loadUi(r"test2.ui", self)
self.pushButton.clicked.connect(self.gotoScreen1)
def gotoScreen1(self):
mainwindow = MainWindow()
widget.addWidget(mainwindow)
widget.setCurrentIndex(widget.currentIndex()+1)
#main
app = QApplication(sys.argv)
widget = QtWidgets.QStackedWidget()
mainwindow = MainWindow()
widget.addWidget(mainwindow)
widget.show()
Building on this, I would like the plugin window to dock on the right in the program. I know that it is possible with the QDockWidget class and addDockWidget (QtCore.Qt.RightDockWidgetArea,...).
But how do I get these class built into my script?
This is my solution (there are now three UIs (windows) that communicate directly with each other.) It works wonderfully in QGIS.
class MainWindow(QDialog):
def __init__(self):
super(MainWindow, self).__init__()
self.gui = loadUi(r"test1.ui", self)
self.button.clicked.connect(self.gotoScreen2)
self.btn_adding.clicked.connect(self.adding)
def gotoScreen2(self):
screen2=Screen2()
widget.setWidget(screen2)
class Screen2(QDialog):
def __init__(self):
super(Screen2,self).__init__()
loadUi(r"test2.ui", self)
self.pushButton.clicked.connect(self.gotoScreen1)
self.pushButton_2.clicked.connect(self.gotoScreen3)
def gotoScreen1(self):
mainwindow = MainWindow()
widget.setWidget(mainwindow)
def gotoScreen3(self):
screen3=Screen3()
widget.setWidget(screen3)
class Screen3(QDialog):
def __init__(self):
super(Screen3,self).__init__()
loadUi(r"test3.ui", self)
self.pushButton.clicked.connect(self.gotoScreen2)
def gotoScreen2(self):
screen2=Screen2()
widget.setWidget(screen2)
widget = QtWidgets.QDockWidget("test")
mainwindow = MainWindow()
widget.setWidget(mainwindow)
#dock on the right side of the screen
iface.addDockWidget(QtCore.Qt.RightDockWidgetArea, widget)
widget.show()
I'm trying to show a new dialog window in my main window when i click on a pushbutton. I'm facing some issues here:
1: when i create a new dialog object inside my mainWindow class, i'll have to use lambda as a slot or else it wont work. the code below works as expected:
class main(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
new = QDialog()
self.ui.pushButton.clicked.connect(lambda: new.show())
self.show()
app = QApplication(sys.argv)
ex = main()
sys.exit(app.exec_())
while going like self.ui.pushButton.clicked.connect(new.show) does not work.
But if the object is created outside the main class it will run without Lambda:
class main(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.show()
app = QApplication(sys.argv)
ex = main()
new = QDialog()
ex.ui.pushButton.clicked.connect(new.show)
sys.exit(app.exec_())
I really don't understand what is happening here. AFAIK using a slot without Lambda should work as long as no arguments are passed to it.
2:
If i wanted to connect the pushbutton to a slot (in which i create a dialog object and run the show() method on it), the dialog window would appear and then immediately disappear, in this case i'll need to do dialoginstance.exec_() instead of dialoginstance.show()
class main(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.pushButton.clicked.connect(lambda: self.showdiag())
self.show()
def showdiag(self):
new = QDialog()
new.exec_() # new.show() wont work!
app = QApplication(sys.argv)
ex = main()
sys.exit(app.exec_())
I'm having a problem with PyQt5 where i have a separate ui file(still a python file not .ui) I'm trying to connect a button which would be located in that file however this doesn't work for me for some reason.
Here's my code.
from PyQt5 import QtCore, QtGui, QtWidgets
from gui import Ui_Form
class Main(QtWidgets.QMainWindow):
def __init__(self):
super(Main, self).__init__()
self.ui = Ui_Form()
self.ui.setupUi(self)
self.show()
self.Ui_Form.exit.clicked.connect(self.handle)
def handle(self):
self.print("hello")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_())
and here's some code from my auto generated gui file using pyuic:
self.exit = QtWidgets.QPushButton(Form)
self.exit.setGeometry(QtCore.QRect(375, 270, 115, 27))
self.exit.setObjectName("exit")
this same exact procedure has worked for me before in Qt4 so i don't see why it wouldn't work here?
You must use the ui attribute to access the button. You must change:
self.Ui_Form.exit.clicked.connect(self.handle)
to:
self.ui.exit.clicked.connect(self.handle)
Note: Typically when using a Widget template, it names that element as a form and the design class as Ui_Form, so you should use QWidget as a class base.
Complete code:
class Main(QtWidgets.QWidget):
def __init__(self):
super(Main, self).__init__()
self.ui = Ui_Form()
self.ui.setupUi(self)
self.show()
self.ui.exit.clicked.connect(self.handle)
def handle(self):
self.print("hello")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Main()
w.show()
sys.exit(app.exec_())
I created 2 windows on QT4.
In Idle i managed to show Window 1 and adding a closing action once button is clicked.
I would like to call and display window 2 by clicking this button. My code is:
import os
import shlex
import sys, Tkinter
#import Converted Python UI File
from W0 import Ui_MainWindow1
If i include from W import Ui_MainWindow2 for calling my 2nd windows, it shows directly my window2 and skip window 1!!
class Main(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
# Button close the window1(would like to show window 2 instead now) .
self.ui.pushButton.clicked.connect(self.close)
def main():
app = QtGui.QApplication(sys.argv)
window = Main()
window.show()
sys.exit(app.exec_())
main()
Try this
from W0 import Ui_MainWindow1
from W import Ui_MainWindow2
class Main1(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.ui = Ui_MainWindow1()
self.ui.setupUi(self)
self.ui.pushButton.clicked.connect(self.close)
class Main2(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.ui = Ui_MainWindow2()
self.ui.setupUi(self)
self.ui.pushButton.clicked.connect(self.close)
def main():
app = QtGui.QApplication(sys.argv)
window1 = Main1()
window1.show()
window2 = Main2()
window2.show()
sys.exit(app.exec_())
main()