Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Alex_C от Апрель 14, 2012, 22:55



Название: В конструктор родителя передать имя объекта
Отправлено: Alex_C от Апрель 14, 2012, 22:55
Нужно что то типа такого:

Код:
CalcWindow::CalcWindow(QSettings *s,
                       bool isModal,
                       QWidget *parent) :
    AbstractLogWindow(this->objectName(), s, isModal, parent)

Однако, этот код вызывает ошибку - ведь здесь так this->objectName() имя класса передать нельзя. А как можно?
Мне это имя нужно в конструкторе родителя.


Название: Re: В конструктор родителя передать имя объекта
Отправлено: kambala от Апрель 14, 2012, 23:21
родитель и сам в состоянии запросить objectName


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Alex_C от Апрель 15, 2012, 10:17
Я пока нашел, что родитель может запросить только children() - список наследуемых от него классов. А вот определить - какой конкретно наследник вызвал - конструктор - пока не нашел.


Название: Re: В конструктор родителя передать имя объекта
Отправлено: alexis031182 от Апрель 15, 2012, 10:35
Но ведь Вы хотите передать имя конкретного класса потомка предку при их создании, так? Так почему бы просто строку не передать? Имя Вам в данной ситуации однозначно известно.


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Igors от Апрель 15, 2012, 10:36
Я пока нашел, что родитель может запросить только children() - список наследуемых от него классов. А вот определить - какой конкретно наследник вызвал - конструктор - пока не нашел.
Хотя это можно сделать финтом, это сложно и опасно. См детали здесь
http://www.prog.org.ru/index.php?topic=21516.msg149271#msg149271 (http://www.prog.org.ru/index.php?topic=21516.msg149271#msg149271)

Обычно делают виртуальный метод (часто называют Init()) который вызывают сразу после конструктора


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Alex_C от Апрель 15, 2012, 10:53
Спасибо за ответы!
То alexis031182: естественно, имя класса-потомка я знаю. Я в первом посте и спросил - как конструктору-родителю передать строку? Я там привел "попытку" это сделать.
То Igors: прочитал. И все больше думаю, что то, что я хочу сделать, а вернее как я это хочу сделать - мягко скажем не верное направление деятельности.

Напишу тогда что хочу сделать: хочу сделать класс-предок, для всех окон моей программы (их много). Одной из задач, которые должен выполнять этот предок - сохранение положения и т.п. установок окна в ini-файле. Как вариант предполагаю сделать так:

Код:
AbstractLogWindow::AbstractLogWindow(QString winName,
                                     QSettings *s,
                                     bool isModal,
                                     QWidget *parent) :
QWidget(parent)
{
    m_WinSet = s;
    m_WinName = winName;
   
    uint winState = (isModal? Qt::Dialog : Qt::Window);

    m_WinSet->beginGroup(m_WinName);
    setGeometry(m_WinSet->value("Geometry", geometry()).toRect());
    setWindowFlags(Qt::WindowFlags(m_WinSet->value("WondowFlags", winState).toUInt()));
    m_WinSet->endGroup();
}

AbstractLogWindow::~AbstractLogWindow()
{
    m_WinSet->beginGroup(m_WinName);
    m_WinSet->setValue("Geometry", geometry());
    m_WinSet->setValue("WondowFlags", uint(windowFlags()));
    m_WinSet->endGroup();
}

Идея думаю понятна.
Вот для этого мне и нужно имя класса-потомка.


Название: Re: В конструктор родителя передать имя объекта
Отправлено: alexis031182 от Апрель 15, 2012, 11:00
Прошу извинить, что может быть туплю, но мне просто интересно, почему нельзя сделать вот так:
Код:
CalcWindow::CalcWindow(QSettings *s, bool isModal, QWidget *parent) :
   AbstractLogWindow("CalcWindow", s, isModal, parent)
И соответственно в любом классе потомке подставлять строку с именем потомка


Название: Re: В конструктор родителя передать имя объекта
Отправлено: mutineer от Апрель 15, 2012, 11:13
Я пока нашел, что родитель может запросить только children() - список наследуемых от него классов. А вот определить - какой конкретно наследник вызвал - конструктор - пока не нашел.

