How to keep a window open in Python PyQt - python

I am trying to build a python based software. (PYQT based software)
Issue:
My second window keeps closing when right after it opens.
Questions:
Is there something wrong with my code?
how do I fix it?
Note: The second window opens when the start button is clicked.
Here is my code:
class MainWindow(QMainWindow):
switch_window=pyqtSignal(str)
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
#Initialize
self.setGeometry(1000, 300, 1200, 800)
self.setWindowTitle('Sensorlyze')
self.setWindowIcon(QIcon('biosensor.jpg'))
icon = QIcon('biosensor.jpg')
# Add Text
l1= QLabel("Welcome to SensorLyze",self)
l1.move(25, 350)
# l1.setWordWrap(True)
l1.setFont(QFont('Calibri',15))
l1.adjustSize()
l2 = QLabel("A software to simply sensor analytics", self)
l2.move(25, 400)
l2.setFont(QFont('Calibri', 10))
l2.adjustSize()
#Add Buttons
button1 = QPushButton('Start',self)
button1.resize(button1.sizeHint())
button1.clicked.connect(start_clicked)
button1.move(60, 450)
button2 = QPushButton('Exit', self)
button2.resize(button2.sizeHint())
button2.clicked.connect(exit_clicked)
button2.move(240, 450)
stylesheet = """
QMainWindow {
background-image: url("C:/Users/admin/Desktop/Sensorlyze/biosensor.jpg");
background-repeat: no-repeat;
background-position: center;
}
"""
# def switch(self):
# self.switch_window.emit(self.line_edit.text())
def start_clicked():
window=QMainWindow()
window.setGeometry(300, 500, 500, 500)
window.setWindowTitle('Hello')
window.show()
win.hide()
def exit_clicked():
msgBox=QMessageBox()
msgBox.setIcon(QMessageBox.Information)
msgBox.setText("Are you sure you want to exit?")
msgBox.setWindowTitle("Exit Sensorlyze")
msgBox.setStandardButtons(QMessageBox.Ok|QMessageBox.Cancel)
msgBox.buttonClicked.connect(msgButtonClick)
returnValue = msgBox.exec()
if returnValue==QMessageBox.Ok:
exit()
def msgButtonClick(i):
print("Buttonclickedis:",i.text())
def main():
app = QApplication(sys.argv)
app.setStyleSheet(stylesheet) # <---
win=MainWindow()
win.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Am I missing something here? Any help...

Alec answered the question but if you are still unclear here is corrected code.
import sys
from PyQt5.QtWidgets import QMainWindow, QLabel, QPushButton, QMessageBox, QApplication
from PyQt5.QtCore import pyqtSignal, pyqtSlot
from PyQt5.QtGui import QIcon, QFont
class MainWindow(QMainWindow):
switch_window=pyqtSignal(str)
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
#Initialize
self.setGeometry(1000, 300, 1200, 800)
self.setWindowTitle('Sensorlyze')
self.setWindowIcon(QIcon('biosensor.jpg'))
icon = QIcon('biosensor.jpg')
# Add Text
l1= QLabel("Welcome to SensorLyze",self)
l1.move(25, 350)
# l1.setWordWrap(True)
l1.setFont(QFont('Calibri',15))
l1.adjustSize()
l2 = QLabel("A software to simply sensor analytics", self)
l2.move(25, 400)
l2.setFont(QFont('Calibri', 10))
l2.adjustSize()
#Add Buttons
button1 = QPushButton('Start',self)
button1.resize(button1.sizeHint())
button1.clicked.connect(self.start_clicked)
button1.move(60, 450)
button2 = QPushButton('Exit', self)
button2.resize(button2.sizeHint())
button2.clicked.connect(self.exit_clicked)
button2.move(240, 450)
def start_clicked(self):
self.window = QMainWindow()
self.window.setGeometry(300, 500, 500, 500)
self.window.setWindowTitle('Hello')
self.window.show()
# win.hide()
def exit_clicked(self):
msgBox = QMessageBox()
msgBox.setIcon(QMessageBox.Information)
msgBox.setText("Are you sure you want to exit?")
msgBox.setWindowTitle("Exit Sensorlyze")
msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
msgBox.buttonClicked.connect(self.msgButtonClick)
returnValue = msgBox.exec()
if returnValue == QMessageBox.Ok:
exit()
def msgButtonClick(self, i):
print("Buttonclickedis:", i.text())
stylesheet = """
QMainWindow {
background-image: url("C:/Users/admin/Desktop/Sensorlyze/biosensor.jpg");
background-repeat: no-repeat;
background-position: center;
}
"""
# def switch(self):
# self.switch_window.emit(self.line_edit.text())
def main():
app = QApplication(sys.argv)
app.setStyleSheet(stylesheet) # <---
win=MainWindow()
win.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Related

