Implementing keyPressEvent in QWidget - python

I have a QDialog window that has a continue button. The continue button is the default button because whenever I press the enter key, the continue button is pressed. I discovered something strange: when I press the enter key three times, the continue button presses three times. However, when I press it a fourth time, the whole window closes. I have a cancel button right below the continue button that closes the window, but I don't make the cancel button the default button or anything.
I wanted to override the keyPressEvent so that whenever I'm in the window, the enter button will always be connected to the continue button.
This is what I have right now:
class ManualBalanceUI(QtGui.QWidget):
keyPressed = QtCore.pyqtSignal()
def __init__(self, cls):
super(QtGui.QWidget, self).__init__()
self.window = QtGui.QDialog(None, QtCore.Qt.WindowSystemMenuHint)
self.ui = uic.loadUi('ManualBalanceUI.ui', self.window)
self.keyPressed.connect(self.on_key)
def keyPressEvent(self, event):
super(ManualBalanceUI, self).keyPressEvent(event)
self.keyPressed.emit(event)
def on_key(self, event):
if event.key() == QtCore.Qt.Key_Enter and self.ui.continueButton.isEnabled():
self.proceed() # this is called whenever the continue button is pressed
elif event.key() == QtCore.Qt.Key_Q:
self.window.close() # a test I implemented to see if pressing 'Q' would close the window
def proceed(self):
...
...
However, this doesn't seem to be doing anything right now. Pressing 'Q' doesn't close the window, and I can't really tell if the 'enter' key is working or not.
I looked at this question beforehand: PyQt Connect to KeyPressEvent
I also reviewed all the documentation on SourceForge. Any help would be greatly appreciated!

You can do two ways and one is simply re implement keyPressevent with out any fancy work. Like this
from PyQt4 import QtCore, QtGui
import sys
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.setGeometry(300, 300, 250, 150)
self.show()
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_Q:
print "Killing"
self.deleteLater()
elif event.key() == QtCore.Qt.Key_Enter:
self.proceed()
event.accept()
def proceed(self):
print "Call Enter Key"
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Or as you tried with signals, in your case you where missing to implement this signal properly, here is updated version.
class Example(QtGui.QWidget):
keyPressed = QtCore.pyqtSignal(QtCore.QEvent)
def __init__(self):
super(Example, self).__init__()
self.setGeometry(300, 300, 250, 150)
self.show()
self.keyPressed.connect(self.on_key)
def keyPressEvent(self, event):
super(Example, self).keyPressEvent(event)
self.keyPressed.emit(event)
def on_key(self, event):
if event.key() == QtCore.Qt.Key_Enter and self.ui.continueButton.isEnabled():
self.proceed() # this is called whenever the continue button is pressed
elif event.key() == QtCore.Qt.Key_Q:
print "Killing"
self.deleteLater() # a test I implemented to see if pressing 'Q' would close the window
def proceed(self):
print "Call Enter Key"
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