Ты бы разобрал кашу в голове - children() возвращает совсем не список наследуемых классов, а список дочерних объектов. Что суть абсолютно разные вещи


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Igors от Апрель 15, 2012, 11:25
Уберите "паскалевские уши"
Код
C++ (Qt)
AbstractLogWindow::AbstractLogWindow(QString winName,  // ненужная подача по значению
AbstractLogWindow::AbstractLogWindow(const QString & winName,  // на плюсах так
 

Возвращаясь к теме - а чего Вы так настойчиво хотите воткнуть создание лога в базовый конструктор? Действительно ли это свойство "базовое"? Все-все созданные экземпляры будут иметь логи - не многовато ли? Более реалистично так
Код
C++ (Qt)
CalcWindow * calc = new CalcWindow(.. );
calc->LoadSettings(...);
 
А то боретесь за то чтобы записать это одной строкой - и теряете при этом всю гибкость

Edit: тут я сам маленько запутался - AbstractLogWindow ввело в заблуждение, подумал что это лог-окно  :)


Название: Re: В конструктор родителя передать имя объекта
Отправлено: alexis031182 от Апрель 15, 2012, 11:40
Код:
CalcWindow::CalcWindow(QSettings *s, bool isModal, QWidget *parent) :
   AbstractLogWindow("CalcWindow", s, isModal, parent)
И соответственно в любом классе потомке подставлять строку с именем потомка
Так ведь AbstractLogWindow - это просто др окно, а не базовый класс

...
Напишу тогда что хочу сделать: хочу сделать класс-предок, для всех окон моей программы (их много). Одной из задач, которые должен выполнять этот предок - сохранение положения и т.п. установок окна в ini-файле.
...


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Igors от Апрель 15, 2012, 12:21
alexis031182, Вы правы, человек действительно хотел сделать базовый класс. Однако затея неудачна, конструктор смотрится коряво
Код
C++ (Qt)
CalcWindow::CalcWindow(QSettings *s, bool isModal, QWidget *parent) :
 
Нужны ли (необходимы) QSettings, isModal самому CalcWindow? Какая ф-циональность AbstractLogWindow кроме одного действия в конструкторе? Пока видно что это явно метод, а не базовый класс



Название: Re: В конструктор родителя передать имя объекта
Отправлено: Alex_C от Апрель 15, 2012, 19:45
Ребят. Без обид - сколько я ссорился на Дельфийских форумах))) Да у меня весьма своеобразная задача))) Но она достаточно популярна "в узких кругах специалистов". Просто по другому - нет смысла писать (моя программа бесплатна - есть другие аналоги). Ей просто не будут пользоваться, если я не сделаю некоторые пользовательские возможности.
На счет "нужны ли" - коротко - ДА. Я ведь прежде всего для себя пишу - программа бесплатна - пишется для удовольствия. Тем кому интересно - пишите на емайл. Поговорим)))

Теперь о программе: в программе около 30 окон - нужно позицию каждого окна сохранять и т.п. Разве моя идея не правильна?


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Igors от Апрель 15, 2012, 20:27
Просто по другому - нет смысла писать (моя программа бесплатна - есть другие аналоги). Ей просто не будут пользоваться, если я не сделаю некоторые пользовательские возможности.
На счет "нужны ли" - коротко - ДА. Я ведь прежде всего для себя пишу - программа бесплатна - пишется для удовольствия. Тем кому интересно - пишите на емайл. Поговорим)))

Теперь о программе: в программе около 30 окон - нужно позицию каждого окна сохранять и т.п. Разве моя идея не правильна?
Никто не пытается доказать что сохранение/восстановление позиции/свойств окон "не нужно". Во всяком случае это Вам виднее. Обсуждается только "как это сделать". Так вот, через базовый класс - плохо. Хоть это и не смертельная ошибка, но Вы просто начнете испытывать некоторые неудобства, и чем дальше - тем больше. Напр Вам придется всегда иметь QSettings чтобы создать окно. Придется откуда-то (искусственно) извлекать имя (чтобы подать его в конструктор) и.т.п

Ребят. Без обид
Эх, как было бы здорово если все вокруг были бы свои "ребят"  :) Но увы, обычно это люди очень разного круга/интересов, поэтому лучше не быть таким фамильярным


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Alex_C от Апрель 15, 2012, 20:41
Обсуждается только "как это сделать". Так вот, через базовый класс - плохо. Хоть это и не смертельная ошибка, но Вы просто начнете испытывать некоторые неудобства, и чем дальше - тем больше. Напр Вам придется всегда иметь QSettings чтобы создать окно. Придется откуда-то (искусственно) извлекать имя (чтобы подать его в конструктор) и.т.п

Так я по этому тут и спрашиваю)) Программа то уже есть. В общем то готовая и хорошая. Бесплатная. Я теперь хочу:
1. Сделать ее кросс-платформенной.
2. В принципе сделать ее в "правильном стиле".
Пока не понимаю, о чем Вы говорите - да, прийдется всегда иметь QSettings - а как иначе? И т.п. Вот и думаю - как лучше?


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Alex_C от Апрель 15, 2012, 20:43
Эх, как было бы здорово если все вокруг были бы свои "ребят"  :) Но увы, обычно это люди очень разного круга/интересов, поэтому лучше не быть таким фамильярным

