two keyPressEvent in the same class (Pyqt5) - python-3.x

Hello
I am using Pyqt5 & QT Designer to create a GUI. and i would like to use two keyPressEvent in one class. one of them to exit from the GUI and the other to hide a button.The problem is that the keyPressEvent overwrite each other so that they can't preform together
Part of the code:
....
self.pushButton = MYButton(self.centralwidget)
....
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent=parent)
self.setupUi(self)
self.initMe()
def initMe(self):
self.pushButton.setToolTip('This is a <u> Button </u>')
self.pushButton.clicked.connect(self.pressed)
QToolTip.setFont(QFont('Arial',7))
self.setToolTip('Das ist ein Fenster!')
self.pushButton_2.clicked.connect(self.close)
def druecken(self): #1
Sender = self.sender()
Sender.move(50,50)
print(Sender.text()+'the Button is already pressed')
def keyPressEvent(self, e):
if e.key() == Qt.Key_W:
self.close()
class MYButton(QPushButton):
def keyPressEvent(self, e):
if e.key() == Qt.Key_Escape:
self.close()
So for example i have to press the Escape key first to hide the buttom then i can't press the W Key to close the GUI. But when i do it oppisitly it does not work because MYButton function is still runing and its keyPressEvent is activied. So how i get the both to run together?

Related

PyQt5 Dialog window opens without layout

When I load a dialog (QMainWindow) window from within my mainwindow (QMainWindow), it loads without layout, even though the setupUi() function is called.
The important pieces of code are here below, click here for pastebin link to full code
class Ui_Dialog(QMainWindow):
def __init__(self, parent=None):
super(Ui_Dialog, self).__init__(parent)
self.setupUi(self)
def setupUi(self, Dialog):
...
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setupUi(self)
self.show()
....
def setupUi(self, Form):
...
self.auto_sap_btn = QPushButton(Form)
self.auto_sap_btn.setGeometry(QRect(0, 0, 61, 25))
self.auto_sap_btn.setObjectName('auto_sap_btn')
self.auto_sap_btn.clicked.connect(self.openDialog)
def openDialog(self):
self.window = Ui_Dialog(self)
self.window.setupUi(self.window)
self.window.move(600, 500)
self.window.show()
Right now my dialog looks like this:
Failed dialog layout
When I load the dialog on its own from its own script created by:
pyuic5 -x dialog.ui -o dialog.py
it looks like this:
Proper dialog layout
What am I missing?
When you create a design based on a Template in Qt Designer, then when you have to pass the appropriate widget, when you created Ui_Dialog you surely used Dialog with Buttons Right so in this case you should use a QDialog instead of QMainWindow:
class Ui_Dialog(QDialog): # change QMainWindow to QDialog
def __init__(self, parent=None):
super(Ui_Dialog, self).__init__(parent)
self.setupUi(self)
[...]
Another mistake is to use the setupUi() method a second time since this method is responsible for filling in the widget, by calling it 2 times you will be adding more widgets unnecessarily:
def openDialog(self):
self.window = Ui_Dialog(self)
self.window.move(600, 500)
self.window.show()

Handle arrow key events by setting the focus policy

I want to handle key events of the arrow keys in my application. I have already read that for doing so the focus must be disabled. I follow this method: PyQt not recognizing arrow keys. Indeed, when calling self.setChildrenFocusPolicy(QtCore.Qt.NoFocus) (as defined in the linked thread and in my source code below) within MyApp.__init__, hitting an arrow key raises a key event. However, I do not want to keep the focus disabled during the entire runtime of the application but only upon clicking a button. So I move self.setChildrenFocusPolicy(QtCore.Qt.NoFocus) to the button click function:
def __init__(self):
self.pushButton.clicked.connect(self.pushButtonClicked)
def pushButtonClicked(self):
self.setChildrenFocusPolicy(QtCore.Qt.NoFocus)
Indeed, hitting the push button disables the focus (e.g. a line edit cannot take the text cursor anymore). However, hitting an arrow key still does not raise a key event.
The whole application (you will need a mainwindow.ui with a push button):
import sys
from PyQt4 import QtCore, QtGui, uic
qtCreatorFile = "d:/test/mainwindow.ui"
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
class MyApp(QtGui.QMainWindow, Ui_MainWindow):
def setChildrenFocusPolicy(self, policy):
def recursiveSetChildFocusPolicy (parentQWidget):
for childQWidget in parentQWidget.findChildren(QtGui.QWidget):
childQWidget.setFocusPolicy(policy)
recursiveSetChildFocusPolicy(childQWidget)
recursiveSetChildFocusPolicy(self)
def __init__(self):
QtGui.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
self.pushButton.clicked.connect(self.pushButtonClicked)
def pushButtonClicked(self):
self.setChildrenFocusPolicy(QtCore.Qt.NoFocus)
def keyPressEvent(self, event):
print "a"
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
There's no need to disable focus. You can get access to all key events by installing an event filter on the application:
class MyApp(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self):
...
QtGui.qApp.installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == QtCore.QEvent.KeyPress:
print(event.key())
return super(MyApp, self).eventFilter(source, event)
But note that this really does get everything, so you may end up with more than you bargained for...