If you're looking at this in 2019, and If Achayan's method does not work for you then check a couple things :
1) Is the keyPressEvent overridden in a child of the main window or main widget? The child's function will override the methods on the parent (at least when using a QMainWindow with setCentralWidget). If this is the case, then the signal might not be emitted like you expect
2) Do you have a widget that handles key inputs differently than QWidget? For example, if the focus is in a QTextEdit object, then key inputs will not be sent to keyPressEvent. Shift focus to another widget
For example, observe the output of the following :
class myDialog(QtWidgets.QDialog):
keyPressed = QtCore.pyqtSignal(QtCore.QEvent)
def __init__(self, parent=None):
super(myDialog, self).__init__(parent)
self.keyPressed.connect(self.on_key)
leftGroupBox = QtWidgets.QGroupBox('A Group Label')
text = QtWidgets.QTextEdit('Enter some text')
layout = QtWidgets.QVBoxLayout()
layout.addWidget(text)
leftGroupBox.setLayout(layout)
rightGroupBox = QtWidgets.QGroupBox('Label Options')
label1 = QtWidgets.QCheckBox('ahu')
layout = QtWidgets.QVBoxLayout()
layout.addWidget(label1)
rightGroupBox.setLayout(layout)
# Create the main layout
mainLayout = QtWidgets.QGridLayout()
mainLayout.addWidget(leftGroupBox)
mainLayout.addWidget(rightGroupBox)
self.setLayout(mainLayout)
def keyPressEvent(self, event):
# keyPressEvent defined in child
print('pressed from myDialog: ', event.key())
# self.keyPressed.emit(event) # Emit is hidden in child
def on_key(self, event):
print('event received # myDialog')
if event.key() == QtCore.Qt.Key_0:
print(0)
class MainWindow(QtWidgets.QMainWindow):
keyPressed = QtCore.pyqtSignal(QtCore.QEvent)
def __init__(self):
super(MainWindow, self).__init__()
self.keyPressed.connect(self.on_key)
self.setCentralWidget(myDialog())
self.show()
def keyPressEvent(self, event):
super(MainWindow, self).keyPressEvent(event)
print('pressed from MainWindow: ', event.key())
self.keyPressed.emit(event)
def on_key(self, event):
print('event received # MainWindow')
if event.key() == QtCore.Qt.Key_0:
print(0)
if __name__ == '__main__':
ex = MainWindow()
Output # console : (no event is received #myDialog OR MainWindow)
pressed from myDialog: 48

For Achayan's answer, I succeeded with the code.
It may be the enter key and the return key.
Try Key_Enter and Key_Return. They are different on my keyboard.

QtCore.QObject.connect(self.ui.search_box, QtCore.SIGNAL("textChanged()"), self.fucn1)
Whenever text is changed in search_box function fucn1 is called.
Works for pyqt4

Related

PyQt5 button gets clicked signal when appeared on screen through stacked widget setCurrentWidget

I have an app with a window and QStackedWidget on it. The first page of the stacked widget disappears changes to the second on click(or touch). There is a button on the second page.
class AppLauncher(QtWidgets.QMainWindow, AppWindow.Ui_MainWindow):
def __init__(self, parent=None):
super(AppLauncher, self).__init__(parent)
self.setupUi(self)
self.iddle = True
self.fooButton.clicked.connect(self.foo)
def foo(self):
pass
def eventFilter(self, obj, event):
if (event.type() == QEvent.TouchBegin or \
event.type() == QEvent.TouchUpdate or \
event.type() == QEvent.MouseButtonPress) and self.manager_initialised :
if self.iddle:
self.stackedScreens.setCurrentWidget(self.buttonPage)
return super(AppLauncher, self).eventFilter(obj, event)
def main():
app = QApplication(sys.argv)
form = AppLauncher()
form.setAttribute(QtCore.Qt.WA_AcceptTouchEvents, True)
form.installEventFilter(form)
form.show()
app.exec_()
if __name__ == '__main__':
main()
It works OK but if I touch an area of the first page where the button on the second page located, pages change in a moment and the button appears under the finger. And when I take off my finger, the button gets "clicked" signal.
This happens so fast that even a fast tap on the first page fires the signal.
This potentially leads to users not understanding that they clicked on button after they touched the first page.
How can I solve this problem? I thought that a clicked signal is fired only if finger was put and taken off after button appears.
check for mouseButtonRelease
class AppLauncher(QtWidgets.QMainWindow, AppWindow.Ui_MainWindow):
def __init__(self, parent=None):
super(AppLauncher, self).__init__(parent)
self.setupUi(self)
self.iddle = True
self.fooButton.clicked.connect(self.foo)
def foo(self):
pass
def eventFilter(self, obj, event):
if (event.type() == QEvent.TouchBegin or \
event.type() == QEvent.TouchUpdate or \
event.type() == QEvent.MouseButtonRelease) and self.manager_initialised :
if self.iddle:
self.stackedScreens.setCurrentWidget(self.buttonPage)
return super(AppLauncher, self).eventFilter(obj, event)
def main():
app = QApplication(sys.argv)
form = AppLauncher()
form.setAttribute(QtCore.Qt.WA_AcceptTouchEvents, True)
form.installEventFilter(form)
form.show()
app.exec_()
if __name__ == '__main__':
main()