Прошу прощения. Я сам уже не молод)) Но вырос в социализме - где все "свои ребята"))) Прошу прощения. Ошибку принял к сведению.


Название: Re: В конструктор родителя передать имя объекта
Отправлено: alexis031182 от Апрель 15, 2012, 22:51
Alex_C, Igors Вам дал очень дельный совет не наследовать CalcWindow (и др. подобные классы окон) от AbstractLogWindow. Это действительно в будущем, с увеличением размера приложения может привести (и наверняка приведёт) к необходимости добавления в код множества т.н. костылей. Разъедините оба класса, и пусть AbstractLogWindow принимает указатель на окна типа CalcWindow.


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Alex_C от Апрель 15, 2012, 23:34
Чего то я пока ничего не понял - я то как раз хочу размер уменьшить - все в класс - потомок свести. Разве это не правильно??


Название: Re: В конструктор родителя передать имя объекта
Отправлено: alexis031182 от Апрель 16, 2012, 08:09
На самом деле через наследование в данном случае Вы не уменьшаете размер. Ну посудите сами: при создании каждого объекта класса CalcWindow будет автоматом создаваться экземпляр класса AbstractLogWindow. То есть, имея, скажем, 30 объектов CalcWindow, Вы получаете по сути 30 объектов AbstractLogWindow. Судя по представленному Вами функционалу AbstractLogWindow в таковом наследовании нет необходимости. Вполне достаточно одного экземпляра AbstractLogWindow на сколь угодно большое количество CalcWindow.


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Alex_C от Апрель 16, 2012, 09:02
Я понял о чем Вы говорите. Просто тот функционал, что я привел - для примера. В реальной программе все существенно сложнее получается, чем просто записывать данные в ini-файл. Конечно,  с Вами согласен - был бы разговор только о записи вида окна - городить огород из наследования - смысла бы не было.


Название: Re: В конструктор родителя передать имя объекта
Отправлено: _OLEGator_ от Апрель 16, 2012, 10:54
Зачем хранить лишнее поле с именем.
Я бы сделал виртуальную функцию получения имени объекта, в потомках его переопределял, а в базовом классе при сохранении и загрузке можно в любом месте получить имя, вызвав эту функцию. Нет необходимости хранить это имя.

Можно воспользоваться функциональностью QObject:
Код
C++ (Qt)
QString objectName () const
void setObjectName ( const QString & name )


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Alex_C от Апрель 16, 2012, 11:03
Зачем хранить лишнее поле с именем.
Я бы сделал виртуальную функцию получения имени объекта, в потомках его переопределял, а в базовом классе при сохранении и загрузке можно в любом месте получить имя, вызвав эту функцию. Нет необходимости хранить это имя.

А вот это наверное самое правильное решение! Так и сделаю!


Название: Re: В конструктор родителя передать имя объекта
Отправлено: LisandreL от Апрель 16, 2012, 11:14
Я бы сделал виртуальную функцию получения имени объекта, в потомках его переопределял, а в базовом классе при сохранении и загрузке можно в любом месте получить имя, вызвав эту функцию. Нет необходимости хранить это имя.
В конструкторе/деструкторе родителя нельзя.
А сохранить данные перед выходом может захотеться именно там.
Ну это просто как напоминание.


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Alex_C от Апрель 16, 2012, 11:27
Поторопился. Виртуальную ф-цию в конструкторе не получается использовать - LisandreL прав.  ???
Какие могут быть еще варианты?


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Alex_C от Апрель 16, 2012, 11:28
Может конечно вообще не заморачиваться - просто название класса ручками прописывать. Но вроде как не по феншую...


Название: Re: В конструктор родителя передать имя объекта
Отправлено: alexis031182 от Апрель 16, 2012, 11:44
Судя по тому, что Вы сохраняете для идентификации соответствия настройкам окна имя класса этого окна, то получается, что в Вашей программе будет лишь один объект класса CalcWindow (иначе уникальностью тут не пахнет). А если так, то идентифицировать можно и просто цифрой :)


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Igors от Апрель 16, 2012, 12:28
Чего то я пока ничего не понял - я то как раз хочу размер уменьшить - все в класс - потомок свести. Разве это не правильно??
Чувствуется кладка дельфийца - давайте раздуем базовый класс "на все случаи жизни" :)
Посмотрим а что делает AbstractLogWindow. Разве сохранение/восстановление размеров/позиции окна как-то связано с CalcWindow или др именно Вашими классами окон? Вовсе нет, это можно делать для любого Qt окна/виджета. Отделаться "загрузкой в конструкторе" + "сохранением в деструкторе" все равно не удается. Напр пользователь нажал "Save" - и окна не закрываются но их расклад должен быть сохранен. Также интересно как Вы будете извиваться если потребуется окно что не зависит от QSettings.

