如何在QGraphicsView的中心显示QDialog?

时间:2015-06-30 15:16:38

标签: qt qdialog

我有一个QGraphicsView子类,在项目的上下文菜单中,我想显示一个属性对话框。

我希望对话框在视图中居中......

我现在拥有它,没有父母,它会显示在屏幕的中央。

MyView::MyView(QWidget *parent) : QGraphicsView(parent) {}

void MyView::showProperties()
{
    TabDialog *tabDialog = new TabDialog();  // shows in center of screen
//    TabDialog *tabDialog = new TabDialog(this); // doesn't show at all
//    TabDialog *tabDialog = new TabDialog((QWidget*)this->parent()); // doesn't show at all
    tabDialog->setWindowFlags(Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint);
    tabDialog->exec();
    delete tabDialog;
}

视图放在一个分组框中......所以父母是分组框......

如何使用父级调用对话框?

1 个答案:

答案 0 :(得分:0)

您必须将对话框设置为顶级窗口,而不仅仅是将嵌入到视图中的子窗口小部件。您的setWindowsFlags调用将重置对话框中的相关标志。您需要手动保存它们。

您也不应该使用exec()重新输入事件循环,因为这需要您的许多其他代码也需要重入。

最小修复如下:

void MyView::showProperties()
{
  auto dialog = new TabDialog(this);
  dialog->setWindowFlags(Qt::Dialog | 
                         Qt::WindowCloseButtonHint | 
                         Qt::WindowSystemMenuHint);
  dialog->setAttribute(Qt::WA_DeleteOnClose);
  dialog->show();
}

也许你想要缓存对话框:

class MyView : public ... {
  QPointer<TabDialog> m_tabDialog; // nulls itself when the dialog perishes
  QTimer m_tabDialogTimer;
  ...
};

MyView::MyView(...) {
  m_tabDialogTimer->setSingleShot(true);
  ...
}    

void MyView::showProperties() {
  if (! m_tabDialog) {
    m_tabDialog = new TabDialog(this);
    m_tabDialog->setWindowFlags(Qt::Dialog | 
                                Qt::WindowCloseButtonHint | 
                                Qt::WindowSystemMenuHint);
    QObject::connect(&m_tabDialogTimer, &QTimer::timeout, 
                     m_tabDialog, &QObject::deleteLater);
    QObject::connect(m_tabDialog, &QDialog::finished, [&this](int){
      // the dialog gets deleted 120 seconds after last use
      m_tabDialogTimer.start(120);
    });
  }
  m_tabDialogTimer.stop(); // reset pending timeout, if any
  m_tabDialog->show();
}