简体   繁体   English

Qt-跨平台行为

[英]Qt - cross platform behaviour

I am trying to deploy a cross platform Qt application written in c++. 我正在尝试部署用C ++编写的跨平台Qt应用程序。 It works fine on my Ubuntu Linux but when I run it on Windows the application's main window's position gets set on the very top left point of the screen with the upper frame (that holds the minimize, maximize, close buttons) missing . 它在Ubuntu Linux上可以正常运行,但是当我在Windows上运行时,应用程序主窗口的位置设置在屏幕的最左上角,而上部框架(包含最小,最大化,关闭按钮) 丢失了

That is it until i resize the main window (in this case making the width smaller from the right). 就是这样,直到我调整主窗口的大小(在这种情况下,使宽度从右变小)。 When this happens the upper frame and the control buttons appear as in the visualization I provided. 发生这种情况时,如我提供的可视化效果所示,上部框架和控制按钮出现。

看这里。

Note: I've removed all widgets on the app so they do not аppear as a distraction. 注意:我已经删除了该应用程序上的所有小部件,以免它们分散注意力。

Note2: It appears the maximize button is disabled, which is not the case inside Ubuntu. 注意2:似乎最大化按钮被禁用,在Ubuntu中不是这种情况。 I have not set any window flags. 我没有设置任何窗口标志。

How do i visualize the upper frame at the very start of the application without the need to resize the window. 我如何在应用程序开始时可视化上部框架,而无需调整窗口大小。 I understand its an OS specific behaviour. 我了解其特定于操作系统的行为。 Setting the main window's geometry with a starting point with a higher y value does NOT help. 使用较高y值的起点设置主窗口的几何形状无济于事。 It still pops at the very top left of the screen. 它仍然弹出在屏幕的左上角。

try to use QWidget::move to set the Window position after setGeometry . 尝试使用QWidget :: move设置setGeometry之后的Window位置。

If the widget is a window, the position is that of the widget on the desktop, including its frame. 如果窗口小部件是窗口,则位置是桌面上窗口小部件(包括其框架)的位置。

You ask a question about cross-platform UI code, and then you don't show the full code. 您询问有关跨平台UI代码的问题,然后您不显示完整的代码。 Please show the full code. 请显示完整代码。

The one line of code you do show does something in the wrong way: if you want to maximize a window, call the appropriate function, instead of setting its absolute size that you think shows the window maximized. 您显示的一行代码以错误的方式执行了某些操作:如果要最大化窗口,请调用适当的函数,而不是设置您认为显示最大化的窗口的绝对大小。 Windows, their decorations and their placement are very very platform specific, and you should prefer their cross-platform abstractions over trying to do them yourself. Windows,它们的装饰和它们的位置非常特定于平台,并且您应该更喜欢它们的跨平台抽象,而不是自己尝试做。

Concretely: the window positioning handles the decorations (title bar) differently on Windows and on Ubuntu. 具体来说:窗口位置在Windows和Ubuntu上对装饰(标题栏)的处理方式不同。 There is absolutely nothing you can do about it except not position your windows absolutely like this. 除了绝对不要像这样放置窗户外,您对此无能为力。

In the MainWindow constructor at the end this->setGeometry(0, 0, 1336, 600); 在MainWindow构造函数的末尾this->setGeometry(0, 0, 1336, 600);

That's the problem. 那就是问题所在。 setGeometry deals with the geometry of the client area. setGeometry处理客户区的几何。 This is well documented . 这是有据可查的 You should use move to change the position of the widget frame. 您应该使用move更改小部件框架的位置。 To set the size of the frame requires the knowledge of the frame's incremental width and height: 要设置框架的大小,需要了解框架的增量宽度和高度:

bool setWidgetFrameGeometry(QWidget *w, const QRect &r) {
  auto frame = w->frameGeometry().size();
  auto client = w->size();
  auto delta = frame - client;
  auto maxDelta = 128;
  if (delta.width() > 0 && delta.width() < maxDelta 
      && delta.height() > 0 && delta.height() < maxDelta) {
    w->move(r.topLeft());
    w->resize(r.size() - delta);
    return true;
  }
  return false;
}

The call may need to be deferred to when the event loop had a chance to run: 可能需要将调用推迟到事件循环有机会运行时:

auto setter = [this]{ return setWidgetFrameGeometry(this, {0,0,1336,600}); };
if (!setter())
  QTimer::singleShot(0, this, setter);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM