测试环境: KUbuntu 20.04, Ubuntu 18.04.4
最近做了一个Qt无边框的程序,发现用Qt MouseMoveEvent 代码移动窗体,无法移出屏幕.
经过测试,发现就算带有系统边框,也无法移出屏幕,但是按住系统标题栏进行移动就可以.
在网上搜索了很久找到了对应的方法:
原文地址:
主要代码:
一.需要安装x11的开发环境
sudo apt install libxau-dev libx11-dev libxext-dev libxtst-dev
二.pro改动:
unix {
QT += x11extras
LIBS += -lX11
}
3.#xxxwidget.cpp
#ifdef Q_OS_LINUX
#include <X11/Xlib.h>
#include <QX11Info>
#endif
#include <QMouseEvent>
void xxxx::mousePressEvent(QMouseEvent *e)
{
if(pMoveWidget && !pMoveWidget->isFullScreen && !pMoveWidget->isMaximized())
{
m_pressed = true;
m_pressedMovePos = pMoveWidget->pos();
m_pressedPos = this->mapToGlobal(e->pos());
}
e->accept();
}
void xxxx::mouseMoveEvent(QMouseEvent *e)
{
if(pMoveWidget && m_pressed)
{
QPoint pos = this->mapToGlobal(e->pos());
#ifdef Q_OS_LINUX
XEvent event;
memset(&event, 0, sizeof(XEvent));
Display *display = QX11Info::display();
event.xclient.type = ClientMessage;
event.xclient.message_type = XInternAtom(display, "_NET_WM_MOVERESIZE", False);
event.xclient.display = display;
//wid 是当前程序的 window id,可以通过 QWidget->wId()获得,QWidget 必须实例化
event.xclient.window = (XID)(pMoveWidget ->winId());
event.xclient.format = 32;
event.xclient.data.l[0] = pos.x();
event.xclient.data.l[1] = pos.y();
event.xclient.data.l[2] = 8;
event.xclient.data.l[3] = Button1;
event.xclient.data.l[4] = 1;
XUngrabPointer(display, CurrentTime);
XSendEvent(display,
QX11Info::appRootWindow(QX11Info::appScreen()),
False,
SubstructureNotifyMask | SubstructureRedirectMask,
&event);
XFlush(display);
#else
pMoveWidget->move(m_pressedMovePos/*按下时的窗口坐标*/ + pos - m_pressedPos/*按下时的屏幕坐标*/);
#endif
}
e->accept();
}