Search code examples
pythonwindowspython-3.4pyqt5qmainwindow

PyQt5 draggable frameless window


I found an example to set borders on a frameless window, however it's not draggable. How can I make a frameless window draggable? Especially if I can see an example it'll be awesome. Here is my example code(normally the code is longer, that's why there are much libraries just don't mind them);

from PyQt5.QtWidgets import (QMessageBox,QApplication, QWidget, QToolTip, QPushButton,
                             QDesktopWidget, QMainWindow, QAction, qApp, QToolBar, QVBoxLayout,
                             QComboBox,QLabel,QLineEdit,QGridLayout,QMenuBar,QMenu,QStatusBar,
                             QTextEdit,QDialog,QFrame,QProgressBar
                             )
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtGui import QIcon,QFont,QPixmap,QPalette
from PyQt5.QtCore import QCoreApplication, Qt,QBasicTimer

import sys

class cssden(QMainWindow):
    def __init__(self):
        super().__init__()


        self.mwidget = QMainWindow(self)
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)


        #size
        self.setFixedSize(320, 450)
        self.center


        #label
        self.lbl = QLabel(self)
        self.lbl.setText("test")
        self.lbl.setStyleSheet("background-color: rgb(0,0,0);"
                               "border: 1px solid red;"
                               "color: rgb(255,255,255);"
                               "font: bold italic 20pt 'Times New Roman';")
        self.lbl.setGeometry(5,5,60,40)

        self.show()

    #center
    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

app = QApplication(sys.argv)
app.setStyleSheet("QMainWindow{background-color: darkgray;border: 1px solid black}")

ex = cssden()
sys.exit(app.exec_())

Solution

  • You need to handle the mouse events yourself.

    • We will need to add an event on mousePressEvent, which will keep the place where we last clicked on the window
    • Then, we will add a mouseMoveEvent, which will calculate the distance between the last clicked point and the current mouse location. We will move the window according to this distance.

    This is the fixed code:

    import sys
    from PyQt5.QtCore import Qt, QPoint
    from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel
    
    
    class cssden(QMainWindow):
        def __init__(self):
            super().__init__()
    
            # <MainWindow Properties>
            self.setFixedSize(320, 450)
            self.setStyleSheet("QMainWindow{background-color: darkgray;border: 1px solid black}")
            self.setWindowFlags(Qt.FramelessWindowHint)
            self.center()
            # </MainWindow Properties>
    
            # <Label Properties>
            self.lbl = QLabel(self)
            self.lbl.setText("test")
            self.lbl.setStyleSheet("QLabel{background-color: rgb(0,0,0); border: 1px solid red; color: rgb(255,255,255); font: bold italic 20pt 'Times New Roman';}")
            self.lbl.setGeometry(5, 5, 60, 40)
            # </Label Properties>
    
            self.oldPos = self.pos()
            self.show()
    
        def center(self):
            qr = self.frameGeometry()
            cp = QDesktopWidget().availableGeometry().center()
            qr.moveCenter(cp)
            self.move(qr.topLeft())
    
        def mousePressEvent(self, event):
            self.oldPos = event.globalPos()
    
        def mouseMoveEvent(self, event):
            delta = QPoint (event.globalPos() - self.oldPos)
            self.move(self.x() + delta.x(), self.y() + delta.y())
            self.oldPos = event.globalPos()
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = cssden()
        sys.exit(app.exec_())