0

I'm making a simple PyQt5 application and am curious about how to make the circle move with the arrow keys. I want it to move 5 pixels on every press.

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(500, 500)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.coords = QtWidgets.QPushButton(self.centralwidget)
        self.coords.setGeometry(QtCore.QRect(0, 0, 75, 23))
        self.coords.setObjectName("coords")
        self.mover = QtWidgets.QLabel(self.centralwidget)
        self.mover.setGeometry(QtCore.QRect(200, 200, 50, 50))
        self.mover.setText("")
        self.mover.setPixmap(QtGui.QPixmap("mover.png"))
        self.mover.setObjectName("mover")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 500, 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", "DYM"))
        self.coords.setText(_translate("MainWindow", "Coords"))


if __name__ == "__main__":
     # Snip

1 Answers1

1

You shouldn't edit nor use the code provided by pyuic from Designer files directly. Instead, you have to create your own code that uses that code as explained here.

A very simple and limited implementation (which doesn't use Designer .ui files) looks like this:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class Mover(QtWidgets.QLabel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setGeometry(0, 0, 500, 21)
        self.setPixmap(QtGui.QPixmap('mover.png'))

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Up:
            self.move(self.x(), self.y() - 5)
        elif event.key() == QtCore.Qt.Key_Down:
            self.move(self.x(), self.y() + 5)
        elif event.key() == QtCore.Qt.Key_Left:
            self.move(self.x() - 5, self.y())
        elif event.key() == QtCore.Qt.Key_Right:
            self.move(self.x() + 5, self.y())
        else:
            QtWidgets.QLabel.keyPressEvent(self, event)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        centralWidget = QtWidgets.QWidget()
        self.setCentralWidget(centralWidget)
        self.mover = Mover(centralWidget)
        self.mover.setFocus()


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

There are some drawback about this, though: I had to setFocus to the widget in order to make it capture key press events, which means that if you have any other widget that interacts with key events (such as a QLineEdit) and it gets focus, your "mover" widget won't move anymore until it receives its focus back (which is usually achieved by means of a QWidget.setFocusPolicy()).

musicamante
  • 41,230
  • 6
  • 33
  • 58
  • Sorry, I'm not sure I'm understanding your question, what do you mean? – musicamante Jul 30 '19 at 08:37
  • Why should I have the code different than the Qt Designer one? –  Jul 31 '19 at 06:31
  • You're not supposed to tinker with it, and there's a clear warning in it. It's created from the files created with Designer: whenever you go back to edit the GUI (which happens very often), you'll have to generate the code again, making it hard to integrate its output with the code you might have modified in the meantime. Also, if you're not careful, it might even overwrite the file you've edited, making it impossible to retrieve it. Changing the pyuic output is something you rarely need (and mostly for very advanced cases), so it's better to leave it as it is and follow the linked guidelines. – musicamante Jul 31 '19 at 07:58