PyQt QScrollArea not scrolling - layout

I want to put some elements of my UI in a scroll area as there can be a lot of them. I tried the following peice of code, but the area just keeps growing as I put more elements on it.
In the first part I set up a scroll area, a widget and a layout. I apply the layout to the widget and I set the widget to the scrollarea. Then I fill in my layout in an external function. The button under all of it allows to fill more elements in the layout.
scrollRow = QtGui.QScrollArea()
scrollRow.setMaximumSize(600, 400)
self.rowAssetWidget = QtGui.QWidget()
self.rowAssetLayout = QtGui.QGridLayout()
self.rowAssetLayout.setSpacing(20)
self.rowAssetWidget.setLayout(self.rowAssetLayout)
scrollRow.setWidget(self.rowAssetWidget)
#self.mainLayout.addLayout(self.rowAssetLayout, 2, 0)
self.mainLayout.addWidget(self.rowAssetWidget, 2, 0)
self.assetRow()
self.addAssetRowBtn = QtGui.QPushButton("+")
self.addAssetRowBtn.setFixedSize(20, 20)
self.mainLayout.addWidget(self.addAssetRowBtn, 3, 0)
self.connect(self.addAssetRowBtn, QtCore.SIGNAL("clicked()"), self.addAssetRow)
My elements appear fine, but it is not scrolling. Any idea ?

import sys
from PyQt4 import QtGui,QtCore
class LayoutTest(QtGui.QWidget):
def __init__(self):
super(LayoutTest, self).__init__()
self.horizontalLayout = QtGui.QVBoxLayout(self)
self.scrollArea = QtGui.QScrollArea(self)
self.scrollArea.setWidgetResizable(True)
self.scrollAreaWidgetContents = QtGui.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 380, 280))
self.horizontalLayout_2 = QtGui.QHBoxLayout(self.scrollAreaWidgetContents)
self.gridLayout = QtGui.QGridLayout()
self.horizontalLayout_2.addLayout(self.gridLayout)
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.add_button = QtGui.QPushButton("Add Items")
self.horizontalLayout.addWidget(self.scrollArea)
self.horizontalLayout.addWidget(self.add_button)
self.connect(self.add_button, QtCore.SIGNAL("clicked()"), self.addButtons)
self.setGeometry(300, 200, 400, 300)
def addButtons(self):
for i in range(0, 50):
self.r_button = QtGui.QPushButton("Button %s " % i)
self.gridLayout.addWidget(self.r_button)
def run():
app = QtGui.QApplication(sys.argv)
ex = LayoutTest()
ex.show()
sys.exit(app.exec_())
if __name__ == "__main__":
run()
I know its too late to answer for this question, but here is a working example and you missing the parent layout.

Yeah. My mistake was on my end is that PyQT Designer set a .setGeometry() for the ScrollAreaWidgetContents widget within the QScrollArea. My solution was to use instead the .setMinimumHeight( ) and .setMinimumWidth( ).
Remove this:
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 380, 280))
And replace with:
self.scrollAreaWidgetContents.setMinimumWidth(380)
self.scrollAreaWidgetContents.setMinimumHeight(280)

Related

Why widgets are not displayed in PyQt6?

