Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 如何在QGraphicsView的中心显示QDialog?_Qt_Qdialog - Fatal编程技术网

Qt 如何在QGraphicsView的中心显示QDialog?

Qt 如何在QGraphicsView的中心显示QDialog?,qt,qdialog,Qt,Qdialog,我有一个QGraphicsView子类,在项目的上下文菜单上,我想显示一个属性对话框 我希望对话框在视图中居中 正如我现在看到的,在没有父对象的情况下,它显示在屏幕的中心 MyView::MyView(QWidget *parent) : QGraphicsView(parent) {} void MyView::showProperties() { TabDialog *tabDialog = new TabDialog(); // shows in center of scree

我有一个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;
}
视图被放置在一个组框中。。。所以父对象是groupbox


如何使用父窗口调用对话框?

您必须将对话框设置为顶级窗口,而不仅仅是嵌入视图中的子窗口小部件。
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();
}
类MyView:公共。。。{
QPointer m_tabDialog;//当对话框消失时,将自身置空
QTimer mu tabDialogTimer;
...
};
MyView::MyView(…){
m_tabDialogTimer->setSingleShot(真);
...
}    
void MyView::showProperties(){
如果(!m_tabDialog){
m_tabDialog=新tabDialog(本);
m_tabDialog->setWindowFlags(Qt::Dialog |
Qt::WindowCloseButtonHint |
Qt::WindowsystemEnuHint);
QObject::connect(&m_选项卡DialogTimer,&QTimer::timeout),
m_tabDialog,&QObject::deleteLater);
连接(m_tabDialog,&QDialog::finished,[&this](int){
//该对话框在上次使用120秒后被删除
定时器启动(120);
});
}
m_tabDialogTimer.stop();//重置挂起超时(如果有)
m_tabDialog->show();
}

通过此更改,“我的窗口”仍将显示在窗口的中心,而不是QGraphicsView的上方。@Thalia这是预期的行为。如果您希望将其显示在顶级窗口的子窗口小部件的正中央,正如我现在假定的那样,您需要手动进行定位。但是请注意,模态对话框在不同平台上的行为不同,因此您的定位选择可能不合适或被忽略。例如,在Mac电脑上,模态对话框显示为从窗口标题栏中掉落的纸张-因此,您是否希望将其放置在其他位置并不重要,它根本不适合平台,默认情况下,您的定位选择被忽略。@Thalia手动定位对话框并不是一件小事,除非对话框有固定的大小,因为对话框的大小在显示之前是未知的,所以在事件循环处理完与对话框可见性更改相关的所有事件后,您需要激活定位代码。我担心,这里的确切行为将非常依赖于平台,因此这是否有意义值得怀疑。你肯定想在所有你瞄准的平台上测试它。感谢Mac的例子-我从来没有注意到它(osx体验不多,但我确实想要多平台行为)。尽管如此,我还是希望如果一个小部件有一个父部件,就可以放在父部件的上方,而不必手动移动它。我想我的问题的答案是,这不是不可能的,但做我想做的事也不是明智的:——)