Adding a Background image with PyQt5

I'm trying to add a background using the answers from previous questions.
Sadly they don't work and return errors, either stylesheet, or the = sign, or the """.
I think it may be my location of the image? Is there something special required to store the image perhaps or something else I'm missing?
I've shown an edited down version of the code.
Thanks
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QMainWindow, QPushButton, QAction
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtCore import pyqtSlot
import os
os.chdir(r'C:\Users\Paul Hannell\python_files')
class App(QMainWindow): # Opening Window
def __init__(self):
super().__init__()
self.title = "Timelord Timer PyQt5"
self.left = 70
self.top = 100
self.width = 1170
self.height = 740
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.setWindowIcon(QIcon(r'C:\Users\Paul Hannell\python_files\Timelord.ico'))
self.statusBar().showMessage('Message in Status Bar')
label=QLabel(self)
############################
# Background Image
self.centralwidget = QWidget()
self.setCentralWidget(self.centralwidget)
lay = QHBoxLayout(self.centralwidget)
stylesheet = '''
MainWindow {
background-image: url(r'C:\Users\Paul Hannell\python_files\Running_Around4.png');
background-repeat: no-repeat;
background-position: center;
}
'''
#####################################
mainMenu = self.menuBar()
fileMenu = mainMenu.addMenu('File')
settingsMenu = mainMenu.addMenu('Settings')
resultsMenu = mainMenu.addMenu('Results')
reportsMenu = mainMenu.addMenu('Reports')
infoMenu = mainMenu.addMenu('Info')
newButton=QAction('New', self)
newButton.setStatusTip('New Race')
#newButton.triggered.connect(self.create) #This open new event options
fileMenu.addAction(newButton)
openButton = QAction('Open' , self)
openButton.setStatusTip('Open File')
#openButton.triggered.connect(self.open) # This will open existing
fileMenu.addAction(openButton)
deleteButton=QAction('Delete', self)
deleteButton.setStatusTip('Delete Race')
#deleteButton.triggered.connect(self.create) #This delete existing event.
fileMenu.addAction(deleteButton)
exitButton=QAction('Exit', self)
exitButton.setStatusTip('Exit application')
exitButton.triggered.connect(self.close)
fileMenu.addAction(exitButton)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
Your code is badly indented (and too long) so it's hard to tell, but I see several issues:
it shoud be #MainWindow in the style sheet (you're missing a #)
you need to name the App with this name: self.setObjectName('MainWindow')
you need to use setStyleSheet at some point
the url needs fixing: no quotes nor 'r'; simply the file name (maybe the space in the file name needs escaping, you could try to play with it)
This, for instance, works:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QMainWindow, QPushButton, QAction
class App(QMainWindow): # Opening Window
def __init__(self):
super().__init__()
self.setWindowTitle('hello bg')
self.setObjectName('MainWindow')
stylesheet = '''
#MainWindow {
background-image: url(/home/me/photos/DSC_0001.jpg);
background-repeat: no-repeat;
background-position: center;
}
'''
self.setStyleSheet(stylesheet)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())

Pushbutton is not being responsive

