打开 QComboBox 会触发 mouseMoveEvent 但不会触发 mousePressEvent

opening QComboBox triggers mouseMoveEvent but not mousePressEvent

在我的代码中,我有两个组合框,我特意设计了一个无框无边框window;所以我必须手动定义鼠标事件以在单击和拖动时移动 window,并调整边缘大小。 没有组合框它工作得很好,但不知何故点击组合框打开它们只触发 mouseMoveEvent 而不是 mousePressEvent,导致错误关于没有 self.old_Pos。如果我们取消注释 init 函数的最后三行,这个错误就消失了,但是在打开连击时整个 window 将被替换。我该如何克服这个问题?

from PyQt5.QtWidgets import *
from PyQt5 import QtCore
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class MainWindow(QWidget):
    switch_window = QtCore.pyqtSignal()
    def __init__(self):
        QWidget.__init__(self)
        self.combo1 = QComboBox()
        for i in range (0,10):
            self.combo1.addItem('Combo1 label %s' %str(i))
        self.combo2 = QComboBox()
        for i in range (0,15):
            self.combo2.addItem('Combo1 label %s' %str(i))
        main_layout = QVBoxLayout()
        layout = QHBoxLayout()
        layout.addWidget(self.combo1)
        layout.addWidget(self.combo2)
        # design title bar
        title_bar = QHBoxLayout()
        title_bar.setObjectName('HeaderBar')
        title_bar.setContentsMargins(0,0,0,0)
        title = QLabel('title bar')
        btn_size = 35
        btn_close = QPushButton("x")
        btn_close.clicked.connect(self.btn_close_clicked)
        btn_close.setFixedSize(btn_size,btn_size)
        btn_close.setStyleSheet("background-color: red;")
        btn_min = QPushButton("_")
        btn_min.clicked.connect(self.btn_min_clicked)
        btn_min.setFixedSize(btn_size, btn_size)
        btn_min.setStyleSheet("background-color: gray;")
        self.btn_max = QPushButton("+")
        self.btn_max.clicked.connect(self.btn_max_clicked)
        self.btn_max.setFixedSize(btn_size, btn_size)
        self.btn_max.setStyleSheet("background-color: gray;")
        title.setAlignment(Qt.AlignCenter)
        title_bar.addWidget(title)
        title_bar.addWidget(btn_min)
        title_bar.addWidget(self.btn_max)
        title_bar.addWidget(btn_close)
        main_layout.addLayout(title_bar)
        main_layout.addLayout(layout)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setLayout(main_layout)
        #self.old_Pos = QPoint(0,0)
        #self.old_width = self.width()
        #self.old_height = self.height()
    def mousePressEvent(self, event):
        self.old_Pos = event.globalPos()
        self.old_width = self.width()
        self.old_height = self.height()
    def mouseMoveEvent(self, event):
        delta = QPoint (event.globalPos() - self.old_Pos)
        if (self.old_Pos.x() > self.x() + self.old_width - 10) or (self.old_Pos.y() > self.y() + self.old_height - 10):
            self.setFixedSize(self.old_width + delta.x(),self.old_height + delta.y())
        else:
            self.move(self.x() + delta.x(), self.y() + delta.y())
            self.old_Pos = event.globalPos()
    def btn_close_clicked(self):
        quit()
    def btn_max_clicked(self):
        if self.isMaximized():
            self.showNormal()
            self.btn_max.setText('+')
        else:
            self.showMaximized()
            self.btn_max.setText('R')
    def btn_min_clicked(self):
        self.showMinimized()        
app = QApplication([])
mainapp = MainWindow()
mainapp.show()
app.exec_()

我相信我已经解决了这个问题。 我们所要做的就是在__init__mouseReleaseEvent中定义self.old_Pos = None,并在mouseMoveEvent中放置一个if self.old_Pos:语句。 这是代码:

