Сам отвечу на этот вопрос =)
Вот результат, который мне удалось получить:
ddWidgetMain w; // создается главное окно
w.resize(500, 250);
w.move(400, 200);
w.show();
//w.showFullScreen();
{
QWidget *myWidget = NULL;
{
ddUiLoader loader; // создается модифицированный лоадер
QFile file(CEngine::Get()->getCurrentDir() + "/files/test1.ui"); // загружаем файл, соответствующий горизонтальному варианту
file.open(QFile::ReadOnly);
myWidget = loader.load(&file, &w);
myWidget->show();
file.close();
}
myWidget->findChild<QLabel*>()->setText("123"); // для наглядности меняем надпись на QLabel-е
qDebug() << myWidget->findChild<QLabel*>(); // распечатываем указатель на этот виждет. Чтобы потом проверить, не изменился ли он
// Сейчас иммитируем переворот экрана, загрузив новый файл интерфейса
{
ddUiLoader loader;
QFile file(CEngine::Get()->getCurrentDir() + "/files/test2.ui"); // загружаем файл, соответствующий [b]вертикальному[/b] варианту
file.open(QFile::ReadOnly);
loader.setCurrent(myWidget); // самое интересное. Даем лоадеру указатель на виджет, где уже есть итемы. Дабы он не создал новые
myWidget = loader.load(&file, &w);
myWidget->show();
file.close();
}
qDebug() << myWidget->findChild<QLabel*>();
}
Результат вывода дебага:
QLabel(0xe04f10, name = "label")
QLabel(0xe04f10, name = "label")
Как видно, при перезагрузке интерфейсного файла метка не изменилась.
Что и требовалось получить =))
Лайоуты пересобрались, виджеты остались те же самые.
Можно например делать калькулятор с двумя разными вариантами интерыейса, и при перевертывании текущее состояние ввода не поменяется.
Теперь код модифицированного лоадера:
class ddUiLoader : public QUiLoader
{
Q_OBJECT
public:
explicit ddUiLoader(QObject *parent = 0);
void setCurrent(QWidget *pWidget);
protected:
QWidget *createWidget(const QString & className, QWidget * parent = 0, const QString & name = QString());
private:
QWidget *m_pCurrentWidget;
};
...........................................
QWidget *ddUiLoader::createWidget(const QString & className, QWidget *parent, const QString &name)
{
QWidget *pWidget = NULL;
if(m_pCurrentWidget)
{
pWidget = m_pCurrentWidget->findChild<QWidget*>(name);
if(pWidget) pWidget->setParent(parent);
}
if(!pWidget) pWidget = QUiLoader::createWidget(className, parent, name);
return pWidget;
}
void ddUiLoader::setCurrent(QWidget *pWidget)
{
m_pCurrentWidget = pWidget;
}
Но есть один нюанс!Злобный QT Designer позволяет настраивать свойства (property) виджета.
Например, текст метки (QLabel).
Чем это грозит.
Мы создали в дезайнере QLineEdit.
Вводим туда данные, все хорошо.
И тут - опа, перевернули девайс. Загрузился новый файл интерфейса.
Сам объект QLineEdit
не изменился.
Но QUiLoader перезапишет его свойство "text" на то, что мы ввели при дизайне,
сведя тем самым на нет наши старания.
На мой взгляд, это косяк разработчиков QT, которые не сделали возможным помимо управления созданием виджетов в лоадере
сделать также доступ к управлению инициализации их свойств.
Лечится просто.
Открываем файл *.ui и удаляем инициализацию свойст для тех лбъектов, где это нужно.
По факту это те виджеты, куда пользователь будет что-то воодить. Иначе потрется.
Вот как это выглядит для QLabel (файл *.ui):
...
<widget class="QLabel" name="label">
<property name="text"> // Удалить!
<string>test</string> // Удалить!
</property> // Удалить!
</widget>
...
Вроде все работает нормально!
Если у Вас есть другие идеи, как избежать правки файла вручную, буду рад посмотреть.
Хотя есть одна мысль.
Сделать функцию, которой можно передать имя файла и названия неизменяемых виджетов.
Эта функция просто будет находить тег <widget ........>...</widget> и удалять всё нутро.
(Пример с калькулятором - с кнопками ничего делать не надо, а вот поле ввода нужно сделать неизменяемым.
Иначе при ресайзе потрется введенное число)