How can I know when the Enter key was pressed on QTextEdit

I'm writing Chat gui for client on Python using PyQt5.
I have a QTextEdit, which the client can write messages in it.
I wan't to know when the 'Enter' key is being pressed while the focus is on the QTextEdit.
I tried using installEventFilter function but it detects keys being pressed on all of the other widgets but the QTextEdit one.
What can I do to fix that?
def initUI(self):
# ...
self.text_box = QtWidgets.QTextEdit(self)
self.installEventFilter(self)
# ...
def keyPressEvent(self, qKeyEvent):
print(qKeyEvent.key())
if qKeyEvent.key() == Qt.Key_Return:
if self.text_box.hasFocus():
print('Enter pressed')
When you override keyPressEvent you are listening to the events of the window, instead install an eventFilter to the QTextEdit, not to the window as you have done in your code, and check if the object passed as an argument is the QTextEdit:
def initUI(self):
# ...
self.text_box = QtWidgets.QTextEdit(self)
self.text_box.installEventFilter(self)
# ...
def eventFilter(self, obj, event):
if event.type() == QtCore.QEvent.KeyPress and obj is self.text_box:
if event.key() == QtCore.Qt.Key_Return and self.text_box.hasFocus():
print('Enter pressed')
return super().eventFilter(obj, event)
The answer from #eyllanesc is very good if you are determined to use QTextEdit.
If you can get away with QLineEdit and its limitations, you can use the returnPressed() signal. The biggest drawback for QLineEdit is you are limited to one line of text. And there is no word wrap. But the advantage is you don't have to mess with eventFilters or think too hard about how keyPress signals fall through all of the widgets in your app.
Here is a minimal example that copies from one QLineEdit to another:
import sys
from PyQt5.QtWidgets import *
class PrintWindow(QMainWindow):
def __init__(self):
super().__init__()
self.left=50
self.top=50
self.width=300
self.height=300
self.initUI()
def initUI(self):
self.setGeometry(self.left,self.top,self.width,self.height)
self.line_edit1 = QLineEdit(self)
self.line_edit1.move(50, 50)
self.line_edit1.returnPressed.connect(self.on_line_edit1_returnPressed)
self.line_edit2 = QLineEdit(self)
self.line_edit2.move(50, 100)
self.show()
def on_line_edit1_returnPressed(self):
self.line_edit2.setText(self.line_edit1.text())
if __name__ == '__main__':
app = QApplication(sys.argv)
window = PrintWindow()
sys.exit(app.exec_())
In this example, I have manually connected to the signal in line 22 (self.line_edit1.returnPressed.connect). If you are using a ui file, this connection can be left out and your program will automatically call the on__returnPressed method.
When you override keyPressEvent you are listening to the events of the window, instead install an eventFilter to the QTextEdit, not to the window as you have done in your code, and check if the object passed as an argument is the QTextEdit:
def initUI(self):
# ...
self.text_box = QtWidgets.QTextEdit(self)
self.text_box.installEventFilter(self)
# ...
def eventFilter(self, obj, event):
if event.type() == QtCore.QEvent.KeyPress and obj is self.text_box:
if event.key() == QtCore.Qt.Key_Return and self.text_box.hasFocus():
print('Enter pressed')
return True
return False
This is building upon the answer of #eyllanesc and the problem #Daniel Segal faced. Adding the correct return values as such to the eventFilter solves the problem.

QWidget cannot catch ESCAPE, BACKSPACE or C-x key press events

