Russian Qt Forum
Ноябрь 25, 2024, 14:36 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Отложенная иницализация окна  (Прочитано 3403 раз)
aljeshishe
Гость
« : Январь 13, 2010, 18:41 »

Не знаю, возможно это все бред, но... в упрощенном виде проблема следующая
Есть базовый класс окна
class CMsgWindow : public QMainWindow
Тут определяются элементы интерфейса общие для дочерних классов окон
Например пункт меню Собщение\сохранить
Есть дочерние классы
class CInMsgWindow : public CMsgWindow
class COutMsgWindow : public CMsgWindow
В них определяется специфика.
Например пункты меню Собщение\принять и
Собщение\отправить соответственно.
Проблема в том, что не всегда вызывая в конструкторе setupUi(this), можно добиться нужного эффекта.
Например сначала в конструкторе CMsgWindow добавляется пункт "сохранить", а затем
в конструкторе CInMsgWindow добавляется "принять". В результате получается не тот порядок пунктов меню который нужен, обусловленный порядком вызова конструкторов. Можно привести более сложные примеры...
Все решила бы виртуализация функции инициализации элементов интерфейса. Тогда в дочернем классе можно вызывать функцию базового класса когда угодно, можно и вообще не вызывать.
Но проблема в том, что виртуальные функции нельзя использовать в конструкторах.
Отсюда вопрос, когда можно инициализировать элементы интерфейса, кроме как в конструкторе, при этом не меняя код создателя окна, оставляя его максимально простым:
CMsgWindow *p = new CInMsgWindow;
p->show();
Event'ы ?
Записан
developer
Гость
« Ответ #1 : Январь 13, 2010, 19:18 »

Можеш использовать паттерн State
Записан
Павел_F.
Гость
« Ответ #2 : Январь 13, 2010, 21:50 »

Но проблема в том, что виртуальные функции нельзя использовать в конструкторах.
Это почему?
Вот код:
Код
C++ (Qt)
#include <QtGui>
 
class MainWindow : public QMainWindow
{
   Q_OBJECT
public:
   MainWindow(QWidget *parent = 0) : QMainWindow( parent)
   {
myTest();
   }
   virtual void myTest()
   {
qWarning("void MainWindow::myTest()");
   }
};
 
 
class MainWindow2 : public MainWindow
{
   Q_OBJECT
public:
   MainWindow2( QWidget *parent = 0) : MainWindow( parent)
   {
myTest();
   }
   void myTest()
   {
qWarning("void MainWindow2::myTest()");
   }
};
 
Компилится, работает, виртуальная функция в конструкторе. Или имеется ввиду чисто виртуальные?
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #3 : Январь 13, 2010, 21:59 »

Павел_

Цитировать
Цитировать
Но проблема в том, что виртуальные функции нельзя использовать в конструкторах.
Это почему?
попробуйте вызвать виртуальную ф-цию перегруженную в конструкторе предка, но выполняющуюся в конструкторе потомка.

Код
C++ (Qt)
class MainWindow : public QMainWindow
{
   Q_OBJECT
public:
   MainWindow(QWidget *parent = 0) : QMainWindow( parent)
   {
myTest();
   }
   virtual void myTest()
   {
qWarning("void MainWindow::myTest()");
   }
};
 
class MainWindow2 : public MainWindow
{
   Q_OBJECT
public:
   void myTest()
   {
qWarning("void MainWindow2::myTest()");
   }
};
 

по вашей логике - раз они работаю то при создание экземпляра MainWindow2 должно вывестись "void MainWindow2::myTest()", но выведется
"void MainWindow::myTest()" т.к. виртуальные ф-ции можно использовать в к-рах, но они не будут работать как виртуальные - это действительно ограничение C++;

aljeshishe
думаю есть решения вашей проблемы
1) использовать отдельные ui для разных окон - в которых все Action руками расставлены по элементам меню как надо (можно использовать UILoader а можно и старым принципом)
2) сделать ф-цию init для базового окна и в ней а не в конструкторе вызывать setupUi -а уже в наследниках вызывать этот init тогда когда удобнее для создания элементов меню
Записан
Dendy
Гость
« Ответ #4 : Январь 13, 2010, 22:00 »

Толку от такой виртуальной функции, которая вызывается из наследуемого класса.

По теме. В конструкторах можно и нужно создавать дочерние виджеты и делать setupUi(). Другое дело, что инициализировать их значениями нужно отдельно, здесь никакого стандартного способа в Qt нет. Нужно создавать свой виртуальный метод инициализации, который будет вызываться сразу же после конструктора. К примеру в Objective-C эта проблема решена тем, что у классов нет конструкторов вообще, только виртуальный метод init, обычно вызываемый после аллокации.
Записан
Павел_F.
Гость
« Ответ #5 : Январь 13, 2010, 23:24 »

А для конкретно этой задачи не проще ли в классе завести список QList< QAction*> с действиями для меню. Рулить списком как пожелается где угодно, потом, например в showEvent, делать void QMenu::addActions ( QList<QAction *> actions )
Записан
Dendy
Гость
« Ответ #6 : Январь 13, 2010, 23:35 »

Да, это вариант. Более того, возможно подойдёт стандартный QWidget::actions().
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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