在 PyQt5 中使用自定义标题栏移动 window 时出现问题

Problem with moving window using custom title bar in PyQt5

我正在尝试使用 setWindowFlags(FramelessWindowHint).

构建带有自定义标题栏的 GUI

我已经成功创建了 close/minimise 按钮等,它们具有各自的功能,并且它们运行良好(它们不包含在我下面的代码中)。但是,使用我的自定义标题栏使 window 可移动并没有取得同样的成功。

当我 运行 代码并试图拖动 window 时,光标变为蓝色加载漩涡然后崩溃。我还用调试器尝试了 运行 它,当我试图拖动 window 时,我得到了错误:

TypeError: unsupported operand type(s) for +: 'QPoint' and 'builtin_function_or_method'

下面是我的代码的一部分。 (从大项目中剪下来的,可能有点乱)

如果能帮助解决我的问题,我们将不胜感激,谢谢。

from PyQt5 import QtCore, QtGui, QtWidgets, Qt
from PyQt5.QtCore import Qt

WINDOW_SIZE = 0

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1200, 700)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.top_bar = QtWidgets.QWidget(self.centralwidget)
        self.top_bar.setMaximumSize(QtCore.QSize(16777215, 60))
        self.top_bar.setStyleSheet("background-color: rgb(52, 56, 60)")
        self.top_bar.setObjectName("top_bar")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.top_bar)
        self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_2.setSpacing(0)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.frame = QtWidgets.QFrame(self.top_bar)
        self.frame.setMinimumSize(QtCore.QSize(80, 60))
        self.frame.setMaximumSize(QtCore.QSize(80, 60))
        self.frame.setStyleSheet("background-color:rgb(30, 34, 38);\n"
                                                       "border: 0px")
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.frame)
        self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_4.setSpacing(0)
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.horizontalLayout_2.addWidget(self.frame)
        self.header_bar = QtWidgets.QFrame(self.top_bar)
        self.header_bar.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.header_bar.setFrameShadow(QtWidgets.QFrame.Raised)
        self.header_bar.setObjectName("header_bar")
        self.horizontalLayout_2.addWidget(self.header_bar)
        self.verticalLayout.addWidget(self.top_bar)
        self.content = QtWidgets.QWidget(self.centralwidget)
        self.content.setStyleSheet("")
        self.content.setObjectName("content")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.content)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setSpacing(0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.verticalLayout.addWidget(self.content)
        MainWindow.setCentralWidget(self.centralwidget)

        self.header_bar.mouseMoveEvent = self.moveWindow

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))

    def mousePressEvent(self, event):
        MainWindow.dragPos = event.globalPos()

    def moveWindow(self, event):
        if MainWindow.isMaximized():
            MainWindow.showNormal()
        else:
            if event.buttons() == Qt.LeftButton:
                MainWindow.move((MainWindow.pos() + event.globalPos() - MainWindow.dragPos))
                MainWindow.dragPos = event.globalPos()
                event.accept()


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

我把改的地方都标出来了

from PyQt5 import QtCore, QtGui, QtWidgets, Qt
from PyQt5.QtCore import Qt

WINDOW_SIZE = 0

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1200, 700)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.top_bar = QtWidgets.QWidget(self.centralwidget)
        self.top_bar.setMaximumSize(QtCore.QSize(16777215, 60))
        self.top_bar.setStyleSheet("background-color: rgb(52, 56, 60)")
        self.top_bar.setObjectName("top_bar")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.top_bar)
        self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_2.setSpacing(0)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.frame = QtWidgets.QFrame(self.top_bar)
        self.frame.setMinimumSize(QtCore.QSize(80, 60))
        self.frame.setMaximumSize(QtCore.QSize(80, 60))
        self.frame.setStyleSheet("background-color:rgb(30, 34, 38);\n"
                                                       "border: 0px")
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.frame)
        self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_4.setSpacing(0)
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.horizontalLayout_2.addWidget(self.frame)
        self.header_bar = QtWidgets.QFrame(self.top_bar)
        self.header_bar.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.header_bar.setFrameShadow(QtWidgets.QFrame.Raised)
        self.header_bar.setObjectName("header_bar")
        self.horizontalLayout_2.addWidget(self.header_bar)
        self.verticalLayout.addWidget(self.top_bar)
        self.content = QtWidgets.QWidget(self.centralwidget)
        self.content.setStyleSheet("")
        self.content.setObjectName("content")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.content)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setSpacing(0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.verticalLayout.addWidget(self.content)
        MainWindow.setCentralWidget(self.centralwidget)

        
        self.header_bar.mouseMoveEvent = self.moveWindow

        #*************************************************************************************************************************************************************
        self.header_bar.mousePressEvent = self.mousePress
        #*************************************************************************************************************************************************************

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))

    #*************************************************************************************************************************************************************
    def mousePress(self, event):
        MainWindow.dragPos = MainWindow.pos()
        self.mouse_original_pos = MainWindow.mapToGlobal(event.pos())
    #*************************************************************************************************************************************************************

    def moveWindow(self, event):
        if MainWindow.isMaximized():
            MainWindow.showNormal()
        else:
            if event.buttons() == Qt.LeftButton:
                #******************************************************************************************************************************************************
                MainWindow_last_pos = MainWindow.dragPos + MainWindow.mapToGlobal(event.pos()) - self.mouse_original_pos
                MainWindow.move(MainWindow_last_pos)
                event.accept()
                #******************************************************************************************************************************************************


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())