I am implementing an app through a class that has a QMainWindow member. I call two functions (create_side_menu, create_mixing_window) that display dynamically added widgets inside a bigger widget, which is added to the QMainWindow. The first function works, while the second does not, even though very similar to the first. Can you help me solving this problem?
Update: I modified the code as it appears now in the question, and debugging it seems that the problem is at line 78 (wid = ChannelModifier(af)) where it throws the error: "QWidget: Must construct a QApplication before a QWidget" even though the application is defined in MainWindow class init
Notes:
ChannelModifier is a custom class deriving from QWidget
class MainWindow:
def __init__(self):
self.QListWidgetLeft = None # QListWidget
self.QListWidgetRight = None # QListWidget
self.central_widget = None
self.manager = Manager.get_instance()
self.app = QApplication(sys.argv)
self.window = QMainWindow()
self.set_window()
self.set_menu_bar()
self.sb = self.window.statusBar()
self.sb.showMessage(f"ready to remix")
self.window.show()
sys.exit(self.app.exec())
def set_window(self):
# self.window.setFixedSize(1080, 720)
self.window.setGeometry(50, 50, 1500, 1000)
self.window.setWindowIcon(QIcon("assets/icon.png"))
# self.window.setStyleSheet('background-color: #b7dfeb')
self.window.setStyleSheet('background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 '
'rgba(165, 165, 247, 255), stop:1 rgba(255, 255, 255, 255))')
self.window.setWindowTitle("Music Remixes and Mashups")
self.create_central_widget()
def create_central_widget(self):
self.central_widget = QWidget()
self.window.setCentralWidget(self.central_widget)
self.central_widget.setLayout(QHBoxLayout())
self.create_side_menu()
self.create_mixing_window()
def create_side_menu(self):
widget = QWidget()
vbox = QVBoxLayout()
scrollbar = QScrollBar()
scrollbar.setMaximum(100)
scrollbar.setStyleSheet("background-color: rgb(60,60,90); width: 14px; border-radius 0px;")
scrollbar.sliderMoved.connect(scrollbar.value)
self.QListWidgetLeft = QListWidget()
self.QListWidgetLeft.setSpacing(5)
self.QListWidgetLeft.setVerticalScrollBar(scrollbar)
self.QListWidgetLeft.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
pr = self.manager.get_current_project()
if pr:
for af in pr.get_audio_files():
self.add_audiofile_to_side_menu(af)
vbox.addWidget(self.QListWidgetLeft)
widget.setLayout(vbox)
widget.setFixedWidth(230)
widget.setStyleSheet('background-color:white')
self.central_widget.layout().addWidget(widget)
def add_audiofile_to_side_menu(self, af: AudioFile):
if self.QListWidgetLeft is None:
self.QListWidgetLeft = QListWidget()
label = QLabel()
label.setFixedWidth(180)
label.setFixedHeight(180)
if af.get_thumb_path():
label.setPixmap(QPixmap(af.get_thumb_path()))
else:
label.setText(af.get_title())
item = QListWidgetItem(self.QListWidgetLeft)
item.setSizeHint(label.size())
self.QListWidgetLeft.addItem(item)
self.QListWidgetLeft.setItemWidget(item, label)
def create_mixing_window(self): # TODO: it doesn't work
mixing_window = QWidget()
grid = QGridLayout()
pr = self.manager.get_current_project()
if pr:
for af in pr.get_audio_files():
# self.add_channel_modifier_to_mixing_menu(af)
wid = ChannelModifier(af)
grid.addWidget(wid)
# grid.addWidget(self.QListWidgetRight)
mixing_window.setLayout(grid)
mixing_window.setStyleSheet('background-color:white')
self.central_widget.layout().addWidget(mixing_window)
def add_channel_modifier_to_mixing_menu(self, af: AudioFile):
if self.QListWidgetRight is None:
self.QListWidgetRight = QListWidget()
wid = ChannelModifier(af)
item = QListWidgetItem(self.QListWidgetRight)
# item.setSizeHint(wid.size())
self.QListWidgetRight.addItem(item)
self.QListWidgetRight.setItemWidget(item, wid)
With the limited amount of code you have included it is difficult to say if this is what is causing your problem or not, but one issue I see is that you aren't using the correct signature in your calls to addWidget() on your grid layout.
With grid layout you have to specify the column and row you want the widget to occupy when adding them to the layout.
def create_mixing_window(self): # TODO: it doesn't work
mixing_window = QWidget()
grid = QGridLayout()
pr = self.manager.get_current_project()
if pr:
for af in pr.get_audio_files():
self.add_channel_modifier_to_mixing_menu(af)
wid = ChannelModifier(af)
grid.addWidget(wid,0,0) # row 0; column 0
grid.addWidget(self.QListWidgetRight, 0, 1) # row 0; column 1
mixing_window.setLayout(grid)
mixing_window.setStyleSheet('background-color:white')
self.central_widget.layout().addWidget(mixing_window)

Aligning QGridLayout rows in QScrollArea