i'm pretty new to python and PyQt5.
My goal is to use a "Push Button" to move to the next widget in the "Stacked Layout". However, it's not being responsive, and it appears that it won't enter the function in order to move on to the next widget.
I have no idea wether its the inheritance i've messed up on, or something else. Any guidance is really appreciated. Thank you!
from PyQt5 import QtCore, QtGui, QtWidgets
class Menu(QtWidgets.QWidget):
def setupUI(self, Main):
Main.setObjectName("Main")
Main.setFixedSize(900, 500)
self.width = 900
self.height = 500
self.setFixedSize(self.width, self.height)
self.menu = QtWidgets.QStackedLayout()
self.welcomeMenu = QtWidgets.QWidget()
self.mainMenu = QtWidgets.QWidget()
self.welcomeUi()
self.menuUi()
self.menu.addWidget(self.welcomeMenu)
self.menu.addWidget(self.mainMenu)
def welcomeUi(self):
#Button for entering portal
self.entrBtn = QtWidgets.QPushButton(self.welcomeMenu)
self.entrBtn.setGeometry(QtCore.QRect(25,150,200,50))
self.entrBtn.setText("To the menu screen!")
#Having welcome text
self.welcomeText = QtWidgets.QLabel(self.welcomeMenu)
self.welcomeText.setGeometry(QtCore.QRect(30, 120, 480, 200))
self.welcomeText.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
self.welcomeText.setText("Welcome!")
def menuUi(self):
self.text = QtWidgets.QLabel(self.mainMenu)
self.text.setGeometry(QtCore.QRect(30, 120, 480, 200))
self.text.setText("test")
class Main(QtWidgets.QMainWindow, Menu):
def __init__(self):
super(Main, self).__init__()
self.setupUI(self)
self.entrBtn.clicked.connect(self.menuWindow)
def menuWindow(self):
self.menu.setCurrentWidget(self.mainMenu)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
m = Main()
sys.exit(app.exec_())
The problem is simple: QLabel is on top of the button so it will block all mouse events. The simple solution is to put QPushButton on QLabel using raise_():
# ...
self.welcomeText.setText("Welcome!")
self.entrBtn.raise_()
But that solves the superficial problem, you have other bigger problem: You should not inherit from 2 QWidget, also the Main is not shown. It is better to rewrite the code as follows:
from PyQt5 import QtCore, QtGui, QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.welcomeMenu = QtWidgets.QWidget()
self.mainMenu = QtWidgets.QWidget()
self.fill_welcomeUi()
self.fill_menuUi()
self.stacked_lay = QtWidgets.QStackedLayout()
self.stacked_lay.addWidget(self.welcomeMenu)
self.stacked_lay.addWidget(self.mainMenu)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
central_widget.setLayout(self.stacked_lay)
self.entrBtn.clicked.connect(self.menuWindow)
self.resize(640, 480)
def menuWindow(self):
self.stacked_lay.setCurrentWidget(self.mainMenu)
def fill_welcomeUi(self):
#Button for entering portal
self.entrBtn = QtWidgets.QPushButton(self.welcomeMenu)
self.entrBtn.setGeometry(QtCore.QRect(25,150,200,50))
self.entrBtn.setText("To the menu screen!")
#Having welcome text
self.welcomeText = QtWidgets.QLabel(self.welcomeMenu)
self.welcomeText.setGeometry(QtCore.QRect(30, 120, 480, 200))
self.welcomeText.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
self.welcomeText.setText("Welcome!")
self.entrBtn.raise_()
def fill_menuUi(self):
self.text = QtWidgets.QLabel(self.mainMenu)
self.text.setGeometry(QtCore.QRect(30, 120, 480, 200))
self.text.setText("test")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
m = MainWindow()
m.show()
sys.exit(app.exec_())

Calculate a value and update this in a GUI python, without block my gui