I am catching key press events by overriding the KeyPressEvent method of my class, inheriting from QWidget, but I cannot see key press events for the ESCAPE and BACKSPACE keys, as well as C-x or again C-c. I can see key release events though. Who catches them ?
class KeyCaptureWidget(QWidget):
# init…
def keyPressEvent(self, event):
key = event.key()
logging.info("key press: {}".format(key))
def keyReleaseEvent(self, event):
key_code = event.key()
logging.info("key release: {}".format(key_code))
The difference between C-x and say C-b is the following:
pressing C-b prints: control is pressed, b is pressed, b is released, control is released.
pressing C-x prints: control is pressed, [nothing], x is released, control is released.
In my QWidget, I use a QVBoxLayout to which I put two QWebEngine views. I tried to override the key press method of the QWebEngineView, but they don't seem to catch anything (and this is the behaviour I expected).
def __init__(self):
self.qtwindow = KeyCaptureWidget()
self.layout = QVBoxLayout()
self.view1 = QWebEngineView() # or a custom one to override keyPressEvent
# self.view2 = the same
self.layout.addWidget(self.view1)
self.layout.addWidget(self.view2)
self.qtwindow.setLayout(self.layout)
self.qtwindow.show()
I tried to catch these with event filters on my QWidget class but again, no luck: I see only a key release for ESC or BACKSPACE.
def __init__(self):
super().__init__()
self.installEventFilter(self)
def eventFilter(self, source, event):
logging.info("event filter: {}".format(event))
if event.type() == QEvent.KeyPress:
logging.info(" event filter key PRESS")
if event.type() == QEvent.KeyRelease:
logging.info(" event filter key RELEASE")
return True
How can I catch them ? Thank you.
Events do not necessarily propagate among all widgets, if a widget consumes it then it will no longer propagate to the parent. In the case of the keyboard events will only be consumed first by the widget that has the focus, in your case QWebEngineView consumes them before and prevents it from being projected in other widgets. If you want to hear events from the keyboard of a window then you must use the QShortcuts, and for that you must create a QShortcut:
Ctrl + C: QtGui.QKeySequence("Ctrl+C")
Ctrl + X: QtGui.QKeySequence("Ctrl+X")
Esc: QtGui.QKeySequence("Escape")
Backspace: QtGui.QKeySequence("Backspace")
Considering the above, the solution is:
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.m_view1 = QtWebEngineWidgets.QWebEngineView()
self.m_view2 = QtWebEngineWidgets.QWebEngineView()
self.m_view1.load(QtCore.QUrl("https://stackoverflow.com/questions/56890831"))
self.m_view2.load(QtCore.QUrl("https://doc.qt.io/"))
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.m_view1)
lay.addWidget(self.m_view2)
QtWidgets.QShortcut(
QtGui.QKeySequence("Ctrl+C"), self, activated=self.on_Ctrl_C
)
QtWidgets.QShortcut(
QtGui.QKeySequence("Ctrl+X"), self, activated=self.on_Ctrl_X
)
QtWidgets.QShortcut(
QtGui.QKeySequence("Escape"), self, activated=self.on_Escape
)
QtWidgets.QShortcut(
QtGui.QKeySequence("Backspace"), self, activated=self.on_Backspace
)
#QtCore.pyqtSlot()
def on_Ctrl_C(self):
print("Ctrl+C")
#QtCore.pyqtSlot()
def on_Ctrl_X(self):
print("Ctrl+X")
#QtCore.pyqtSlot()
def on_Escape(self):
print("Escape")
#QtCore.pyqtSlot()
def on_Backspace(self):
print("Backspace")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())

Get the RFID text without QLineEdit

