Russian Qt Forum
Апреля 19, 2025, 12:59 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Диалог с динамической загрузкой  (Прочитано 5528 раз)
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() ничего не дает.
Записан
crossly
Гость
« Ответ #1 : Мая 26, 2010, 16:18 »

для этого есть setupUi
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #2 : Мая 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 Улыбающийся
« Последнее редактирование: Мая 26, 2010, 16:33 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #3 : Мая 26, 2010, 16:29 »

crossly
Цитировать
для этого есть setupUi
setupUi() используется для статических форм.
Здесь вопрос про динамические.
Записан

Qt 5.11/4.8.7 (X11/Win)
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #4 : Мая 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.
« Последнее редактирование: Мая 26, 2010, 17:37 от Alex Custov » Записан
Kolobok
Гость
« Ответ #5 : Мая 26, 2010, 17:57 »

Код:
ui = (QWidget *)loader.load(&uiFile, this);

зачем здесь cast?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Мая 26, 2010, 18:22 »

Грузите из ресурсов QWidget и вставляйте его в заранее созданный QDialog. Когда потребуется, удаляете этот виджет и загружаете новый. Возможно потребуется подогнать размеры загруженного под видимый (или наоборот)

Цитировать
Грузите апельсины бочками.
Братья Карамазовы
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #7 : Мая 26, 2010, 18:24 »

Код:
ui = (QWidget *)loader.load(&uiFile, this);

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

ах да, не нужен.
Записан
vladmailbox
Гость
« Ответ #8 : Июня 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);
    }
}

< пользуемся тэгом "код"
« Последнее редактирование: Июня 08, 2010, 07:44 от Константин » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.044 секунд. Запросов: 23.