I have a simple application, one label and 2 buttons ( start increment, stop increment), write in pyqt5.
When I pres start button want to see in ui, value update in real time and have acces at stop button.
Now when I press start button, not see an update in UI and when try to press on stop receive not responding.
One solution probably is Threads, but I don't understand how work thread's in Python
import sys
import time
from PyQt5 import QtWidgets, Qt
from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QLineEdit
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class MainWindow(QMainWindow):
running = True
value = 1
def __init__(self):
QMainWindow.__init__(self)
self.setMinimumSize(QSize(600, 500))
self.setMaximumSize(QSize(600, 500))
self.setWindowTitle("Demo app")
QApplication.setStyle("fusion")
self.move(1000, 200)
self.button_start = QPushButton('Start', self)
self.button_start.setFixedHeight(40)
self.button_start.setFixedWidth(170)
self.button_start.move(10, 215)
self.button_start.clicked.connect(self.start_function)
self.update()
self.button_stop = QPushButton('Stop', self)
self.button_stop.setFixedHeight(40)
self.button_stop.setFixedWidth(170)
self.button_stop.move(200, 215)
self.button_stop.setDisabled(True)
self.button_stop.clicked.connect(self.stop_function)
self.update()
self.label = QLineEdit(self)
self.label.move(10, 170)
self.label.resize(170, 40)
self.label.setEnabled(False)
self.label.setAlignment(Qt.AlignCenter)
self.label.setStyleSheet("color: red;")
self.update()
def start_function(self):
self.button_start.setDisabled(True)
self.button_stop.setDisabled(False)
while self.running is True:
self.value += 1
self.label.setText(str(self.value))
print("Value: ", self.value)
time.sleep(1)
def stop_function(self):
self.running = False
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
mainWin.update()
sys.exit(app.exec_())
Maybe I'm a little late and you figured out yourself how to solve this problem, but for those with the same issue:
You can't set a loop in the GUI thread for this purpose, It will block the GUI thread from doing anything. Instead, You can use QTimer to schedule something to run at a later point in time. You can use it to implement something like a stopwatch.
Here is a functional minimal example:
import sys
import time
from PyQt5 import QtWidgets, Qt
from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QLineEdit
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class MainWindow(QMainWindow):
value = 0
def __init__(self):
QMainWindow.__init__(self)
self.setMinimumSize(QSize(600, 500))
self.setMaximumSize(QSize(600, 500))
self.setWindowTitle("Demo app")
QApplication.setStyle("fusion")
self.move(1000, 200)
self.button_start = QPushButton('Start', self)
self.button_start.setFixedHeight(40)
self.button_start.setFixedWidth(170)
self.button_start.move(10, 215)
self.button_start.clicked.connect(self.start_function)
self.update()
self.button_stop = QPushButton('Stop', self)
self.button_stop.setFixedHeight(40)
self.button_stop.setFixedWidth(170)
self.button_stop.move(200, 215)
self.button_stop.setDisabled(True)
self.button_stop.clicked.connect(self.stop_function)
self.update()
self.label = QLineEdit(self)
self.label.move(10, 170)
self.label.resize(170, 40)
self.label.setEnabled(False)
self.label.setAlignment(Qt.AlignCenter)
self.label.setStyleSheet("color: red;")
self.label.setText(str(self.value))
self.update()
self.workTimer = QTimer()
self.workTimer.setInterval(1000)
self.workTimer.timeout.connect(self.increase_value)
def start_function(self):
self.workTimer.start()
self.button_start.setDisabled(True)
self.button_stop.setDisabled(False)
def stop_function(self):
self.workTimer.stop()
self.button_start.setDisabled(False)
self.button_stop.setDisabled(True)
def increase_value(self):
self.value += 1
self.label.setText(str(self.value))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
mainWin.update()
sys.exit(app.exec_())

Open a new window when the button is clicked || PyQt5

I know this question have been asked multiple times. But I can't understand with the existing examples.
I have a code which creates a window with a button called 'start'. I want the app to close the current window and open a new window when the 'start' button is clicked. The new window has to be a blank window.
Any help is much appreciated.
The code is as follows:
import sys
from PyQt5 import QtGui
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton,
QToolTip, QMessageBox, QLabel
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.title = "First Window"
self.top = 100
self.left = 100
self.width = 680
self.height = 500
self.pushButton = QPushButton("Start", self)
self.pushButton.move(275, 200)
self.pushButton.setToolTip("<h3>Start the Session</h3>")
self.main_window()
def main_window(self):
self.label = QLabel("Manager", self)
self.label.move(285, 175)
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
self.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
sys.exit(app.exec())
Try it:
import sys
from PyQt5 import QtGui
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QToolTip, QMessageBox, QLabel)
class Window2(QMainWindow): # <===
def __init__(self):
super().__init__()
self.setWindowTitle("Window22222")
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.title = "First Window"
self.top = 100
self.left = 100
self.width = 680
self.height = 500
self.pushButton = QPushButton("Start", self)
self.pushButton.move(275, 200)
self.pushButton.setToolTip("<h3>Start the Session</h3>")
self.pushButton.clicked.connect(self.window2) # <===
self.main_window()
def main_window(self):
self.label = QLabel("Manager", self)
self.label.move(285, 175)
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
self.show()
def window2(self): # <===
self.w = Window2()
self.w.show()
self.hide()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
sys.exit(app.exec())

Creating a pop-up window from custom pushbutton python

