I have a program that requires several scripts to work together.
I managed to recreate the situation with a simplified example.
I have a main window (here called the StartTestUIv01) that is launched from another script (here called LaunchTestv01) so that variables and options can be added in my actual script. This main window have buttons that allows the user to open another window (here the BasicGraphUIv01) that itself uses data obtained by another script (here the LaunchBasicGraphv01).
So the script chain becomes like this:
LaunchTestv01 -> StartTestUIv01 -> LaunchBasicGraphv01 -> BasicGraphUIv01
Here is the code for each:
LaunchTestv01
## This will launch StartTestUIv01 with the button
from PyQt5 import QtWidgets
from PyQt5.QtCore import QProcess
from StartTestUIv01 import Ui_MainWindow
class Window(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setupUi(self)
self.startGraph = QtWidgets.QAction('Launch Graph', self)
self.w = None #Set the default value
self.pushButton.clicked.connect(self.LaunchGraph)
def LaunchGraph(self):
if self.w is None:
print("Working")
# self.message("Executing Graph script")
self.w = QProcess()
self.w.finished.connect(self.closeGraph)
self.w.start("python",['LaunchBasicGraphv01.py'])
def closeGraph(self):
print("Closing")
# self.message("Graph script ended")
self.w = None
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec())
StartTestUIv01
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(313, 196)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(30, 20, 261, 121))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 313, 22))
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.pushButton.setText(_translate("MainWindow", "START"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
LaunchBasicGraphv01
## This calculates values to insert in the Graph and displays that Window
from PyQt5 import QtWidgets
import BasicGraphUIv01 as ui
from pyqtgraph.Qt import QtCore
import numpy as np
x = np.arange(0,9)
y = np.random.randint(25, size=(9))
MainWindow = ui.QtWidgets.QMainWindow()
win = ui.Ui_MainWindow()
win.setupUi(MainWindow)
MainWindow.show()
# p0 = win.centralwidget.plot(x,y, pen='b')
p0 = win.graphWidget.plot(x,y, pen='y')
class Window(ui.QtWidgets.QMainWindow, ui.Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setupUi(self)
def update():
y = np.random.randint(25, size=(9))
p0.setData(x,y)
timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)
BasicGraphUIv01
from PyQt5 import QtCore, QtGui, QtWidgets
from pyqtgraph import PlotWidget
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(473, 283)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.graphWidget = PlotWidget(self.centralwidget)
self.graphWidget.setGeometry(QtCore.QRect(10, 10, 451, 211))
self.graphWidget.setObjectName("graphWidget")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 473, 22))
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"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Now the obvious problem is that the chain doesn't start !
It seems that if I'm launching a script that is itself launching another window, it just doesn't happen!
What is the proper way of doing this ?
EDIT: So I got banned because this solved question wasn't good enough or something.
To clarify; I was searching for the proper way of launching a PyQt script from another in the case where a python script is needed in-between to collect data.
Hope this helps.
Solved it!
Thanks to #musicamante for the clues.
I only had to change the two launching scripts as so:
LaunchTestv01
## This will launch StartTestUIv01 with the button
from PyQt5 import QtWidgets
from PyQt5.QtCore import QProcess
from StartTestUIv01 import Ui_MainWindow
class Window(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setupUi(self)
self.startGraph = QtWidgets.QAction('Launch Graph', self)
self.w = None #Set the default value
self.pushButton.clicked.connect(self.LaunchGraph)
def LaunchGraph(self):
if self.w is None:
print("Working")
# self.message("Executing Graph script")
self.w = QProcess()
self.w.finished.connect(self.closeGraph)
self.w.execute('python',['LaunchBasicGraphv01.py'])
def closeGraph(self):
print("Closing")
# self.message("Graph script ended")
self.w = None
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec())
LaunchBasicGraphv01
from PyQt5 import QtWidgets
from BasicGraphUIv01 import Ui_MainWindow
from pyqtgraph.Qt import QtCore
import numpy as np
import sys
app = QtWidgets.QApplication(sys.argv)
x = np.arange(0,9)
y = np.random.randint(25, size=(9))
MainWindow = QtWidgets.QMainWindow()
win = Ui_MainWindow()
win.setupUi(MainWindow)
MainWindow.show()
# p0 = win.centralwidget.plot(x,y, pen='b')
p0 = win.graphWidget.plot(x,y, pen='y')
class Window(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setupUi(self)
def update():
y = np.random.randint(25, size=(9))
p0.setData(x,y)
timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)
if __name__ == '__main__':
sys.exit(app.exec())
Thanks for the help !
Related
I have recreated a problem I am encountering as a minimal example below.
The situation: I have two Qt Designer generated GUI, each being called by their own separated scripts. A third script is meant to collect information from the first script upon the click of a button on the second script. I does not, yet there is no errors.
I have also attempted to solve this by using signals, but these does not seem to communicate between scripts. I provided a simpler version here that doesn't use signals per se.
My question is: How do You get a third script to handle information of two other scripts related to GUIs in pyqt5 ?
Here is the minimal example:
The first GUI script:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(504, 223)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.TypeHere = QtWidgets.QTextEdit(self.centralwidget)
self.TypeHere.setObjectName("TypeHere")
self.verticalLayout.addWidget(self.TypeHere)
self.HelloButton = QtWidgets.QPushButton(self.centralwidget)
self.HelloButton.setObjectName("HelloButton")
self.verticalLayout.addWidget(self.HelloButton)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 504, 22))
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.HelloButton.setText(_translate("MainWindow", "Say hello"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
The second GUI script:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(282, 392)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.pushButton01 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton01.setObjectName("pushButton01")
self.verticalLayout.addWidget(self.pushButton01)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 282, 22))
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.pushButton01.setText(_translate("MainWindow", "PushButton"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
JustSomeTextv01, the script of the first GUI:
from PyQt5 import QtWidgets
from PyQt5.QtCore import QProcess, QThreadPool
from TypingUIv01 import Ui_MainWindow
import JustSomeButtonsv01 as JSB
import sys
class Window(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setupUi(self)
self.HelloButton.pressed.connect(self.openButtons)
self.Display = JSB.Window()
self.ButtonsThread()
def openButtons(self):
self.Display.show()
def ButtonsThread(self):
self.threadpoolbutt = QThreadPool()
self.threadpoolbutt.start(self.runButtons)
def runButtons(self):
self.butt = QProcess()
print("Buttons Running")
self.butt.execute('python',['JustSomeButtonsv01.py'])
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec())
JustSomeButtonsv01, the script of the second GUI:
from PyQt5 import QtWidgets
from PyQt5.QtCore import QProcess, QThreadPool
from ButtonsUIv01 import Ui_MainWindow
# import JustSomeRecordv01 as JSR
import sys
class Window(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setupUi(self)
self.RecordThread()
def RecordThread(self):
self.threadpoolrec = QThreadPool()
self.threadpoolrec.start(self.runRecord)
def runRecord(self):
self.rec = QProcess()
print("Record Running")
self.rec.execute('python',['JustSomeRecordv01.py'])
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
# window.show()
sys.exit(app.exec())
And finally, JustSomeRecordv01, the third script trying to interact with the other two:
from PyQt5 import QtWidgets
import sys
from TypingUIv01 import Ui_MainWindow as JSTWin
from ButtonsUIv01 import Ui_MainWindow as ButtWin
class Record(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
# self.setupUi(self)
app2 = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
self.Win = JSTWin()
self.Win.setupUi(MainWindow)
self.Text = self.Win.TypeHere.toPlainText()
print("Running")
self.Butt = ButtWin()
self.Butt.setupUi(MainWindow)
self.Butt.pushButton01.pressed.connect(self.PrintIT)
def PrintIT(self):
print("Texting")
print(self.Text)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Record()
# window.show()
sys.exit(app.exec())
How to reproduce the problem:
You execute the JustSomeTextv01 script. Press the "Hello Button" and a second window will show up. You type anything in the QTextEdit of the first window and then click the button of the second window. The intent is that this second button would print what You wrote, but it doesn't work.
Thank You for your time,
I managed to do it within the example scripts, but the only solution was to put everything not-GUI into the same script as so:
# To test textbox related function
from PyQt5 import QtWidgets, QtCore
from TypingUIv01 import Ui_MainWindow
from ButtonsUIv01 import Ui_MainWindow as Ui2
import sys
class Window(QtWidgets.QMainWindow, Ui_MainWindow):
PatchSignal = QtCore.pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setupUi(self)
self.HelloButton.pressed.connect(self.openButtons)
self.PatchSignal.connect(self.printIT)
def openButtons(self):
self.w2 = Wintwo()
self.w2.show()
def printIT(self):
self.Text = self.TypeHere.toPlainText()
# print("PRINTING")
print(self.Text)
class Wintwo(QtWidgets.QMainWindow, Ui2):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setupUi(self)
self.pushButton01.pressed.connect(self.Emit)
self.emitter = window
def Emit(self):
# print("EMITTING")
self.emitter.PatchSignal.emit()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec())
It seems sending Signals between scripts is simply not possible in pyqt5!
Somehow this doesn't work in my actual script since "window" isn't recognized, but that's another question for another day.
I tried to design a pyqt gui in when I press "x" will stop run function a counter , what should i do ?
I only know to use the following code
def closeEvent(self,event):
pass
Logic Code
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtCore import *
import sys
import time
from GUI import Ui_MainWindow
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.thread = MyThread(self)
self.thread.trigger.connect(self.textBrowser)
self.thread.start()
def textBrowser(self,a):
self.ui.textBrowser_4.clear()
self.ui.textBrowser_4.append(str(a))
def closeEvent(self,event):
pass
class MyThread(QThread):
trigger = pyqtSignal(str)
def run(self):
a = 0
while True:
a = a + 1
self.trigger.emit(str(a))
time.sleep(1)
if __name__ == "__main__":
app = QtWidgets.QApplication([])
MainWindow = MainWindow()
MainWindow.show()
sys.exit(app.exec_())
GUI Code
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(944, 587)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(30, 310, 181, 41))
self.label_2.setObjectName("label_2")
self.label_4 = QtWidgets.QLabel(self.centralwidget)
self.label_4.setGeometry(QtCore.QRect(30, 20, 141, 21))
self.label_4.setObjectName("label_4")
self.textBrowser_4 = QtWidgets.QTextBrowser(self.centralwidget)
self.textBrowser_4.setGeometry(QtCore.QRect(230, 300, 241, 61))
self.textBrowser_4.setObjectName("textBrowser_4")
MainWindow.setCentralWidget(self.centralwidget)
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.label_2.setText(_translate("MainWindow", "counter"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Add an initiator and an is_running variable in your Thread class like so :
def __init__(self):
self.is_running = True
Then make your loop depend on the truthness of this new variable :
def run(self):
a = 0
while self.is_running:
... your logic here
And finally when you want to exit in closeEvent() :
self.thread.is_running = False
Cheers
In my PyQt5 Application I want to add an Import data window in order to make sure delimiter, skiprows, etc.. is correctly set before trying to import data from a file. Obviously I want this to happen in a separate window. I'm not going to post the full code there, just a quick example which is similar.
In this example there are two windows: the main and the import window. I'd like to send simple text from import window to mainwindow. My problem is I can't really access the created instance of MainWindow, because that happens in main.py.
Here is the code:
main.py
import sys
from logic import MainProgram
from PyQt5 import QtWidgets
def main():
app = QtWidgets.QApplication(sys.argv)
my_interface = MainProgram()
my_interface.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
logic.py
from PyQt5.QtWidgets import QFileDialog
from PyQt5 import QtWidgets, QtCore
from mainwindow_ui import Ui_MainWindow
from import_ui import Ui_ImportPage
class MainProgram(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainProgram, self).__init__(parent)
self.setupUi(self)
self.open.clicked.connect(self.open_import_page)
def open_import_page(self):
self.window1 = ImportPage(self)
self.window1.show()
class ImportPage(QtWidgets.QMainWindow, Ui_ImportPage):
def __init__(self, parent=None):
super(ImportPage, self).__init__(parent)
self.setupUi(self)
self.get.clicked.connect(self.get_text)
def get_text(self):
print(self.line.text()) # <--- this is want I want to send back to MainProgram class
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
my_interface = MainProgram()
my_interface.show()
sys.exit(app.exec_())
mainwindow_ui.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.open = QtWidgets.QPushButton(self.centralwidget)
self.open.setObjectName("open")
self.verticalLayout.addWidget(self.open)
self.line2 = QtWidgets.QLineEdit(self.centralwidget)
self.line2.setPlaceholderText('Recieved from import page')
self.verticalLayout.addWidget(self.line2)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26))
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.open.setText(_translate("MainWindow", "Open import page"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
import_ui.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_ImportPage(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("Import")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.get = QtWidgets.QPushButton('Send data to MainWindow', self.centralwidget)
self.verticalLayout.addWidget(self.get)
self.line = QtWidgets.QLineEdit(self.centralwidget)
self.line.setObjectName("open")
self.line.setPlaceholderText('Type here what you want to send to MainWindow')
self.verticalLayout.addWidget(self.line)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26))
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", "Import"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_ImportPage()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Should I change the structure of the code to achieve this? Is there anything I'm missing?
Thank you for answering.
You can access the ImportPage instance in MainProgram as you create it in that scope. So you should make the necessary connections and get the text:
class MainProgram(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainProgram, self).__init__(parent)
self.setupUi(self)
self.open.clicked.connect(self.open_import_page)
self.window1 = ImportPage(self)
self.window1.get.clicked.connect(self.on_clicked)
def open_import_page(self):
self.window1.show()
def on_clicked(self):
print(self.window1.line.text())
Using Python3 and PyQt5, I want to have a GUI that has a button on it that, when pressed, opens another widget which also has buttons and other controls. In the future, the master GUI will have many buttons that will open many additional widgets. I'm looking at having one widget with an embedded matplotlib.pyplot. At the moment, I am struggling to open a second widget.
Main Program
import sys
from PyQt5 import QtWidgets
from gui import Ui_MainWindow as Ui_MainWindow1
from gui2 import Ui_MainWindow as Ui_MainWindow2
class Window(QtWidgets.QMainWindow, Ui_MainWindow1):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.ui_gui = Ui_MainWindow1()
self.ui_gui.setupUi(self)
self.pb.clicked.connect(self.on_pb_clicked)
self.graph = Graph(self)
def on_pb_clicked(self):
print('pb clicked')
self.graph.show()
class Graph(QtWidgets.QMainWindow, Ui_MainWindow2):
def __init__(self, parent=None):
super(Graph, self).__init__(parent)
self.ui_graph = Ui_MainWindow2()
self.ui_graph.setupUi(self)
if __name__ == "__main__":
#import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow1()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
gui = gui2. Both look like the below.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(282, 219)
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setObjectName("centralWidget")
self.pb = QtWidgets.QPushButton(self.centralWidget)
self.pb.setGeometry(QtCore.QRect(100, 60, 75, 23))
self.pb.setObjectName("pb")
MainWindow.setCentralWidget(self.centralWidget)
self.menuBar = QtWidgets.QMenuBar(MainWindow)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 282, 21))
self.menuBar.setObjectName("menuBar")
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.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pb.setText(_translate("MainWindow", "pb"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
I want to click the button on gui and have the gui2 appear. NB gui will not equal gui2 in the future.
Since Window and Graph inherit from Ui_Window1 and Ui_Window2, respectively, you should call self.setupUi(self) in Window.__init__ and Graph.__init__ instead of creating separate instances of Ui_Window1 and Ui_Window2, i.e.
class Window(QtWidgets.QMainWindow, Ui_MainWindow1):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.setupUi(self)
self.pb.clicked.connect(self.on_pb_clicked)
self.graph = Graph(self)
# just to see the two windows side-by-side
self.move(500, 400)
self.graph.move(self.x()+self.width()+20, self.y())
def on_pb_clicked(self):
print('pb clicked')
self.graph.show()
class Graph(QtWidgets.QMainWindow, Ui_MainWindow2):
def __init__(self, parent=None):
super(Graph, self).__init__(parent)
self.setupUi(self)
The main part of the program should then be something like
if __name__ == "__main__":
#import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = Window()
MainWindow.show()
app.exec()
You use QMetaObject::connectSlotsByName() to enable the automatic calling of the on_pb_clicked() slot.
You do not need to use self.pb.clicked.connect(self.on_pb_clicked)
You need #QtCore.pyqtSlot()
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from gui_1 import Ui_MainWindow as Ui_MainWindow1
from gui_2 import Ui_MainWindow as Ui_MainWindow2
class Graph(QtWidgets.QMainWindow, Ui_MainWindow2):
def __init__(self, parent=None):
super(Graph, self).__init__(parent)
self.setupUi(self)
self.setWindowTitle("window Graph")
self.setGeometry(QtCore.QRect(850, 260, 282, 219))
# self.pb.clicked.connect(self.on_pb_clicked) # ---
#QtCore.pyqtSlot() # +++
def on_pb_clicked(self):
print('pb clicked -> Graph')
class Window(QtWidgets.QMainWindow, Ui_MainWindow1):
def __init__(self):
super().__init__()
self.setupUi(self)
self.setWindowTitle("main Window")
# self.pb.clicked.connect(self.on_pb_clicked) # ---
self.graph = Graph(self)
#QtCore.pyqtSlot() # +++
def on_pb_clicked(self):
print('pb clicked -> "main Window')
self.graph.show()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())
Im first trying to connect a sample cancel button that when clicked will show 'Hello'. Again, thats just a sample. I just like to know how can I connect my ui to the python code that id like to use for the cancel button. I hope someone can help me. Im new to python.
Heres the code:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import pyqtSlot
from A3AMainWindow import Ui_MainWindow
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__()
self.setupUi(self)
self.connect(self.btn_inv_cancel.clicked.connect(self.on_click))
#pyqtSlot()
def on_click(self):
QMessageBox.Information(Self, "hello")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Try it:
from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox
from PyQt5.QtCore import pyqtSlot
from A3AMainWindow import Ui_MainWindow
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setupUi(self)
self.pushButton.clicked.connect(self.on_click)
#pyqtSlot()
def on_click(self):
QMessageBox.information(self, "Announcement.","Hello")
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
A3AMainWindow.py
# 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.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(134, 110, 121, 71))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 400, 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.pushButton.setText(_translate("MainWindow", "PushButton"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())