c++ 为什么我会得到QWindowsWindow::setGeometry:无法使用Qt 5.12.0设置几何警告

h6my8fg2  于 2023-03-25  发布在  Windows
关注(0)|答案(3)|浏览(423)

我把一些代码从Qt 5.6.0迁移到了5.12.0。令人惊讶的是,我收到了很多与QWindowsWindow::setGeometry相关的警告。每当一个对话框显示在另一个对话框的顶部时,我都会收到这个警告。
我可以在MCVE中隔离问题,它非常简单和最小化,所有的养育看起来都很好,但是,当按下按钮时,我们会得到警告:

QWindowsWindow::setGeometry: Unable to set geometry 132x30+682+303 on QWidgetWindow/'QDialogClassWindow'. Resulting geometry:  132x42+682+303 (frame: 4, 28, 4, 4, custom margin: 0, 0, 0, 0, minimum size: 116x42, maximum size: 16777215x16777215).

main.cpp:

#include <QApplication>
#include "mainframe.h"
#include <qDebug>

void MessageOutput( QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    qDebug() << msg;
}

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

    qInstallMessageHandler(MessageOutput);

    MainFrame wnd;
    wnd.show();

    return app.exec();
}

主机.h:

#include <QMainWindow>

class QPushButton;
class MainFrame : public QMainWindow
{
    Q_OBJECT

public:
    MainFrame();

public slots:
    void showPopup();

private:
    QPushButton* button;
};

mainframe.cpp:

#include "mainframe.h"

#include <QDialog>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>

MainFrame::MainFrame()
{
    QWidget* widget = new QWidget( this );
    widget->setLayout( new QVBoxLayout( widget ) );

    QPushButton* pTextButton = new QPushButton( "Show popup", widget );
    widget->layout()->addWidget( pTextButton );
    connect( pTextButton, SIGNAL(clicked()), this, SLOT(showPopup()) );

    setCentralWidget( widget );
}

void MainFrame::showPopup()
{
    QDialog dlg( this );
    dlg.setLayout( new QVBoxLayout() );
    dlg.layout()->addWidget( new QLabel("popup message",&dlg) );
    dlg.exec();
}

我在Windows 7和10下看到了这个问题。我做错了什么吗?
我知道可以通过设置setMinimumSize(参见https://stackoverflow.com/a/31231069/3336423)来删除警告,但是为什么我们要为我们创建的每个小部件都这样做呢?有没有一种方法可以永久解决这个问题呢?

x6yk4ghg

x6yk4ghg1#

正如您所提到的,此问题仅在Windows中发生:QWindowsWindow类是windows平台插件的一部分。查看Qt的源代码(qwindowswindow.cpp@QWindowsWindow::setGeometry),没有直接的方法来暂停特定的消息。
我现在能想到的唯一全局解决方案是使用消息处理程序过滤警告消息:

void myMessageOutput(QtMsgType type, const QMessageLogContext& context, const QString& msg)
{
  if (type != QtWarningMsg || !msg.startsWith("QWindowsWindow::setGeometry")) {
    QByteArray localMsg = msg.toLocal8Bit();
    fprintf(stdout, localMsg.constData());
  }
}

int main(int argc, char* argv[])
{
  qInstallMessageHandler(myMessageOutput);
  QApplication a(argc, argv);
  // ...
}

更新

其中一个问题是Windows会将自己的按钮添加到框架中。在您的示例中,对话框添加了三个按钮:系统按钮(左上角的 * 图标 *)、帮助按钮和关闭按钮。帮助和关闭按钮的大小是固定的,恰好大于QDialog的框架(计算为请求的大小和minimumSize之间的最大值)。然后生成警告:您请求的大小与Windows创建的大小不匹配:

如果您删除帮助按钮,例如(dlg.setWindowFlags(dlg.windowFlags() & ~Qt::WindowContextHelpButtonHint);),警告消失,而不设置窗口的最小尺寸。必须为每个显示的对话框采取手动操作,但我认为它比最小尺寸更容易自动化(通过工厂也许?):

xghobddn

xghobddn2#

该问题已报告给Qt:https://bugreports.qt.io/browse/QTBUG-73258
在OP中的代码是好的,这只是一个Qt的错误。
它被标记为“P2重要”,所以希望它应该在下一个版本中得到修复。
更新:在Qt 6.2.2中仍然没有修复...

5lhxktic

5lhxktic3#

请尝试设置maximumHeight,maximumWidth,minimumHeight,minimumWidth。
当窗口太大时,它对我很有效。

相关问题