Qt在Linux下实现无边框可缩放的窗口

Qt在Linux下实现无边框可缩放的窗口

在Linux平台上做desktop应用的还是非常少的。所以基本上网上这部分资料是没有的。Linux平台又不像Win那么多API。这次的实现,本来自己想写xlib的函数的,然后机智的我从deepin的代码里把他们封装好的抠出来了,然后补充了一些x11的封装函数。来完成最终的效果。

本篇文章纯粹抛砖引玉,毕竟只是个demo。简单的说一下遇到的坑。

代码

实现上很简单,重写qt的三个函数就可以。

void FLWidget_Linux::mouseMoveEvent(QMouseEvent *event)
{
#ifdef Q_OS_LINUX
     const int x = event->x();
     const int y = event->y();

     if (resizingCornerEdge == XUtils::CornerEdge::kInvalid)
     {
      XUtils::UpdateCursorShape(this, x, y, this->layout()->contentsMargins(), ResizeHandleWidth);
     }
#endif

 return QWidget::mouseMoveEvent(event);
}

void FLWidget_Linux::mousePressEvent(QMouseEvent *event)
{
#ifdef Q_OS_LINUX
 const int x = event->x();
 const int y = event->y();
 if (event->button() == Qt::LeftButton)
 {
      const XUtils::CornerEdge ce = XUtils::GetCornerEdge(this, x, y, this->layout()->contentsMargins(), ResizeHandleWidth);
      if (ce != XUtils::CornerEdge::kInvalid)
      {
           resizingCornerEdge = ce;
           //send x11 move event dont send mouserrelease event
           XUtils::SendButtonRelease(this, event->pos(), event->globalPos());
           XUtils::StartResizing(this, QCursor::pos(), ce);
      }
 }
#endif
 return QWidget::mousePressEvent(event);

void FLWidget_Linux::mouseReleaseEvent(QMouseEvent *event)
{
#ifdef Q_OS_LINUX
     resizingCornerEdge = XUtils::CornerEdge::kInvalid;
#endif
     return QWidget::mouseReleaseEvent(event);
}

只重写这三个函数就可以完成对应的功能,当然还得有XUtils。
XUtils是deepin封装的一个功能namespace。封装了常用的xlib操作qt的widget的一些函数。
然后我补充了一个他们的函数

主要是调用的xlib的mousemove之后,Qt接受不到release事件,需要手动再发一个

XUtils::SendButtonRelease(this, event->pos(), event->globalPos());
void SendButtonRelease(const QWidget *widget,
          const QPoint &pos, const QPoint &globalPos)
{
 const auto display = QX11Info::display();
 const auto screen = QX11Info::appScreen();

 XEvent xevent;
 memset(&xevent, 0, sizeof(XEvent));

 xevent.type = ButtonRelease;
 xevent.xbutton.button = Button1;
 xevent.xbutton.window = widget->effectiveWinId();
 xevent.xbutton.x = pos.x();
 xevent.xbutton.y = pos.y();
 xevent.xbutton.x_root = globalPos.x();
 xevent.xbutton.y_root = globalPos.y();
 xevent.xbutton.display = display;

 XSendEvent(display, widget->effectiveWinId(), False, ButtonReleaseMask, &xevent);
 XFlush(display);
}

昨天整理了下文档,发到github上了,欢迎star跟fork

https://github.com/CryFeiFei/FLWidget

公众号

张小飞那些事儿

小程序

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值