I have an QLineEdit that will take the value of an RFID tag and the log the user in with the value that is received, I have setup the QLineEdit so that it calls a login function when the enter key is pressed.
The only issue that I am left with is that the QLineEdit is visible which is not necessary as the user will not be typing the value of their RFID tag, they will just scan it and the scanner will enter the value and press enter.
rfid_enter = QLineEdit()
rfid_enter.returnPressed.connect(lambda: log_user_in(rfid_enter.text()))
def log_user_in(value):
print(value) (THIS WILL LOG THE USER IN)
QLineEdit needs to have the focus to get the keyboard events, but to have the focus it needs to be visible, so hiding it will not be the solution.
As pointed out by the OP in the comments in the window there are only: two labels, and a few spacers that do not handle the keyboard event so there are no widgets that intercept that event so the window can get them without problems (if there are other widget like QLineEdits, QTextEdit, QSpinBox, etc. the logic could change).
Considering the above, I have implemented the following logic:
import string
from PyQt5 import QtCore, QtWidgets
class Widget(QtWidgets.QWidget):
returnPressed = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(
QtWidgets.QLabel("My Label", alignment=QtCore.Qt.AlignHCenter),
alignment=QtCore.Qt.AlignTop,
)
self.m_text = ""
self.returnPressed.connect(self.log_user_in)
def keyPressEvent(self, event):
if event.text() in string.ascii_letters + string.digits:
self.m_text += event.text()
if event.key() in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
self.returnPressed.emit(self.m_text)
# clear text
self.m_text = ""
super(Widget, self).keyPressEvent(event)
#QtCore.pyqtSlot(str)
def log_user_in(self, text):
print(text)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.resize(240, 320)
w.show()
sys.exit(app.exec_())
The answer from eyllanesc would work if the entire window was the class that he had created, but in my case the layout will change and therefore I could not use that as the main window.
I went for a cheat approach of just trying to hide the box as much as possible and ended up with this result.
class LogInRFIDListener(QtWidgets.QPlainTextEdit):
def __init__(self):
super(LogInRFIDListener, self).__init__()
self.setTextInteractionFlags(QtCore.Qt.TextEditable)
self.setCursor(QtCore.Qt.ArrowCursor)
self.setStyleSheet("border: none; color: transparent;") # Hide the border around the text box
self.setCursorWidth(0) # Hide the cursor
def keyPressEvent(self, event): # Major restricting needed
if event.key() in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
log_user_in(self.toPlainText())
super(LogInRFIDListener, self).keyPressEvent(event)

Update a QLineEdit on a WheelEvent when scroll bar is already set

