【问题标题】:QDialog not positioned correctlyQDialog 未正确定位
【发布时间】:2014-03-21 13:33:07
【问题描述】:

我遇到了 QDialog 的问题,它没有显示在父窗口的中心。 下面sn-p解释一下:

void MyWidget::showDialog() {
    QObject* p = parent();
    while (p!=0) {
        qDebug() << p;
        p = p->parent();
    }
    qDebug() << QApplication::activeWindow();

    MyClassDerivedFromQDialog dlg( this );
    if ( dlg.exec() != dlg.Accepted ) {
        return;
    }
    ... do something
}

qDebug 上的输出如下

QSplitter(0x2d89930, name = "splitter") 
MyWidget(0x2d89670, name = "widget") 
MainWindow(0x27ef20, name = "application")
MainWindow(0x27ef20, name = "application")

执行我的示例会在屏幕上的某处打开对话框。将 QApplication::activeWindow() 作为父级传递给对话框构造函数会导致一个以主窗口为中心的对话框。那么为什么会这样以及如何追踪问题呢?

【问题讨论】:

  • 在什么系统上你有这个问题?

标签: c++ qt


【解决方案1】:

我发现这种行为与对话框创建的时间有关。 如果您创建一个 QDialog(或派生类)对话框 parent 显示(例如,在父构造函数中),对话框将显示在不可预测的位置(或者至少,不是你期望它显示的地方)。 但是,如果对话框是在显示父级之后创建的,那么您将获得预期的行为。 例如,如果您有一个按钮调用您的对话框。按钮和对话框都是同一个小部件的子级,因此对话框父级与按钮父级相同。在这种情况下,建议将对话框创建延迟到单击按钮之前,而不是在此之前。 这样,您可以确保仅在显示父级后才创建对话框。

【讨论】:

    【解决方案2】:

    我不确定是否理解您的问题。

    QDialogs 始终以您作为父级传递的小部件为中心。这是设计使然。因此,如果您将“activeWindow()”作为父级传递,它将以活动窗口为中心。如果您将“this”作为父级传递,则对话框将位于 MyWidget 上方。

    您的对话在哪些方面不遵守这些规则?

    【讨论】:

    • 在 QDialog 描述中写道,对话框以父级顶级小部件为中心,即主窗口。我知道它的 exec 函数的描述略有不同。与许多其他 qdialog 类一起,它可以完美运行,甚至这个特定的类在其他地方也可以完美运行。无论如何,从某个位置调用的对话框不会出现在父窗口小部件上,它出现在屏幕的左侧,一半在桌面之外,并且远离应用程序窗口。我在 Windows 7 64 位上使用 qt 5.2。
    • 只是为了确保:如果您将“this”作为父级传递,您会从桌面获得一半的对话框?
    • 是的,但前提是我在 MyWidget 中显示对话框!在另一个位置使用完全相同的代码,完全相同的 Dialog 类按预期工作。这就是为什么我在这里放置父堆栈调试但我似乎是合理的。
    • 关于那个堆栈...它说“this”(即 MyWidget)有一个父 QSplitter,它有一个父 MyWidget,它有一个父 MainWindow。您是否有 两个 MyWidget 实例,它们是彼此的父级?另外请发布创建所有这些小部件(构造函数或其他)的代码。
    • MyClassDerivedFromQDialog::MyClassDerivedFromQDialog(QWidget *parent) : QDialog(parent), ui(new Ui::MyClassDerivedFromQDialog) { ui->setupUi(this); //去除 ?标题栏中的按钮 Qt::WindowFlags flags = windowFlags(); Qt::WindowFlags helpFlag = Qt::WindowContextHelpButtonHint;标志 = 标志 & (~helpFlag);设置窗口标志(标志); }
    【解决方案3】:

    Dialog 类通过

    实例化
    MyClassDerivedFromQDialog::MyClassDerivedFromQDialog(QWidget *parent) 
    : QDialog(parent), 
      ui(new Ui::MyClassDerivedFromQDialog) 
    { 
        ui->setupUi(this); 
    
        //remove the ? button in titlebar 
        Qt::WindowFlags flags = windowFlags(); 
        Qt::WindowFlags helpFlag = Qt::WindowContextHelpButtonHint; 
        flags = flags & (~helpFlag); 
        setWindowFlags(flags); 
    } 
    

    而且我总是在初始帖子中的 showDialog 函数中使用它。有时它会起作用...不,我没有两个 MyWiget,它们是彼此的父母。

    【讨论】:

    • 这是你应该检查的东西(我在提供的代码中看不到它):为什么你的调试输出显示一个祖先“MyWidget”而你认为它不是?!是否有您不打算创建的 MyWidget 实例?小部件是其自身的父级吗?在 MyWidget::showDialog() 中打印出“this”来比较地址。
    • 您在哪里看到了祖先 MyWidget?有两个 MainWindows 但这是因为 QApplication::activeWindow() 写入调试输出
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 2015-07-16
    • 1970-01-01
    相关资源
    最近更新 更多