from PyQt5.QtWidgets import *
from PyQt5 import QtCore
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class MainWindow(QWidget):
    switch_window = QtCore.pyqtSignal()
    def __init__(self):
        QWidget.__init__(self)
        self.combo1 = QComboBox()
        for i in range (0,10):
            self.combo1.addItem('Combo1 label %s' %str(i))
        self.combo2 = QComboBox()
        for i in range (0,15):
            self.combo2.addItem('Combo2 label %s' %str(i))
        main_layout = QVBoxLayout()
        layout = QHBoxLayout()
        layout.addWidget(self.combo1)
        layout.addWidget(self.combo2)
        # design title bar
        title_bar = QHBoxLayout()
        title_bar.setObjectName('HeaderBar')
        title_bar.setContentsMargins(0,0,0,0)
        title = QLabel('title bar')
        btn_size = 35
        btn_close = QPushButton("x")
        btn_close.clicked.connect(self.btn_close_clicked)
        btn_close.setFixedSize(btn_size,btn_size)
        btn_close.setStyleSheet("background-color: red;")
        btn_min = QPushButton("_")
        btn_min.clicked.connect(self.btn_min_clicked)
        btn_min.setFixedSize(btn_size, btn_size)
        btn_min.setStyleSheet("background-color: gray;")
        self.btn_max = QPushButton("+")
        self.btn_max.clicked.connect(self.btn_max_clicked)
        self.btn_max.setFixedSize(btn_size, btn_size)
        self.btn_max.setStyleSheet("background-color: gray;")
        title.setAlignment(Qt.AlignCenter)
        title_bar.addWidget(title)
        title_bar.addWidget(btn_min)
        title_bar.addWidget(self.btn_max)
        title_bar.addWidget(btn_close)
        main_layout.addLayout(title_bar)
        main_layout.addLayout(layout)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setLayout(main_layout)
        self.work_with_combo = True
        self.old_Pos = None
    def mousePressEvent(self, event):
        self.old_Pos = event.globalPos()
        self.old_width = self.width()
        self.old_height = self.height()
    def mouseMoveEvent(self, event):
        if self.old_Pos:
            delta = QPoint (event.globalPos() - self.old_Pos)
            if (self.old_Pos.x() > self.x() + self.old_width - 10) or (self.old_Pos.y() > self.y() + self.old_height - 10):
                self.setFixedSize(self.old_width + delta.x(),self.old_height + delta.y())
            else:
                self.move(self.x() + delta.x(), self.y() + delta.y())
                self.old_Pos = event.globalPos()
    def mouseReleaseEvent(self, event):
        self.old_Pos = None
    def btn_close_clicked(self):
        quit()
    def btn_max_clicked(self):
        if self.isMaximized():
            self.showNormal()
            self.btn_max.setText('+')
        else:
            self.showMaximized()
            self.btn_max.setText('R')
    def btn_min_clicked(self):
        self.showMinimized()        
app = QApplication([])
mainapp = MainWindow()
mainapp.show()
app.exec_()

我一直在寻找这个解决方案永远。只是想非常感谢您发布解决方案。非常适合我!

对于只使用 Qt Creator 的人,这是我使用的最终代码:

//Declare oldPos in .h private
QPoint oldPos = QPoint();

void GiftCardDialog::mousePressEvent(QMouseEvent* event) {
    oldPos = event->globalPos();
}

void GiftCardDialog::mouseReleaseEvent(QMouseEvent *event) {
    (void)event;
    oldPos = QPoint();
}

void GiftCardDialog::mouseMoveEvent(QMouseEvent* event) {
    if(!oldPos.isNull()) {
        QPoint delta = event->globalPos() - oldPos;
        if(oldPos.x() > this->x() + this->width() - 10
                || oldPos.y() > this->y() + this->height() - 10) {

        } else {
            move(this->x() + delta.x(), this->y() + delta.y());
            oldPos = event->globalPos();
        }
    }
}