I am trying to create a lot of rows in a PyQt5 grid widget, but they try to expand as much as they can. How can I set a fixed cell height? They are represented like this:
But I would like them to stick at the top, ordered like this:
Code:
name = QtWidgets.QLabel()
name.setText(str(ui.nombre.toPlainText()) + "({}, {}, {})".format(do, cota, alejamiento))
borrar = QtWidgets.QPushButton()
borrar.setText("X")
borrar.clicked.connect(self.borrar)
ui.elementos.addWidget(name, self.num_elementos, 0, 1, 1)
ui.elementos.addWidget(borrar, self.num_elementos, 1, 1, 1)
self.num_elementos += 1
self.update()
print(self.puntos)
And the elementos widget is created in other class:
self.scroll = QtWidgets.QScrollArea(self.gridLayoutWidget_2)
self.scroll_widget = QtWidgets.QWidget()
self.scroll_widget.resize(200, 700)
self.elementos = QtWidgets.QGridLayout()
self.scroll_widget.setLayout(self.elementos)
self.scroll.setWidget(self.scroll_widget)
self.Punto.addWidget(self.scroll, 4, 0, 1, 3)
You need to add a stretchable space beneath the rows of widgets, so that it pushes them all up to the top. One way to do this is to put another widget inside the scroll-widget, and then use a vertical layout to add the spacer. It will also help if you make the scroll-widget resizable, otherwise the rows will start to get squashed if too many are added.
Below is a demo that implements all that. Hopefully it should be clear how you can adapt this to work with your own code:
import sys
from PyQt5 import QtCore, QtWidgets
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.scroll = QtWidgets.QScrollArea()
self.scroll.setWidgetResizable(True)
self.scroll_widget = QtWidgets.QWidget()
self.scroll_widget.setMaximumWidth(200)
self.elementos_widget = QtWidgets.QWidget()
vbox = QtWidgets.QVBoxLayout(self.scroll_widget)
vbox.setContentsMargins(0, 0, 0, 0)
vbox.addWidget(self.elementos_widget)
vbox.addStretch()
self.elementos = QtWidgets.QGridLayout()
self.elementos_widget.setLayout(self.elementos)
self.scroll.setWidget(self.scroll_widget)
self.button = QtWidgets.QPushButton('Add')
self.button.clicked.connect(self.crear_punto)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.scroll)
layout.addWidget(self.button)
def crear_punto(self):
num_elementos = self.elementos.rowCount()
name = QtWidgets.QLabel()
name.setText('FOO %s' % num_elementos)
borrar = QtWidgets.QPushButton()
borrar.setText('X')
self.elementos.addWidget(name, num_elementos, 0)
self.elementos.addWidget(borrar, num_elementos, 1)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 100, 300, 500)
window.show()
sys.exit(app.exec_())

Add left panel to bottom and top panel

The code I have makes a top and bottom pannel I need to add a left panel as seem in the picture below:
My current code is:
import wx
class MainFrame(wx.Frame):
def __init__(self,parent):
wx.Frame.__init__(self,parent,title="myapp",size=(800,580))
self.split_win =wx.SplitterWindow(self)
self.top = wx.Panel(self.split_win ,style = wx.SUNKEN_BORDER)
self.bottom = wx.Panel(self.split_win ,style = wx.SUNKEN_BORDER)
self.split_win.SplitHorizontally(self.top,self.bottom,450)
st1 = wx.StaticText(self.bottom, -1, "This is an example of static text", (20, 10))
self.bottom.SetBackgroundColour('white')
app = wx.App()
frame=MainFrame(None).Show()
app.MainLoop()
I need s left panel like the one in the picture where I can add a button and combobox.
I would also like to know if it is possible to have bottom and left and top panel without split?
Thanks for the help
Welcome to sizers in wx.python
Start here: https://wxpython.org/Phoenix/docs/html/sizers_overview.html
import wx
class MainFrame(wx.Frame):
def __init__(self,parent):
wx.Frame.__init__(self,parent,title="myapp",size=(800,580))
self.top = wx.Panel(self, style = wx.SUNKEN_BORDER)
self.bottom = wx.Panel(self ,style = wx.SUNKEN_BORDER)
self.left = wx.Panel(self ,style = wx.SUNKEN_BORDER, size = (150,-1))
st1 = wx.StaticText(self.bottom, -1, "This is an example of static text")
st2 = wx.StaticText(self.left, -1, "Left Panel", (20, 10))
self.bottom.SetBackgroundColour('white')
sizer1 = wx.BoxSizer(wx.VERTICAL)
sizer1.Add(self.top,1,wx.EXPAND,5)
sizer1.Add(self.bottom,1,wx.EXPAND,5)
sizer2 = wx.BoxSizer(wx.HORIZONTAL)
sizer2.Add(self.left,0,wx.EXPAND,5)
sizer2.Add(sizer1,1,wx.EXPAND,5)
self.SetSizer(sizer2)
app = wx.App()
frame=MainFrame(None).Show()
app.MainLoop()