Drag a file into a gui using PySide

Hi I want to drag a file (image) into my gui with PySide, however I can't get it to work. I Cannot get it to go into the dropEvent Function. My object that I am trying to drag into is a QGraphicsView so the filter can't take over the whole gui because I want to drag two images into it.
class Consumer(QMainWindow, Ui_MainWindow, QComboBox, QtGui.QWidget):
def __init__(self, parent=None):
self.paylod = None
super(Consumer, self).__init__(parent)
self.setupUi(self)
self.chkApplyCompression.stateChanged.connect(self.makecompress)
self.viewCarrier1.setMouseTracking(True)
self.viewCarrier1.installEventFilter(self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.viewCarrier1)
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.QDropEvent and
print('yay?')
return QtGui.QWidget.eventFilter(self, source, event)
def dropEvent(self, e):
print("yay")
def dragEnterEvent(self, *args, **kwargs):
print("Yay!!")
if __name__ == "__main__":
currentApp = QtGui.QApplication(sys.argv)
currentForm = Consumer()
currentForm.show()
currentApp.exec_()
Thanks
You need to accept the drag enter event before Qt will handle a subsequent drop event:
def dragEnterEvent(self, event):
event.accept()

PyQt keyPressEvent not triggered from QDialog

I have a simple example of of a dialog window that has the keyPressEvent method. However, no matter what is typed when the sub window has focus, the event is not triggered.
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import PyQt4.Qt
class KpeWindow(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
main = QVBoxLayout(self)
label = QLabel(self)
label.setText('Test the keyPressEvent')
self.adjustSize()
self.setLayout(main)
def keyPressEvent(self, event):
QMessageBox.warning(self, 'MDI', 'keyPressEvent')
super().keyPressEvent(event)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('KeyPressEvent Test')
child = KpeWindow()
self.setCentralWidget(child)
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
The following code works:
class KpeWindow(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self,parent)
main = QVBoxLayout(self)
label = QLabel(self)
label.setText('Test the keyPressEvent')
main.addWidget(label)
self.adjustSize()
self.setLayout(main)
def keyPressEvent(self, event):
QMessageBox.warning(self, 'MDI', 'keyPressEvent')
self.parent().keyPressEvent(event)
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setWindowTitle('KeyPressEvent Test')
main = QVBoxLayout(self)
child = KpeWindow(self)
child.setFocusPolicy(Qt.StrongFocus)
self.setFocusProxy(child)
main.addWidget(child)
child.setFocus(True)
self.adjustSize()
self.setLayout(main)
I am not sure which of my changes work, I suspect setFocusProxy. In general I would recommend using QWidget as the child, and putting things into layouts even when there are no siblings.
The keyPressEvent is sensitive to the focus policy. In your example, the event is going to the QMainWindow (if you move the keyPressEvent to there, it does receive key events).
Is there any reason to have a dialog within a window? If you launch the dialog in the usual way, using child.show(), child.exec_() instead of setCentralWidget, it shows in a separate window and captures the key event.

How does the keyPressEvent method work in this program?

I'm having trouble understanding how the keyPressEvent method works in this program. Specifically, what is "e" here? Is keyPressEvent a redefined method using a pre-existing instance "e"?
import sys
from PyQt4 import QtGui, QtCore
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.setGeometry(300,300,250,150)
self.setWindowTitle('Event handler')
self.show()
def keyPressEvent(self, e):
if e.key() == QtCore.Qt.Key_Escape:
self.close()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
e is the "event" that is generated when a user presses a key. This is pretty common in event handlers, it's a great way to pass information (such as which key got pressed - which is what's getting pulled with e.key()) to event handlers, so that we can combine related events and handle them with a single function.
# A key has been pressed!
def keyPressEvent(self, event):
# Did the user press the Escape key?
if event.key() == QtCore.Qt.Key_Escape: # QtCore.Qt.Key_Escape is a value that equates to what the operating system passes to python from the keyboard when the escape key is pressed.
# Yes: Close the window
self.close()
# No: Do nothing.

Resources