首页 > 解决方案 > 如何通过单击 QDialog 中的自定义标题来移动窗口

问题描述

当我按下标题栏或 frame_title 时,我想移动窗口,但我不知道该怎么做。当我按下按钮时会弹出此 QDialog 窗口。但是,我无法移动 QDialog 窗口。我想移动用鼠标拖放窗口。我分享了我的代码,没有不必要的东西。所以事情可能看起来不完整和荒谬。

def Musteri_Ekle_Penceresi(self):
    mustekledialog=QDialog()
    mustekledialog.setGeometry(600, 280, 880, 651)

    mustekledialog.setWindowFlags(Qt.FramelessWindowHint)
    mustekledialog.setAttribute(Qt.WA_TranslucentBackground)

    self.drop_shadow_layout = QVBoxLayout(mustekledialog)

    self.drop_shadow_frame = QFrame(mustekledialog)
    self.drop_shadow_frame.setFrameShape(QFrame.NoFrame)
    self.drop_shadow_frame.setFrameShadow(QFrame.Raised)

    self.verticalLayout = QVBoxLayout(self.drop_shadow_frame)

    self.title_bar = QFrame(self.drop_shadow_frame)
    self.title_bar.setFrameShape(QFrame.NoFrame)
    self.title_bar.setFrameShadow(QFrame.Raised)
    
    self.horizontalLayout = QHBoxLayout(self.title_bar)

    self.frame_title = QFrame(self.title_bar)
    self.frame_title.setFrameShape(QFrame.StyledPanel)
    self.frame_title.setFrameShadow(QFrame.Raised)
    self.verticalLayout_2 = QVBoxLayout(self.frame_title)
    self.verticalLayout_2.setSpacing(0)
    self.label_title = QLabel(self.frame_title)
    self.verticalLayout_2.addWidget(self.label_title)
    self.horizontalLayout.addWidget(self.frame_title)
    self.frame_btns = QFrame(self.title_bar)
    self.frame_btns.setFrameShape(QFrame.StyledPanel)
    self.frame_btns.setFrameShadow(QFrame.Raised)
    self.horizontalLayout_3 = QHBoxLayout(self.frame_btns)
    self.btn_minimize = QPushButton(self.frame_btns)             
    self.btn_minimize.clicked.connect(mustekledialog.showMinimized)
    self.horizontalLayout_3.addWidget(self.btn_minimize)
    self.btn_maximize = QPushButton(self.frame_btns)
    self.horizontalLayout_3.addWidget(self.btn_maximize)
    self.btn_close = QPushButton(self.frame_btns)
    self.btn_close.clicked.connect(mustekledialog.close)

    self.horizontalLayout_3.addWidget(self.btn_close)
    self.horizontalLayout.addWidget(self.frame_btns)
    self.verticalLayout.addWidget(self.title_bar)
    self.content_bar = QFrame(self.drop_shadow_frame)

    self.content_bar.setFrameShape(QFrame.StyledPanel)
    self.content_bar.setFrameShadow(QFrame.Raised)
    self.verticalLayout_4 = QVBoxLayout(self.content_bar)
    self.frame = QFrame(self.content_bar)
    self.frame.setFrameShape(QFrame.StyledPanel)
    self.frame.setFrameShadow(QFrame.Raised)
    self.mEkle_ad = QLineEdit(self.frame)
    self.mEkle_soyad = QLineEdit(self.frame)
    self.mEkle_tel = QLineEdit(self.frame)
    self.mEkle_mail = QLineEdit(self.frame)
    self.mEkle_TC = QLineEdit(self.frame)
    self.label = QLabel(self.frame)
    self.label_2 = QLabel(self.frame)
    self.label_3 = QLabel(self.frame)
    self.label_4 = QLabel(self.frame)
    self.label_5 = QLabel(self.frame)
    self.mEkle_adres = QPlainTextEdit(self.frame)
    self.mEkle_kaydet = QPushButton(self.frame)

    self.verticalLayout_4.addWidget(self.frame)
    self.verticalLayout.addWidget(self.content_bar)
    self.credits_bar = QFrame(self.drop_shadow_frame)
    self.credits_bar.setFrameShape(QFrame.NoFrame)
    self.credits_bar.setFrameShadow(QFrame.Raised)
    self.horizontalLayout_2 = QHBoxLayout(self.credits_bar)
    self.frame_label_credits = QFrame(self.credits_bar)
    self.frame_label_credits.setFrameShape(QFrame.StyledPanel)
    self.frame_label_credits.setFrameShadow(QFrame.Raised)
    self.verticalLayout_3 = QVBoxLayout(self.frame_label_credits)
    self.label_credits = QLabel(self.frame_label_credits)
    self.verticalLayout_3.addWidget(self.label_credits)
    self.horizontalLayout_2.addWidget(self.frame_label_credits)
    self.frame_grip = QFrame(self.credits_bar)
    self.frame_grip.setFrameShape(QFrame.StyledPanel)
    self.frame_grip.setFrameShadow(QFrame.Raised)
    self.horizontalLayout_2.addWidget(self.frame_grip)
    self.verticalLayout.addWidget(self.credits_bar)
    self.drop_shadow_layout.addWidget(self.drop_shadow_frame)


    mustekledialog.show()
    mustekledialog.exec_()

标签: pythonpyqtpyqt5qdialog

解决方案


一个简单的实现使用 QFrame 的子类(您将其用作“标题栏”)并实现鼠标事件以移动其顶级窗口。

其概念是获取鼠标按下事件的位置(局部于框架),计算鼠标移动事件的差值,并通过将当前窗口位置与上述差值相加来设置新位置。

class DragWidget(QFrame):
    startPos = None
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.startPos = event.pos()

    def mouseMoveEvent(self, event):
        if event.buttons() == Qt.LeftButton and self.startPos is not None:
            delta = event.pos() - self.startPos
            self.window().move(self.window().pos() + delta)

    def mouseReleaseEvent(self, event):
        self.startPos = None


class YourWindow(QMainWindow):
    def Musteri_Ekle_Penceresi(self):
        # ...
        self.title_bar = DragWidget(self.drop_shadow_frame)
        # ...

推荐阅读