wx python image refresh on Windows

I have an application that involves displaying multiple images. This works as I would expect on linux, but on Windows there is an annoying flash as the images are painted. This is best seen as a little square in the top left-hand corner of the screen where a flash of colour appears. Am I not approaching this requirement in the right way? Or is there some fix I should be applying to overcome the Windows effect? Or is it just my version on Windows (I only have one to test it: Windows 7 Ultimate)?
I have tried Freeze and Thaw in refresh_sizer_cell but it didn't behave as I expected
import wx
class ImageSizer(wx.Frame):
BACKGROUND_COLOUR = (246, 244, 242)
def __init__(self, parent, title):
super(ImageSizer, self).__init__(parent, title=title)
self.main_sizer = wx.GridBagSizer()
self.SetSizer(self.main_sizer)
cmd_reset = wx.Button(self, label='Reset')
cmd_reset.Bind(wx.EVT_BUTTON, self.on_cmd_reset_click)
cmd_cancel = wx.Button(self, label='Cancel')
cmd_cancel.Bind(wx.EVT_BUTTON, self.on_cmd_cancel_click)
self.main_sizer.Add((400, 0), pos=(0, 0), span=(1, 2)) # dummy to position Available
self.main_sizer.Add((0, 100), pos=(1, 0), span=(1, 1)) # dummy to position Buttons
self.main_sizer.Add(cmd_reset, pos=(2, 2), flag=wx.LEFT | wx.TOP, border=10)
self.main_sizer.Add(cmd_cancel, pos=(2, 3), flag=wx.RIGHT | wx.BOTTOM | wx.TOP | wx.ALIGN_RIGHT, border=10)
self.SetBackgroundColour(self.BACKGROUND_COLOUR)
self.shape_types = {'available': 0, 'selected': 1}
self.available_shapes = []
self.selected_shapes = []
self.initialise()
self.Center()
self.Fit()
self.Show()
def initialise(self):
self.available_shapes = ['square', 'circle', 'triangle', 'cross']
self.selected_shapes = []
self.display_images()
def display_images(self):
available_sizer = ShapeSizer(self, self.available_shapes, self.shape_types['available'])
self.refresh_sizer_cell(self.main_sizer, available_sizer, (1, 2), (1, 3))
selected_sizer = ShapeSizer(self, self.selected_shapes, self.shape_types['selected'])
self.refresh_sizer_cell(self.main_sizer, selected_sizer, (1, 1), (2, 1))
self.Layout()
#staticmethod
def refresh_sizer_cell(sizer, item, pos, span, flag=wx.ALL, border=10):
old_item = sizer.FindItemAtPosition(pos)
if old_item is not None and old_item.IsWindow():
old_item.GetWindow().Hide()
sizer.Detach(old_item.GetWindow())
sizer.Add(item, pos=pos, span=span, flag=flag, border=border)
def on_available_shape_double_click(self, event):
shape = event.GetEventObject().GetName()
self.available_shapes.remove(shape)
self.selected_shapes.append(shape)
self.display_images()
def on_selected_shape_double_click(self, event):
shape = event.GetEventObject().GetName()
self.selected_shapes.remove(shape)
self.available_shapes.append(shape)
self.display_images()
def on_cmd_reset_click(self, event):
self.initialise()
def on_cmd_cancel_click(self, event):
self.Destroy()
class ShapeSizer(wx.Panel):
def __init__(self, parent, shapes, shape_type):
wx.Panel.__init__(self, parent, id = wx.ID_ANY)
if shape_type == parent.shape_types['available']:
size = 40
action = parent.on_available_shape_double_click
else:
size = 80
action = parent.on_selected_shape_double_click
panel_sizer = wx.BoxSizer(wx.HORIZONTAL)
shapes.sort()
for shape in shapes:
bitmap = wx.Bitmap(shape + '.png', wx.BITMAP_TYPE_PNG)
bitmap = self.scale_bitmap(bitmap, size, size)
img = wx.StaticBitmap(self, wx.ID_ANY, bitmap, name=shape)
img.Bind(wx.EVT_LEFT_DCLICK, action)
panel_sizer.Add(img, flag=wx.RIGHT, border=10)
self.SetSizer(panel_sizer)
#staticmethod
def scale_bitmap(bitmap, width, height):
image = wx.ImageFromBitmap(bitmap)
image = image.Scale(width, height, wx.IMAGE_QUALITY_HIGH)
result = wx.BitmapFromImage(image)
return result
if __name__ == '__main__':
app = wx.App()
ImageSizer(None, title='Image Sizer')
app.MainLoop()
Here are the images:
Every time you double click on a shape your program is creating new instances of the panels and their wx.StaticBitmap widgets, it is these new instances you are seeing as they are initially created with a small default size and then they are repositioned by the next layout. Instead you should reorganize things so you only create the set of panels once, and as the state of the shape selections changes you can have the existing panels update themselves. That will greatly reduce the flicker visible to the user.

