#python #pyqt #mouseevent #qdialog
#python #pyqt #mouseevent #qdialog
Вопрос:
Итак, у меня есть безрамочный QDialog, который я хочу иметь возможность перемещать, просто щелкая и перетаскивая его. Учитывая приведенный ниже код, перетаскивание диалогового окна всегда привязывает самый верхний левый угол (0,0) диалогового окна к мыши. Как я могу обойти это, или, скорее, какова может быть математика для этого?
Стандартный QDialog со следующим базовым подклассом:
class Main(QtGui.QDialog):
def __init__(self, args):
QtGui.QDialog.__init__(self)
def mouseMoveEvent(self, event):
super(Main, self).mouseMoveEvent(event)
if self.leftClick == True: self.moveWindow(event.globalPos())
def mousePressEvent(self, event):
super(Main, self).mousePressEvent(event)
if event.button() == QtCore.Qt.LeftButton:
self.leftClick = True
def mouseReleaseEvent(self, event):
super(Main, self).mouseReleaseEvent(event)
self.leftClick = False
Ответ №1:
Вместо event.pos() попробуйте вызвать event.globalPos(). Из ссылки на QMouseEvent: «Если вы перемещаете виджет в результате события мыши, используйте глобальную позицию, возвращаемую globalPos(), чтобы избежать тряски».
Комментарии:
1. Отлично! Это сработало, я обновил свой приведенный выше код, чтобы показать, где я нахожусь на данный момент. Теперь мне нужно иметь возможность удерживать мышь там, где она находится по отношению к диалоговому окну, поскольку всякий раз, когда я щелкаю левой кнопкой мыши, чтобы перетащить диалоговое окно, верхний левый угол диалогового окна привязывается к мыши.
2. вы решили эту проблему? моя мышь также перемещается в верхний левый угол диалогового окна.. я не могу от этого избавиться
3. Нет, я еще этого не делал, я просто разобрался с его зависанием на данный момент. Надеюсь, кто-нибудь сможет прийти и помочь.
4. Привет, я столкнулся с той же проблемой и решил ее. Сохраните координаты первого щелчка в mousePressEvent:
self.clickX = event.x() self.clickY = event.y()
Затем переместите окно с поправкой на первоначальное местоположение щелчка:self.move(event.globalPos(event.globalX-self.clickX, event.globalY-self.clickY)
Ответ №2:
Предлагаемое решение перемещает окно, но курсор мыши перемещается на 0,0 окна. Я хотел, чтобы курсор мыши все время оставался на x, y окна.
Вот обновленная версия кода [в QT5]:
X=0
X2=8 #!!!!
Y=0
Y2=30 #!!!!
class Main(QtWidgets.QMainWindow):
leftClick = False #! IMPORTANT
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
def mouseMoveEvent(self, event):
super(Main, self).mouseMoveEvent(event)
if self.leftClick == True:
self.move(event.globalPos().x()-X-X2,event.globalPos().y()-Y-Y2)
def mousePressEvent(self, event):
super(Main, self).mousePressEvent(event)
if event.button() == QtCore.Qt.LeftButton:
self.leftClick = True
global X,Y
X=event.pos().x()
Y=event.pos().y()
def mouseReleaseEvent(self, event):
super(Main, self).mouseReleaseEvent(event)
self.leftClick = False
Для безрамочного окна (созданного с помощью window.setMask()
) мне нужны некоторые константы, такие как X2 и Y2, потому что «замаскированное» безрамочное окно немного меньше реального оформленного окна. Пока не знаю, как вычислить эту разницу.
ВВЕРХ.Спустя долгое время я обнаружил одну критическую ошибку. Если вы нажмете левую кнопку мыши на любой кнопке (сразу после запуска приложения) и отведете курсор мыши от этой кнопки, ваше приложение завершит работу, потому что мы ссылаемся на несуществующую переменную LeftClick. Вот почему в классе Main нам нужно создать LeftClick.