黒い雪*_*黒い雪 4 qt github stylesheet windows-8
我最近在我的Windows 7机器上安装了Github for Windows并且喜欢它的自定义框架,它非常适合整个应用程序主题,并且它有自己的标题栏按钮,这些按钮非常好,非常流畅,并且看起来很自然用.
我做了一些挖掘,发现2个标志可以完全清除边框,经过一些自定义后,我的应用程序也有一个很好的自定义外观,直观但与旧的Windows边框的所有应用程序不同.
事情是,它不像其他窗户那样流畅自然地响应,它很奇怪,我很容易让窗户用鼠标移动但它经常出现故障,并且能够移动到它不应该喜欢的区域单击并拖动禁用的按钮.
与showMaximize方法相关联的最大化按钮只是放大整个窗口占据整个桌面,你仍然可以移动它(真的不是真正最大化).
该窗口没有响应任何系统信号,如单击任务栏以最小化它等.
经过大量的修复之后,我终于放弃了,因为我真的很好看,看起来非常直观,就像github for Windows一样非常直观.
我有什么方法可以做到这一点,我还没准备好放弃.
我知道在制作原始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);
Run Code Online (Sandbox Code Playgroud)
解决此问题的真正方法是修改Window Qt平台插件(请参阅Qt源中的QWindowsWindow类).可能有一种方法可以继承默认实现,修改它并在您的应用中使用.你也可以问Qt开发人员这种行为是否合理,还是一个bug.我认为这个问题可以用补丁修复.
如果您仍打算使用此代码并且还应支持其他操作系统,请不要忘记将特定于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();
}
}
Run Code Online (Sandbox Code Playgroud)
这ui->title是一个用于显示假标题栏的标签,QPoint window_drag_start_pos是一个类变量.