【问题标题】:Why am I getting QWindowsWindow::setGeometry: Unable to set geometry warning with Qt 5.12.0为什么我收到 QWindowsWindow::setGeometry: Unable to set geometry warning with Qt 5.12.0
【发布时间】:2019-01-22 11:35:44
【问题描述】:

我将一些代码从 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();
}

mainframe.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)来删除警告,但是为什么我们要对我们创建的每个小部件都这样做呢?有没有办法永久解决这个问题?

【问题讨论】:

    标签: c++ qt


    【解决方案1】:

    正如您所提到的,此问题仅发生在 Windows 中:QWindowsWindow 类是 windows 平台插件的一部分。查看 Qt 的源代码 (qwindowswindow.cpp@QWindowsWindow::setGeometry),没有直接的方法可以暂停该特定消息。

    我现在能想到的唯一全局解决方案是使用message handler 过滤警告消息:

    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 将自己的按钮添加到框架中。在您的示例中,对话框添加了三个按钮:系统按钮(icon,左上角)、帮助按钮和关闭按钮。帮助和关闭按钮具有固定大小,恰好大于QDialog 的框架(计算为请求大小和minimumSize 之间的最大值)。然后会生成警告:您请求的大小与 Windows 创建的不匹配:

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

    【讨论】:

    • 谢谢。但我更多的是寻找一种方法来修复警告而不是忽略它。
    • @jpo38 我添加了一些可能对您有所帮助的信息。我认为不存在全局修复。
    【解决方案2】:

    问题已报告给 Qt: https://bugreports.qt.io/browse/QTBUG-73258

    到OP中的代码是可以的,只是Qt的一个bug。

    它被标记为“P2 重要”,因此希望它应该在下一个版本中得到修复。


    更新:Qt 6.2.2 中仍未修复...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 2022-12-02
      • 2017-04-07
      • 2020-09-18
      • 2022-12-09
      • 2022-12-26
      相关资源
      最近更新 更多