2015-06-30 4 views
0

У меня есть подкласс QGraphicsView, где в контекстном меню на элементе я хочу показать диалог свойств.Как показать 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; 
} 

Вид помещен в GroupBox ... так что родитель является GroupBox ...

Как я могу вызвать диалог с помощью одного из родителей?

ответ

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(); 
} 
+0

С этим изменением, мое окно все равно будет отображаться в центре окна, не выше QGraphicsView. – Thalia

+0

@Thalia Это ожидаемое поведение. Если вы хотите показать его точно по центру под виджета окна верхнего уровня, как я теперь предполагаю, вы должны сделать это вручную. Обратите внимание, однако, что модальные диалоги ведут себя по-разному на разных платформах, поэтому ваши варианты позиционирования могут быть неуместными или игнорироваться. Например, на Mac модальные диалоги отображаются как листы, выходящие из строки заголовка окна - поэтому не имеет значения, что вы хотите разместить его где-то в другом месте, это просто не будет выглядеть правильно для платформы, и по умолчанию ваше позиционирование выбор игнорируется. –

+0

@Thalia Ручное позиционирование диалогового окна не является тривиальным, если только диалоговое окно не имеет фиксированного размера, так как размер диалогового окна неизвестен до тех пор, пока он не будет показан, поэтому вам нужно будет активировать ваш код позиционирования, как только цикл события обработает все связанные события к изменению видимости диалога. Я боюсь, что точное поведение здесь будет очень зависимым от платформы, поэтому сомнительно, имеет ли смысл делать попытку. Вы определенно захотите протестировать его на всех платформах, на которые настроены таргетинг. –

 Смежные вопросы

  • Нет связанных вопросов^_^