Qt 工作 Windows 8 风格无框自定义窗口

2023-12-15

我最近在我的 Windows 7 机器上安装了适用于 Windows 的 Github,并且喜欢它的自定义框架,它非常适合整个应用程序主题,并且有自己的标题栏按钮,布局非常好,非常流畅,并且工作起来看起来非常自然和。

我做了一些挖掘,发现了 2 个可以完全清除边框的标志,经过一些定制后,我的应用程序也有了一个很好的定制外观,它很直观,但与所有具有旧 Windows 边框的应用程序不同。

问题是它不像其他窗口那样流畅和自然响应,它很糟糕,我很容易让窗口用鼠标移动,但它经常出现故障,并且能够移动到它不喜欢的区域单击并拖动禁用的按钮。

链接到 showMaximize 方法的最大化按钮只是放大了整个窗口以占据整个桌面,您仍然可以移动它(并没有真正最大化)。

该窗口不响应任何系统信号,例如单击任务栏将其最小化等。

经过大量修复后,我最终放弃了,这很遗憾,因为我真的很喜欢它的外观,而且它非常直观,就像 Windows 上的 github 非常直观一样。

有什么办法可以做到这一点,我真的还没准备好放弃。

我知道在制作原始Windows API应用程序时,您必须将其链接到XP内置样式,因为它默认继承Windows 95样式,也许有Qt未连接到的Windows 8样式,我不知道没有研究还没有走那么远。


通过单击任务栏最小化窗口

看起来Qt::FramelessWindowHint的实施是有限的。设置此标志后,Windows 认为该窗口无法最小化或最大化。我试过了这个解决方案在纯 winapi 中实现。通过单击任务栏最小化和恢复无框窗口效果很好。显然 Qt 设置了一些阻止此功能的错误标志。也许有一个很好的理由,我不知道。

我们可以将winapi和Qt一起使用,但是比较麻烦。首先,在设置窗口标志并使用 Qt 显示窗口后,应执行 winapi 代码。否则 Qt 将覆盖窗口标志。

另一个问题是,当我们使用 winapi 删除边框时,窗口几何形状突然发生变化,而 Qt 并不知道这一点。渲染和事件映射(包括鼠标单击位置)变得无效。我没有找到任何更新映射的记录方法。我发现我们可以告诉 Qt 屏幕方向已更改,并强制它重新计算窗口几何形状。但这看起来像是一个肮脏的黑客行为。还有QWidget::windowHandleQt 4 中缺少该功能,并且 Qt 5 中“可能会发生变化”。所以这种方法不可靠。但无论如何,现在可以了。以下是应放置在顶部窗口类构造函数中的完整代码(在 Windows 8 中测试):

#include "windows.h"
#include <QWindow>
//...
show();
HWND hwnd = reinterpret_cast<HWND>(effectiveWinId());
LONG lStyle = GetWindowLong(hwnd, GWL_STYLE);
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU);
SetWindowLong(hwnd, GWL_STYLE, lStyle);
setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
windowHandle()->reportContentOrientationChange(Qt::PrimaryOrientation);

解决这个问题的真正方法是修改Window Qt平台插件(参见Qt源码中的QWindowsWindow类)。可能有一种方法可以继承默认实现,修改它并在您的应用程序中使用。您也可以询问 Qt 开发人员这种行为是否合理或者是否是一个错误。我认为这个问题可以通过补丁来解决。

如果您仍然打算使用此代码并且还应该支持其他操作系统,请不要忘记将特定于 Windows 的实现包装在#ifdef Q_OS_WIN.

仅当单击标题栏且窗口未最大化时才启用窗口拖动

其他问题可以更容易地解决。当您处理鼠标事件以实现窗口拖动时,请检查窗口状态和事件位置,并在不需要时禁用移动。

void MainWindow::mousePressEvent(QMouseEvent *e) {
  if (!isMaximized() && 
      e->button() == Qt::LeftButton && 
      ui->title->geometry().contains(e->pos())) {
    window_drag_start_pos = e->pos();
  }
}

void MainWindow::mouseReleaseEvent(QMouseEvent *e) {
  window_drag_start_pos = QPoint(0, 0);
}

void MainWindow::mouseMoveEvent(QMouseEvent *e) {
  if (!window_drag_start_pos.isNull()) {
    move(pos() + e->pos() - window_drag_start_pos);
  }
}

void MainWindow::on_minimize_clicked() {
  showMinimized();
}

void MainWindow::on_maximize_clicked() {
  if (isMaximized()) {
    showNormal();
  } else {
    showMaximized();
  }
}

Here ui->title是用于显示假标题栏的标签,并且QPoint window_drag_start_pos是一个类变量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt 工作 Windows 8 风格无框自定义窗口 的相关文章

