m0_37670973 2024-03-06 10:40 采纳率: 0%
浏览 27
已结题

关于#qt#的问题:QWidget设置Qt::FramelessWindowHint后,窗体原有任务栏功能和拖拽缩放功能消失

#QWidget设置Qt::FramelessWindowHint后,窗体原有任务栏功能和拖拽缩放功能消失

#软件用的QT6开发,目前使用了监听nativeEvent方法,能做到窗体移动和拖拽控制大小,但是任务栏功能消失了。请问资深的qt专家,上述的问题如何实现,目前网上的介绍大多从监控鼠标事件入手,自定义这些功能,效果不好。有如下几点期望:
1 鼠标调整窗口大小高效灵活
2 窗口移动时不卡顿
3 点击任务栏图标窗口能显示或隐藏

  • 写回答

23条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-03-06 10:40
    关注

    引自免费微信小程序:皆我百晓生

    在Qt中,当您设置了Qt::FramelessWindowHint属性时,窗口会失去系统默认的标题栏、边框以及任务栏操作。为实现自定义无边框窗口的同时保持高效的拖拽缩放和任务栏功能,您可以按照以下步骤进行:

    1. 实现窗口移动: 通过监听鼠标按下事件,并在鼠标移动时更新窗口的位置。
    void MainWindow::mousePressEvent(QMouseEvent *event)
    {
        if (event->button() == Qt::LeftButton) {
            mousePressPosition = event->globalPos() - this->frameGeometry().topLeft();
            event->accept();
        }
    }
    
    void MainWindow::mouseMoveEvent(QMouseEvent *event)
    {
        if (event->buttons() & Qt::LeftButton) {
            move(event->globalPos() - mousePressPosition);
            event->accept();
        }
    }
    
    1. 实现窗口大小调整: 监听鼠标在窗口边缘或角落按下并移动以改变窗口大小。
    bool isResizeArea(const QPoint &pos)
    {
        QRect rect = this->rect();
        int margin = 8; // 自定义可调整大小的边距
        return pos.x() >= rect.left() && pos.x() <= rect.right() - margin &&
               pos.y() >= rect.top() + margin && pos.y() <= rect.bottom() - margin;
    }
    
    void MainWindow::mousePressEvent(QMouseEvent *event)
    {
        if (isResizeArea(event->pos())) {
            resizing = true;
            resizeStartPoint = event->globalPos();
            resizeEdge = getResizeEdge(event->pos());
            event->accept();
        }
        // ...(上述窗口移动事件代码)
    }
    
    void MainWindow::mouseMoveEvent(QMouseEvent *event)
    {
        if (resizing) {
            QSize newSize = this->size();
            switch (resizeEdge) {
                case Top:
                    newSize.setHeight(resizeStartPoint.y() - event->globalY());
                    break;
                case Bottom:
                    newSize.setHeight(event->globalY() - resizeStartPoint.y());
                    break;
                case Left:
                    newSize.setWidth(resizeStartPoint.x() - event->globalX());
                    break;
                case Right:
                    newSize.setWidth(event->globalX() - resizeStartPoint.x());
                    break;
                case TopLeft:
                case BottomRight:
                    newSize.setWidth(resizeStartPoint.x() - event->globalX());
                    newSize.setHeight(event->globalY() - resizeStartPoint.y());
                    break;
                case TopRight:
                case BottomLeft:
                    newSize.setWidth(event->globalX() - resizeStartPoint.x());
                    newSize.setHeight(resizeStartPoint.y() - event->globalY());
                    break;
                default:
                    break;
            }
    
            // 添加最小尺寸限制
            newSize = newSize.expandedTo(minimumSize());
            setFixedSize(newSize);
            event->accept();
        }
        // ...(上述窗口移动事件代码)
    }
    
    Qt::Edges MainWindow::getResizeEdge(const QPoint &pos)
    {
        QRect rect = this->rect();
        int margin = 8;
        if (pos.y() <= margin) {
            if (pos.x() <= margin)
                return Qt::TopLeft;
            else if (pos.x() >= rect.right() - margin)
                return Qt::TopRight;
            else
                return Qt::Top;
        } else if (pos.y() >= rect.bottom() - margin) {
            if (pos.x() <= margin)
                return Qt::BottomLeft;
            else if (pos.x() >= rect.right() - margin)
                return Qt::BottomRight;
            else
                return Qt::Bottom;
        } else if (pos.x() <= margin)
            return Qt::Left;
        else if (pos.x() >= rect.right() - margin)
            return Qt::Right;
        else
            return Qt::NoEdge;
    }
    
    void MainWindow::mouseReleaseEvent(QMouseEvent *)
    {
        resizing = false;
    }
    
    1. 确保窗口在任务栏显示和隐藏: 虽然设置了Qt::FramelessWindowHint,但只要窗口是顶级窗口并且正常创建,它应该仍然会在任务栏上显示。要响应点击任务栏图标显示/隐藏窗口,需要处理show()hide()信号或者activateWindow()方法。例如,在你的主窗口类中:
    // 假设你有一个 TrayIcon 类实例 trayIcon
    QSystemTrayIcon *trayIcon = new QSystemTrayIcon(this);
    
    // 设置托盘图标和关联的上下文菜单
    // ...
    
    connect(trayIcon, &QSystemTrayIcon::activated, [this](QSystemTrayIcon::ActivationReason reason) {
        if (reason == QSystemTrayIcon::Trigger || reason == QSystemTrayIcon::DoubleClick)
            this->setVisible(!this->isVisible()); // 切换窗口显示与隐藏
    });
    
    // 在构造函数或初始化阶段设置好 trayIcon 后,记得调用 show()
    trayIcon->show();
    

    以上代码片段将帮助您实现一个无边框窗口的高效拖拽和缩放功能,同时确保窗口能够在任务栏正确显示和隐藏。请注意,根据您的具体需求可能需要对代码进行微调以适应不同的场景。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 3月8日
  • 创建了问题 3月6日

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改