I'm trying to update a QLineEdit when I do a wheel move on the mouse and if I press a number on the keyboard at the same time. Unfortunatly, I don't see a mouse wheel event for QLineEdit widget so I don't understand how I can set a signal to each QLineEdit. The other issue I have is as the QLineEdit are already in a scroll bar environment, I cannot detect all wheel event because the scroll is done first.
For instance with this code:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
class SurfViewer(QMainWindow):
def __init__(self, parent=None):
super(SurfViewer, self).__init__()
self.parent = parent
self.centralTabs= QTabWidget()
self.setCentralWidget(self.centralTabs)
self.setFixedWidth(200)
self.setFixedHeight(200)
#tab Model selection
self.tab_ModelSelect = QWidget()
self.centralTabs.addTab(self.tab_ModelSelect,"Label")
self.groupscrolllayouttest = QHBoxLayout() ####
self.groupscrollbartest = QGroupBox() ####
self.mainHBOX_param_scene = QVBoxLayout()
for i in range(10):
LineEdit = QLineEdit(str(i))
LineEdit.setFixedWidth(200)
self.mainHBOX_param_scene.addWidget(LineEdit)
self.installEventFilter(self)
scroll = QScrollArea()
widget = QWidget(self)
widget.setLayout(QVBoxLayout())
widget.layout().addWidget(self.groupscrollbartest)
scroll.setWidget(widget)
scroll.setWidgetResizable(True)
self.groupscrollbartest.setLayout(self.mainHBOX_param_scene)
self.groupscrolllayouttest.addWidget(scroll)
self.tab_ModelSelect.setLayout(self.groupscrolllayouttest)
def eventFilter(self, widget, event):
if (event.type() == QEvent.Wheel) :
# get which key is pressed
# if the key is a number, put the number in 'num' variable
# get on which QLineEdit the wheel was make
# set the text of that QLineEdit to previous value +- num
event.ignore()
return QWidget.eventFilter(self, widget, event)
def main():
app = QApplication(sys.argv)
ex = SurfViewer(app)
ex.setWindowTitle('window')
# ex.showMaximized()
ex.show()
sys.exit(app.exec_( ))
if __name__ == '__main__':
main()
I tried to something with wheelevent but as mention, I don't enter in this function because the scroll bar is activated first. I tried to test if the wheel event happend on a QLineEdit but I even struggle to do that...
What I'm seeking to do is when I do a wheelevent with the mouse on a QlineEdit with the '5' key pressed, I want increase or decrease the QLineEdit text by 5 according to the direction of the mouse wheel.
I red some post with eventfilter (as How to get Click Event of QLineEdit in Qt?) but I don't understand how does this work.
In my eventFilter function, I need to do several step:
# get which key is pressed
# if the key is a number, put the number in 'num' variable
# get on which QLineEdit the wheel was make
# set the text of that QLineEdit to previous value +- num
but I don't know how to make them. In particular getting the pressed key and knowing on which QlineEdit the wheel was made.
If you wish that all QLineEdit have that behavior then it is appropriate that you create your own class and overwrite the necessary events, to avoid that when you move the scroll when the pointer is inside the QLineEdit and pressing an established key, we accept the event so that it does not propage.
Another recommendation is not to use the 5 key since this is a text that QLineEdit can handle causing problems, for this you can use the SHIFT key:
class LineEdit(QLineEdit):
KEY = Qt.Key_Shift
def __init__(self, *args, **kwargs):
QLineEdit.__init__(self, *args, **kwargs)
self.isKeyPressed = False
def keyPressEvent(self, event):
if event.key() == LineEdit.KEY:
self.isKeyPressed = True
QLineEdit.keyPressEvent(self, event)
def keyReleaseEvent(self, event):
if event.key() == LineEdit.KEY:
self.isKeyPressed = False
QLineEdit.keyReleaseEvent(self, event)
def wheelEvent(self, event):
if self.isKeyPressed:
delta = 1 if event.angleDelta().y() > 0 else -1
fn = self.font()
fn.setPointSize(fn.pointSize() + delta)
self.setFont(fn)
event.accept()
The complete example:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
class LineEdit(QLineEdit):
KEY = Qt.Key_Shift
def __init__(self, *args, **kwargs):
QLineEdit.__init__(self, *args, **kwargs)
self.isKeyPressed = False
def keyPressEvent(self, event):
if event.key() == LineEdit.KEY:
self.isKeyPressed = True
QLineEdit.keyPressEvent(self, event)
def keyReleaseEvent(self, event):
if event.key() == LineEdit.KEY:
self.isKeyPressed = False
QLineEdit.keyReleaseEvent(self, event)
def wheelEvent(self, event):
if self.isKeyPressed:
delta = 1 if event.angleDelta().y() > 0 else -1
fn = self.font()
fn.setPointSize(fn.pointSize() + delta)
self.setFont(fn)
event.accept()
class SurfViewer(QMainWindow):
def __init__(self, parent=None):
super(SurfViewer, self).__init__()
self.parent = parent
self.centralTabs= QTabWidget()
self.setCentralWidget(self.centralTabs)
self.setFixedWidth(200)
self.setFixedHeight(200)
#tab Model selection
self.tab_ModelSelect = QWidget()
self.centralTabs.addTab(self.tab_ModelSelect,"Label")
self.groupscrolllayouttest = QHBoxLayout() ####
self.groupscrollbartest = QGroupBox() ####
self.mainHBOX_param_scene = QVBoxLayout()
for i in range(10):
le = LineEdit(str(i))
le.setFixedWidth(200)
self.mainHBOX_param_scene.addWidget(le)
self.installEventFilter(self)
scroll = QScrollArea()
widget = QWidget(self)
widget.setLayout(QVBoxLayout())
widget.layout().addWidget(self.groupscrollbartest)
scroll.setWidget(widget)
scroll.setWidgetResizable(True)
self.groupscrollbartest.setLayout(self.mainHBOX_param_scene)
self.groupscrolllayouttest.addWidget(scroll)
self.tab_ModelSelect.setLayout(self.groupscrolllayouttest)
def main():
app = QApplication(sys.argv)
ex = SurfViewer(app)
ex.setWindowTitle('window')
# ex.showMaximized()
ex.show()
sys.exit(app.exec_( ))
if __name__ == '__main__':
main()

Categories