Имеет смысл унаследоваться от QSettings и там добавить свои методы - какие-то соглашения по секциям будут так или иначе. Или даже просто сделать сохранение/восстановление глобальной ф-цией (или как говорят синглтоном). Да, придется вызывать его после каждого создания окна, это минус. Но конструктор требующий QSettings (а где его взять?) никак не лучше


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Alex_C от Апрель 16, 2012, 13:27
Или даже просто сделать сохранение/восстановление глобальной ф-цией (или как говорят синглтоном). Да, придется вызывать его после каждого создания окна, это минус. Но конструктор требующий QSettings (а где его взять?) никак не лучше

Не соглашусь с Вами - потому как в Дельфи у меня так и сделано. Тут же (как мне кажется) можно сделать куда как правильнее. Потому как у меня в программе много отдельных окон, базовый класс для них - самое то. В Дельфи мне приходилось в конструктор каждого окна что - то прописывать (как минимум к глобальным переменным нужно обращаться и т.п.) Тут как раз можно все начальные операции по определению класса сделать "по умолчанию" - по моему это правильно.
Я не настаиваю на своем мнении - хочу услышать почему я не прав.


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Alex_C от Апрель 16, 2012, 13:40
Да кстати о наследии Дельфи - в дельфи унаследовать класс TForm было весьма не простым делом - там ведь ручками прийдется все компонеты на нем расставлять.  Тут же - лайоуты - красота :) Как раз поле для классов)))


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Igors от Апрель 16, 2012, 13:56
Не соглашусь с Вами - потому как в Дельфи у меня так и сделано. Тут же (как мне кажется) можно сделать куда как правильнее. Потому как у меня в программе много отдельных окон, базовый класс для них - самое то. В Дельфи мне приходилось в конструктор каждого окна что - то прописывать (как минимум к глобальным переменным нужно обращаться и т.п.) Тут как раз можно все начальные операции по определению класса сделать "по умолчанию" - по моему это правильно.
Я не настаиваю на своем мнении - хочу услышать почему я не прав.
Покрутите разные ситуации. Напр у меня есть "Reset Windows" - выстроить окна как они записаны в установках. Как будете делать если у Вас это жестко вбито в конструктор? Или пользователь выходит без сохранения - а у Вас в деструкторе установки окон зачем-то сохраняются. и.т.п. Быстро выясняется что не сам класс окна а какая-то "третья сторона" решает нужно ли загружать/сохранять. Значит надо иметь эти действия в виде ф-ций - и все.

Если "чисто теоретически" то можно объяснить так. Является ли сохранение/загрузка "неотъемлемым" свойством Ваших окон, без которого они не могут жить? Никак не является, очень может быть есть (или будут) окна которым это не нужно. Так чего это свойство вынесено в базовый класс?

Конечно это не является "ужасной ошибкой", "кривой архитектурой" и.т.п. - это молодые любят преувеличивать, а я тоже "из советских времен"  :)

Тут же - лайоуты - красота :) Как раз поле для классов)))
Заметьте что лайоут никак не входит в базовые свойства


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Alex_C от Апрель 16, 2012, 17:03
Кстати, за всеми этими теоретическими выкладками заметил вот что: у меня положение окна восстанавливается, а его размер - нет. Что не так?

Код:
AbstractLogWindow::AbstractLogWindow(QString winName,
                                     QSettings *s,
                                     bool isModal,
                                     QWidget *parent) :
QWidget(parent)
{
    m_WinSet = s;
    m_WinName = winName;

    uint winState = (isModal? Qt::Dialog : Qt::Window);

    m_WinSet->beginGroup(m_WinName);
    setWindowFlags(Qt::WindowFlags(m_WinSet->value("WondowFlags", winState).toUInt()));
    setGeometry(m_WinSet->value("Geometry", geometry()).toRect());
    m_WinSet->endGroup();
}

AbstractLogWindow::~AbstractLogWindow()
{
    m_WinSet->beginGroup(m_WinName);
    m_WinSet->setValue("Geometry", geometry());
    m_WinSet->setValue("WondowFlags", uint(windowFlags()));
    m_WinSet->endGroup();
}

Смотрю ini-файл - все записывается правильно. Но размеры то почему не восстанавливаются? Т.е. положение - правильное, а размер - нет.


Название: Re: В конструктор родителя передать имя объекта
Отправлено: Alex_C от Апрель 17, 2012, 15:49
И что - никто не скажет в чем проблема? ))) Чего, в конструкторе состояние окна нельзя восстанавливать?