I am trying to create a pop-up window that gets popped-up from pressing on a QPushButton. However, I have a separate QPushButton class that I would like to use. I can't seem to get it working. Anything I am doing wrong?
#import ... statements
import sys
# from ... import ... statements
from PyQt5.QtWidgets import (QMainWindow, QApplication, QPushButton, QGridLayout, QWidget, QHBoxLayout, QLabel,
QVBoxLayout)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont, QFontDatabase, QColor, QPalette, QMovie
from skimage import transform, io
# Create main window of the widget
class MainWindow(QWidget):
def __init__(self):
super().__init__()
#Set a title inside the widget
self.titleLabel = QLabel()
titleText = "some title text"
self.titleLabel.setText(titleText)
# Give the label some flair
self.titleLabel.setFixedWidth(1000)
self.titleLabel.setAlignment(Qt.AlignCenter)
QFontDatabase.addApplicationFont(link_to_custom_font)
font = QFont()
font.setFamily("custom_font_name")
font.setPixelSize(50)
self.titleLabel.setFont(font)
# Set first button - The "Yes" Button
self.btn1 = myButtonOne("Yes")
#Initialize GUI
self.layoutGUI()
self.initUI()
def initUI(self):
self.fromleft = 200
self.fromtop = 100
self.w = 1000
self.h = 500
self.setGeometry(self.fromleft, self.fromtop, self.w, self.h)
def layoutGUI(self):
hbox = QHBoxLayout()
hbox.setSpacing(20)
hbox.addWidget(self.btn1)
vbox = QVBoxLayout()
vbox.addWidget(self.titleLabel)
vbox.addLayout(hbox)
self.setLayout(vbox)
class myButtonOne(QPushButton):
def __init__(self, parent=None):
super(myButtonOne, self).__init__(parent)
# Set maximum border size
imSize = io.imread(imagePath)
imHeight = imSize.shape[1]
imWidth = imSize.shape[0]
# Set first button - The "Yes" Button
yesImage = someImagePath
self.setStyleSheet("background-image: url(" + yesImage + ");"
"background-repeat: none;"
"background-position: center;"
"border: none")
self.setFixedSize(imWidth, imHeight)
self.clicked.connect(self.buttonOnePushed)
def buttonOnePushed(self):
textView().show()
def enterEvent(self, event):
newImage = someOtherImagePath
self.setStyleSheet("background-image: url("+newImage+");"
"background-repeat: none;"
"background-position: center;"
"border: none")
def leaveEvent(self, event):
newImage = someImagePath
self.setStyleSheet("background-image: url("+newImage+");"
"background-repeat: none;"
"background-position: center;"
"border: none")
class textView(QWidget):
def __init(self):
textView.__init__()
theText = QLabel()
#define sizes
self.height = 550
self.width = 250
# Open QWidget
self.initUI()
# Set the text for the QLabel
someText = "Some Text for the label"
theText.setText(someText)
def initUI(self):
self.show()
# Start GUI
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
So, I am trying to keep the QPushButton classes separate, so that I can customize them. I would like to keep it like that, especially to keep it clean and readable.
First off - please read: How to create a Minimal, Complete, and Verifiable example. I had a lot of work minimizing your code, which wasted a good amount of my time.
Nonetheless, here is a minimal working code, with your own button class:
import sys
from PyQt5.QtWidgets import QApplication, QPushButton, QWidget, QLabel, QVBoxLayout
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.titleLabel = QLabel( "some label text" )
self.btn1 = myButtonOne( "button text" )
hbox = QVBoxLayout() # one vertical box seemed enough
hbox.addWidget( self.titleLabel )
hbox.addWidget( self.btn1 )
self.setLayout( hbox )
class myButtonOne(QPushButton):
def __init__(self, text, parent=None):
super(myButtonOne, self).__init__(text, parent)
self.clicked.connect(self.buttonOnePushed)
# add your customizations here
def buttonOnePushed (self) :
self.t = textView()
self.t.show()
class textView(QWidget):
def __init__(self):
super(textView, self).__init__()
self.theText = QLabel('test', self )
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
What have you done wrong in your code?
using textView().show() creates a local version of you textView-class and show()'s it:
def buttonOnePushed(self):
textView().show()
But, show() means that the code continues, where the end of your code comes, which results in cleaning up the locals. End - it's just shown for a microsecond.
def buttonOnePushed (self) :
self.t = textView()
self.t.show()
The code above stores the var as instance-attribute of the button, which is not cleaned up.
Furthermore you misspelled the init in your textView-class:
"__init" should be __init__ - else it is not called when using the constructor:
class textView(QWidget):
def __init(self):
textView.__init__()
Finally, you wanted to called show() twice:
in your textView-init you call initUI() which is calling show()
you calling show manually with textView().show()
Hope this helps! I did not include your personal style adjustments for readability.

Categories

Resources