How to add TextEdit, Labels and Buttons that move when Window Size is moved using PyQt?

I am new to PyQt, but for the past days I was trying to create a GUI which has labels, TextEdit and buttons which move when the Window size is moved (minimized or enlarged), I tried doing it so but the Buttons get stuck in the top left corner while the labels and TextEdit completely don't show up on the form, Please do help . Here is a snippet of my codes
import sys
from PyQt4 import QtGui, QtCore
class Window(QtGui.QMainWindow, QtGui.QWidget):
` def __init__(self):
super(Window, self).__init__()
self.setGeometry(50, 50, 500, 300)
self.setWindowTitle("PTE")
self.setWindowIcon(QtGui.QIcon('.png'))
self.center()
# Adding Menu to the GUI
quitAction = QtGui.QAction(QtGui.QIcon('exit.png'), "&Quit", self)
quitAction.setShortcut("Ctrl+Q")
quitAction.setStatusTip('Exit Application')
quitAction.triggered.connect(self.close_application)
undoAction = QtGui.QAction(QtGui.QIcon('undo.png'), "&Undo", self)
undoAction.setShortcut("Ctrl+Z")
undoAction.triggered.connect(self.close_application)
aboutAction = QtGui.QAction("&About PTE...", self)
self.statusBar()
#Actual Main Menu with options
mainMenu = self.menuBar()
fileMenu = mainMenu.addMenu('&File')
fileMenu.addAction(quitAction)
fileMenu = mainMenu.addMenu('&Edit')
fileMenu.addAction(undoAction)
fileMenu = mainMenu.addMenu('&Help')
fileMenu.addAction(aboutAction)
self.home()
#Centering Window on the screen
def center(self):
gui = self.frameGeometry()
cp = QtGui.QDesktopWidget().availableGeometry().center()
gui.moveCenter(cp)
self.move(gui.topLeft())
def home(self):
#Buttons
qbtn = QtGui.QPushButton('Quit', self)
qbtn.clicked.connect(self.close_application)
rbtn = QtGui.QPushButton("Run", self)
rbtn.clicked.connect(self.close_application)
hbox = QtGui.QHBoxLayout()
hbox.addStretch(1)
hbox.addWidget(qbtn)
hbox.addWidget(rbtn)
vbox = QtGui.QVBoxLayout()
vbox.addStretch(1)
vbox.addLayout(hbox)
self.setLayout(vbox)
self.show()
#Labels and TextBox
Intervals = QtGui.QLabel('Number of intervals (0<=20) :')
Timesteps = QtGui.QLabel('Number of time steps (<=1000) : ')
IntervalsEdit = QtGui.QLineEdit()
TimestepsEdit = QtGui.QLineEdit()
grid = QtGui.QGridLayout()
grid.setSpacing(2)
grid.addWidget(Intervals, 1, 0)
grid.addWidget(IntervalsEdit, 1, 1)
grid.addWidget(Timesteps, 2, 0)
grid.addWidget(TimestepsEdit, 2, 1)
self.setLayout(grid)
self.show()
#What to display when the app is closed
def close_application(self):
#Popup message before closing the application in Binary
choice = QtGui.QMessageBox.question(self, 'Message',"Are you sure you want to exit?",
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No )
if choice == QtGui.QMessageBox.Yes:
print(" Until Next Time")
sys.exit()
else:
pass
def run():
app = QtGui.QApplication(sys.argv)
GUI = Window()
sys.exit(app.exec_())
run()
Hey i fixed the issues with your code. In my fix, i added the QGridLayout to the QHBoxLayout. If you want the grid in another place you might need to nest both layouts in a 3rd layout.
Note that you are using setLayout for grid and for vbox when you can only set 1 layout. You also call show() twice, which you don't need. You also add a QVBoxLayout to hbox but do not add any widget. As it is, this is useless. If you want hbox and grid to be vertically aligned you will need to vbox.addLayout(grid) and self.setLayout(vbox) instead.
import sys
from PyQt4 import QtGui, QtCore
class Window(QtGui.QMainWindow, QtGui.QWidget):
` def __init__(self):
super(Window, self).__init__()
self.setGeometry(50, 50, 500, 300)
self.setWindowTitle("PTE")
self.setWindowIcon(QtGui.QIcon('.png'))
self.center()
# Adding Menu to the GUI
quitAction = QtGui.QAction(QtGui.QIcon('exit.png'), "&Quit", self)
quitAction.setShortcut("Ctrl+Q")
quitAction.setStatusTip('Exit Application')
quitAction.triggered.connect(self.close_application)
undoAction = QtGui.QAction(QtGui.QIcon('undo.png'), "&Undo", self)
undoAction.setShortcut("Ctrl+Z")
undoAction.triggered.connect(self.close_application)
aboutAction = QtGui.QAction("&About PTE...", self)
self.statusBar()
#Actual Main Menu with options
mainMenu = self.menuBar()
fileMenu = mainMenu.addMenu('&File')
fileMenu.addAction(quitAction)
fileMenu = mainMenu.addMenu('&Edit')
fileMenu.addAction(undoAction)
fileMenu = mainMenu.addMenu('&Help')
fileMenu.addAction(aboutAction)
self.home()
#Centering Window on the screen
def center(self):
gui = self.frameGeometry()
cp = QtGui.QDesktopWidget().availableGeometry().center()
gui.moveCenter(cp)
self.move(gui.topLeft())
def home(self):
#Buttons
qbtn = QtGui.QPushButton('Quit', self)
qbtn.clicked.connect(self.close_application)
rbtn = QtGui.QPushButton("Run", self)
rbtn.clicked.connect(self.close_application)
hbox = QtGui.QHBoxLayout()
hbox.addStretch(1)
hbox.addWidget(qbtn)
hbox.addWidget(rbtn)
vbox = QtGui.QVBoxLayout()
vbox.addStretch(1)
vbox.addLayout(hbox)
#self.show() #this only needs to be called once
#Labels and TextBox
Intervals = QtGui.QLabel('Number of intervals (0<=20) :')
Timesteps = QtGui.QLabel('Number of time steps (<=1000) : ')
IntervalsEdit = QtGui.QLineEdit()
TimestepsEdit = QtGui.QLineEdit()
grid = QtGui.QGridLayout()
grid.setSpacing(2)
grid.addWidget(Intervals, 1, 0)
grid.addWidget(IntervalsEdit, 1, 1)
grid.addWidget(Timesteps, 2, 0)
grid.addWidget(TimestepsEdit, 2, 1)
hbox.addLayout(grid) #this will add the grid to the horizontal layout.
#if you want it to be vertcally aligned change this to vbox.addLayout(grid)...
#... and this to self.setLayout(vbox)
self.setLayout(hbox)
self.show()
#What to display when the app is closed
def close_application(self):
#Popup message before closing the application in Binary
choice = QtGui.QMessageBox.question(self, 'Message',"Are you sure you want to exit?",
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No )
if choice == QtGui.QMessageBox.Yes:
print(" Until Next Time")
sys.exit()
else:
pass

Resources