Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: vladmailbox от Мая 26, 2010, 16:08



Название: Диалог с динамической загрузкой
Отправлено: vladmailbox от Мая 26, 2010, 16:08

Нужно сделать диалог с динамически загружаемым интерфейсом.
Для этого делаю класс наследуемый от QDialog. В конструкторе пишу:

UiDialog::UiDialog(QString FormName, QWidget *parent) : QDialog(parent)
{
    setAttribute(Qt::WA_DeleteOnClose);
    owner = 0;

    QUiLoader loader;
    QFile uiFile(FormName );
    uiFile.open(QIODevice::ReadOnly);
    ui = (QDialog*)loader.load(&uiFile, parent);
    uiFile.close();
   
}


При этом если пишу в коде
UiDialog * dlg = new UiDialog(mainWnd->PrgPath() + "/" + name, this); dlg->exec(),
то открывается пустой диалог, а если принудительно сделать ui->Visible(true), то отоброжается отдельно
пустое окно диалога и отдельно UI. Как их связать?

Если сделать вместо dlg->exec() ui->exec() и работать с ui вместо dlg, то все
на первый взгляд работает, но тогда не удается сделать reject при неправильном
вводе данных, т.к. переопределение вирт. метода accept() ничего не дает.


Название: Re: Диалог с динамической загрузкой
Отправлено: crossly от Мая 26, 2010, 16:18
для этого есть setupUi


Название: Re: Диалог с динамической загрузкой
Отправлено: GreatSnake от Мая 26, 2010, 16:23
Код
C++ (Qt)
void UiDialog::accept()
{
}
 
void UiDialog::reject()
{
}
 
int UiDialog::exec()
{
   return ui->exec();
}
 
UiDialog::UiDialog(QString FormName, QWidget *parent) : QObject(parent)
{
   QUiLoader loader;
   QFile uiFile(FormName );
   uiFile.open(QIODevice::ReadOnly);
   ui = (QDialog*)loader.load(&uiFile, parent);
   uiFile.close();
 
  if( ui )
  {
     connect( ui, SIGNAL(accepted()), this, SLOT(accept()) );
     connect( ui, SIGNAL(rejected()), this, SLOT(reject()) );
  }
}
 

Таким образом ты получаешь фейковый QDialog :)


Название: Re: Диалог с динамической загрузкой
Отправлено: GreatSnake от Мая 26, 2010, 16:29
crossly
Цитировать
для этого есть setupUi
setupUi() используется для статических форм.
Здесь вопрос про динамические.


Название: Re: Диалог с динамической загрузкой
Отправлено: Alex Custov от Мая 26, 2010, 17:35
Чтобы так сделать, загружаемый файл должен быть наследником QWidget, а не QDialog. Т.к. наличие родителя для этих двух виджетов отличается - QWidget встраивается в родителя, а QDialog всегда становится top-level окном (у тебя так и происходит).

К тому же просто указать родителя в load() будет недостаточно - полученный виджет надо встроить в layout. Что-то типа

Код
C++ (Qt)
UiDialog::UiDialog(QString FormName, QWidget *parent) : QDialog(parent)
{
   layout = new QGridLayout(...);
   setLayout(layout);
 
   QUiLoader loader;
   QFile uiFile(FormName );
   uiFile.open(QIODevice::ReadOnly);
   ui = (QWidget *)loader.load(&uiFile, this);
   uiFile.close();
 
   layout->addWidget(ui);
}
 


и не забывай проверять результат вызова load() на 0.


Название: Re: Диалог с динамической загрузкой
Отправлено: Kolobok от Мая 26, 2010, 17:57
Код:
ui = (QWidget *)loader.load(&uiFile, this);

зачем здесь cast?


Название: Re: Диалог с динамической загрузкой
Отправлено: Igors от Мая 26, 2010, 18:22
Грузите из ресурсов QWidget и вставляйте его в заранее созданный QDialog. Когда потребуется, удаляете этот виджет и загружаете новый. Возможно потребуется подогнать размеры загруженного под видимый (или наоборот)

Цитировать
Грузите апельсины бочками.
Братья Карамазовы


Название: Re: Диалог с динамической загрузкой
Отправлено: Alex Custov от Мая 26, 2010, 18:24
Код:
ui = (QWidget *)loader.load(&uiFile, this);

зачем здесь cast?

ах да, не нужен.


Название: Re: Диалог с динамической загрузкой
Отправлено: vladmailbox от Июня 07, 2010, 13:09
После ряда экперементов получилось так:

Код:
UiDialog::UiDialog(QString FormName, QWidget *parent) : QDialog(parent)
{
    setAttribute(Qt::WA_DeleteOnClose);
    setWindowFlags(windowFlags() ^ Qt::WindowContextHelpButtonHint);
    owner = 0;

    QLayout* layout = new QVBoxLayout(this);
    setLayout(layout);

    QUiLoader loader;
    QFile uiFile(FormName );
    uiFile.open(QIODevice::ReadOnly);
    ui = loader.load(&uiFile, parent);
    uiFile.close();

    layout->addWidget(ui);
    this->setMinimumWidth(ui->width());
    this->setMinimumHeight(ui->height()+this->frameSize().height()-this->height());
    ui->setVisible(true);

    connect( ui, SIGNAL(accepted()), this, SLOT(slotAccepted()) );
    connect( ui, SIGNAL(rejected()), this, SLOT(slotRejected()) );

}


void UiDialog::slotAccepted()
{
    isValid = true;
    emit receiveSignal("OK");
    if( isValid )
    {
        QDialog::accept();
    }
    else
    {
        ui->setVisible(true);
    }
}

void UiDialog::slotRejected()
{
    isValid = true;
    emit receiveSignal("Cancel");
    if( isValid )
    {
        QDialog::reject();
    }
    else
    {
        ui->setVisible(true);
    }
}

< пользуемся тэгом "код"