我最近在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::windowHandle
功能在Qt 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();
}
}
这ui->title
是用于显示假标题栏的标签,并且QPoint window_drag_start_pos
是一个类变量。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句