我的任务是为 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 构建构建它时,一切都按预期工作。
但是,我的团队正在使用基于 OpenGL 的 Qt 构建。问题是,当我的代码链接到此类 Qt 版本时,绘画区域会按窗口框架的大小移动:
更重要的是,只有绘画区域被移动。例如,鼠标命中框位于适当的位置。因此,命中框和场景项目坐标是不同步的。 (MouseArea 的交互区域与其填充的 Rectangle 位于不同的位置)
我的期望是使用不同的 Qt 构建应该不会影响最终的应用程序。
我的问题是为什么使用基于 OpenGL 的 Qt 构建会影响窗口外观,以及我如何可移植地(跨 Windows Qt 构建)实现预期的行为。
我使用的构建是:
- 适用于 32 位 Windows 的 Qt 5.3.1(VS 2013、OpenGL、557 MB)
- Windows 32 位 Qt 5.3.1(VS 2013,559 MB)
我正在使用 Windows 8.1 进行测试
更新: Qt 5.4.0 好像修复了这个bug
最佳答案
这是一个 Qt 错误。请照原样报告。您无需在代码中执行任何特殊操作即可使其正常运行。
关于c++ - 自定义窗口框架在 qt 构建中表现不同(ANGLE 与 OpenGL),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24994033/