随机推荐

  • 我可以在这个复杂的不规则形状链接上使用CSS悬停吗

    我已经研究了很多可能的解决方案 但仍然没有找到有效的解决方案 我正在尝试使用 CSS 让我的链接在悬停时发光 我尝试使用矩形的每个版本来包围我的图像以链接它们 但有些非常小并且会重叠 有没有办法将多坐标合并到 CSS 中 我认为我的主要问题
  • 将 Web 应用程序发布到 Azure 网站暂存部署槽因 webjob 失败

    我刚刚为我的应用程序创建了一个新的部署槽 将发布配置文件导入到 Visual Studio 但部署后我收到此错误消息 错误 8 创建 WebJob 计划时发生错误 找不到与 WebSiteName myapp staging 和 WebSi
  • 在 Git 中查找更改最多的文件

    如何显示 Git 中最常更改的文件 您可以执行以下操作 git log pretty format name only sort uniq c sort rg head 10 日志仅输出每次提交中已更改的文件的名称 而其余部分仅排序并输出前
  • AbstractTableModel getValueAt 性能

    我是新手JTable 也许我不明白什么 假设我有ArrayList共 1000 个Students id name surname age 我想向所有学生展示JTable 据我所知 我必须创造StudentTableModel that e
  • “类型*名称”和类型*名称”有什么区别?[重复]

    这个问题在这里已经有答案了 我是 C 新手 我找不到任何地方将 放在类型后面或名称前面有什么区别 例如 两者之间的区别是什么 int p int p C 编译器忽略空格 字符常量和字符串文字内的空格除外 代表着 int p int p in
  • Excel VBA 更新:查找数据、循环多个工作表、复制范围

    昨天更新此线程 Excel VBA 查找数据 循环多个工作表 复制特定单元格范围 特别感谢 findwindow 让我走到这一步 我在某个部分不断收到运行时 91 错误 并最终放入 If Then 语句以跳到下一张表 但现在我在其正下方的行
  • 用python将假分数转换为带分数

    我需要使用 python 将假分数转换为带分数 甚至将浮点数转换为带分数 我的代码如下 from fractions import Fraction numerator int input Enter numerator denominat
  • 在 MagicalRecord 中使用现有的 SQLite 数据库

    我创建了一个 SQLite 数据库 其中包含一些 JSON 的记录 使用本教程 我想使用 MagicalRecord 来查询它 MagicalRecord 看到 NSManagedObject BlogPost 并且可以创建记录 但它看不到
  • Nginx 由于不允许的 MIME 类型(“text/html”)而被阻止。角8

    everythink 与这些代码配合得很好 http include mime types default type application octet stream log format main remote addr remote u
  • 如何展平多维数组?

    在 PHP 中 是否可以在不使用递归或引用的情况下展平 双 多 维数组 我只对值感兴趣 因此可以忽略键 我在想array map and array values 可以在以下位置找到更新的解决方案下面这个答案 As of PHP 5 3最短
  • 递归导致的分段错误

    我正在编写一个程序 该程序将获取 1 10 之间的数字并显示排列数字的所有可能方式 前任 输入 3 输出 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 每当我输入 9 或 10 时 程序就会给出分段错误并转储核心
  • 为什么浏览器将 tbody 元素插入到 table 元素中?

    我正在使用原始 html 和 JQuery 尝试一些想法 我所做的一件事是创建一个包含一组行的表格元素 table tr td Title td tr tr td 1 td tr tr td 2 td tr tr td 3 td tr tr
  • 解析 XML 内容 - C#

    我使用 XML 的时间不长 需要从 XML 响应中提取有用的信息 如果有 2 个相同但名称不同的标签 例如
  • SUMIF 仅过滤数据

    我有一个 Excel 公式 可以对特定数据列进行求和 SUMIF Data E E E 89 Data F F 我正在寻找添加一个我想要过滤的 G 列 因此 理想情况下 当我单击 数据 gt 筛选 时 我可以使 SUMIF 仅对 G 列中筛
  • 有关 using 语句的一些高级问题

    我知道这里有很多关于如何使用 using 语句和调用 Dispose 方法的线程 我已经阅读了其中的大部分主题 如果我调用 Dispose 它会调用 Close 吗 如果我想使用一个对象 比如 SqlDataReader 但随后在另一个代码
  • 使用 XPath 访问 XML 中的注释

    如何使用 XPath 访问 XML 文档中的注释 例如 table table
  • 如何将mysql表的行转置为列

    这是我当前的 mysql 表的样子 PunchID EmpID PunchEvent PunchDateTime 1 0456 clockin 5 14 2013 8 36 26 AM 48 0456 breakout 5 14 2013
  • 分散 Flask 模型时,引发 RuntimeError: 'application not Registered on db'

    我正在通过分散模型 蓝图来重构我的 Flask 应用程序 但遇到运行时错误 def create app app flask Flask app app config SQLALCHEMY DATABASE URI sqlite app r
  • 优化 Internet Explorer 11 的滚动速度

    我目前有一个类似议程的应用程序 其中第一列绝对水平 第一行绝对垂直 我通过捕获滚动效果并更改其附加的 CSS 类的 left 或 top 属性来实现此目的 这些课程最多可达 700 个项目 每天 2 年 window scroll func
  • Qt 工作 Windows 8 风格无框自定义窗口

    我最近在我的 Windows 7 机器上安装了适用于 Windows 的 Github 并且喜欢它的自定义框架 它非常适合整个应用程序主题 并且有自己的标题栏按钮 布局非常好 非常流畅 并且工作起来看起来非常自然和 我做了一些挖掘 发现了