首页 文章

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

提问于
浏览
9

我的任务是为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();
}

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"
        }
    }
}

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

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

Window which is expected

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

Window with shifted painting area

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

Window with shifted painting area and hovered rectangle hitbox

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

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

我使用的构建是:

  • Qt 5.3.1 for Windows 32-bit(VS 2013,OpenGL,557 MB)

  • Qt 5.3.1 for Windows 32-bit(VS 2013,559 MB)

我正在使用Windows 8.1进行测试

Update: 在Qt 5.4.0中似乎修复了这个错误

1 回答

  • 1

    这是一个Qt错误 . 请报告 . 您不需要在代码中执行任何特殊操作即可正常运行 .

相关问题