自定义窗口框架在qt版本中表现不同(ANGLE与OpenGL)

Mar*_*zos 9 c++ opengl winapi qt qt-quick

我的任务是为QtQuick创建一个窗口,可以像普通窗口一样使用它,但具有自定义框架外观(不是默认的系统装饰).我想实现类似于Visual Studio窗口或类似的效果.

允许我实现该目标的代码如下所示:

main.cpp中

#include <QtQuick/qquickpainteditem.h>
#include <qapplication.h>
#include <qqmlengine.h>
#include <QtQuick/qquickwindow.h>

class frameLess :
    public QQuickWindow
{
public:
    frameLess(QWindow *parent = 0) :QQuickWindow(parent) { }

    bool nativeEvent(const QByteArray& eventType, void* message, long* result)
    {
        MSG *msg = static_cast<MSG *>(message);

        switch (msg->message)
        {
        case WM_SHOWWINDOW:
            // after that call Qt considers window as frameless
            setFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
            // that call force the Windows to serve users mouse events like in standard window
            SetWindowLongPtr(msg->hwnd, GWL_STYLE, WS_POPUP | WS_CAPTION | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX);
            return false;

        case WM_NCCALCSIZE:
            // prevent the Windows from painting the frame
            *result = 0;
            return true;

        default:
            break;
        }

        return false;
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    qmlRegisterType<frameLess>("fb", 1, 0, "FrameLess");

    QQmlEngine engine;
    QQmlComponent *component = new QQmlComponent(&engine);

    QObject::connect(&engine, SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit()));

    component->loadUrl(QUrl("qrc:////main.qml"));

    if (!component->isReady())
    {
        qWarning("%s", qPrintable(component->errorString()));
        return -1;
    }

    QObject *topLevel = component->create();
    QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);

    QSurfaceFormat surfaceFormat = window->requestedFormat();
    window->setFormat(surfaceFormat);
    window->show();

    return app.exec();
}
Run Code Online (Sandbox Code Playgroud)

main.qml

import fb 1.0
import QtQuick 2.2
import QtQuick.Controls 1.1

FrameLess {
    color:"lightgray"
    Rectangle {
        width: 45
        height: 45
        color: "green"
        anchors {
            top: parent.top
            left: parent.left
        }

        MouseArea {
            anchors.fill: parent
            hoverEnabled: true;
            onEntered: parent.color="red"
            onExited: parent.color="green"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,应显示左上角带有绿色矩形的无框窗口.此外,当鼠标悬停时,该矩形应该将颜色更改为红色.

当我使用基于ANGLE的Qt构建构建时,一切都按预期工作.

预期的窗口

但是,我的团队正在使用基于OpenGL的Qt构建.问题是,当我的代码链接到这样的Qt版本时,绘制区域会移动窗口框架的大小:

窗口与移动的绘画区域

更重要的是,只有油漆区域被移动.例如,鼠标命中箱位于适当的位置.因为hitboxes和场景项坐标是不同步的.(MouseArea的交互区域位于与填充的矩形不同的位置)

窗口与移动的绘画区域和悬停的矩形hitbox

我的期望是使用不同的Qt构建不应该影响最终的应用程序.

我的问题是为什么使用基于OpenGL的Qt构建会影响窗口外观以及如何实现可移植(跨Windows Qt构建)预期的行为.

我使用的构建是:

  • 适用于Windows 32位的Qt 5.3.1(VS 2013,OpenGL,557 MB)
  • Qt 5.3.1 for Windows 32-bit(VS 2013,559 MB)

我正在使用Windows 8.1进行测试

更新: 似乎在Qt 5.4.0中修复了此错误

Rei*_*ica 1

这是一个 Qt 错误。请如此报告。您无需在代码中执行任何特殊操作即可使其正常运行。