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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Layout->Layout->Layout или добавление объектов.  (Прочитано 6206 раз)
Ovoshlook
Гость
« : Май 22, 2011, 15:14 »

Здравствуйте. проблема следующего характера:
Есть у меня TabWidget вместе с его Layout.
после неких действий (выбора в комбобоксе) на нем рисуется много Layout'ов и в них кнопки.
По нажатю этих кнопок в один из добавленных на основной Layout TabWidget'a Layout'ов должны добавиться еще 2 Layout'a с widget'ами внутри.

Собственно вопрос вот в чем. Как мне добраться до определенного Layout, в который нужно положить еще 2 Layout

Архитектура такая:
TabWidget->Layout->QuestionAndAnsversVBoxLayout
Вот собственно в QuestionAndAnsversVBoxLayout мне нужно положить еще 2 Layout c Widget'ами внутри.

Дело осложняется тем что   TabWidget->Layout создается одним классом, а функция которая кладет в него QuestionAndAnsversVBoxLayout и другие Layout'ы с кнопками, после нажатия на которые в QuestionAndAnsversVBoxLayout должны добавиться еще 2 Layout'a создается в другом классе.

Собственно как положить QuestionAndAnsversVBoxLayout я понял. Я это делаю вот так:

Код:
void Question::SingleOrManyVariantsQuestionForm(QTabWidget *TabWidget)

{
    QuestionAndAnsversVBoxLayout= new QVBoxLayout;
    AnsversHBoxLayout= new QHBoxLayout;

    ButtonsForDellAndAddVariantsHBoxLayout= new QHBoxLayout;
    QustionAndPictureHBoxLayout= new QHBoxLayout;

    PictureContainer=new QLabel;
    TextContainer= new QTextEdit;

    AddVariantButton =new QPushButton;
    DeleteVariantButton =new QPushButton;
    AddPictureButton =new QPushButton;

    AddPictureButton->setText(tr("Add Picture"));
    AddVariantButton->setText(tr("Add Variant"));
    DeleteVariantButton->setText(tr("Delete Variant"));

    /*просто присвиваю Layout который класса QLayout значение TabWidget->currentWidget()->layout()*/
    Layout=static_cast<QVBoxLayout*>(TabWidget->currentWidget()->layout());
    Layout->addLayout(QuestionAndAnsversVBoxLayout);
    Layout->addLayout(ButtonsForDellAndAddVariantsHBoxLayout);

    QuestionAndAnsversVBoxLayout->addLayout(QustionAndPictureHBoxLayout);
    QuestionAndAnsversVBoxLayout->addLayout(AnsversHBoxLayout);

    QustionAndPictureHBoxLayout->addWidget(TextContainer);
    QustionAndPictureHBoxLayout->addWidget(PictureContainer);

    ButtonsForDellAndAddVariantsHBoxLayout->addWidget(AddPictureButton);
    ButtonsForDellAndAddVariantsHBoxLayout->addStretch();
    ButtonsForDellAndAddVariantsHBoxLayout->addWidget(AddVariantButton);
    ButtonsForDellAndAddVariantsHBoxLayout->addWidget(DeleteVariantButton);

    connect (AddVariantButton, SIGNAL(clicked()),OTS_MainWindow, SLOT(AddVariantForSingleAnsverQuestion()));
}

Но как мне теперь докапаться до нужного мне QuestionAndAnsversVBoxLayout я не совсем понимаю.

Сделал вот так:
Код:
void Question::AddVariantForSingleAnsverQuestion()

{
   AnsverRadioButton= new QRadioButton;
   TextForAnsverContainer= new QTextEdit;
   RadioOrCheckButtonsVBoxLayout=new QVBoxLayout;
   TextForAnsverContainersVBoxLayout=new QVBoxLayout;
  
   AnsversHBoxLayout->addLayout(RadioOrCheckButtonsVBoxLayout,1);
   AnsversHBoxLayout->addLayout(TextForAnsverContainersVBoxLayout,5);
   RadioOrCheckButtonsVBoxLayout->addWidget(AnsverRadioButton);
   TextForAnsverContainersVBoxLayout->addWidget(TextForAnsverContainer);
}

После применения данной функции на форму ничего не добавляется, следовательно что новые Layout'ы добавляются в никуда.

Заранее спасибо за помощь.
« Последнее редактирование: Май 22, 2011, 16:40 от Ovoshlook » Записан
like-nix
Гость
« Ответ #1 : Май 22, 2011, 17:57 »

>Но как мне теперь докапаться до нужного мне QuestionAndAnsversVBoxLayout я не совсем понимаю.

Например хранить на него указатель

Или последовательно добираться до нужного layout используя у слоя функцию layout.

« Последнее редактирование: Май 22, 2011, 19:20 от like-nix » Записан
Ovoshlook
Гость
« Ответ #2 : Май 22, 2011, 18:03 »

последовательно добираться- это я уже понял, но вот вопрос в следующем:
Скажем я определю элемент
Layout=static_cast<QVBoxLayout*>(TabWidget->currentWidget()->layout()->layout());
Но у меня на TabWidget->currentWidget()->layout() помещен не один Layout, а много Как мне докапаться до конкретно искомого?
Записан
Fess
Гость
« Ответ #3 : Май 22, 2011, 18:54 »

Как я понял, вам нужны динамические формы. Но зачем у вас они создаются в разных классах?
Вам нужен только один класс формы с достаточным количеством методов, чтобы им управлять.
Только форма должна знать где и как расположены виджеты и лайауты, остальные вызывают AddVariant() и т.д.

В целом вы форму создаете в конструкторе (руками или дизайнером - не важно) и где-то имеете контейнер для динамического контента.
Сохраняйте указатель на него в классе формы и добавляйте в него виджеты в одном из методов.

"В никуда" виджеты добавляться не могут. Вы ведь вызываете layout->addWidget. И либо тут схватите исключение от нулевого указателя, либо лайаут таки есть Улыбающийся
Попробуйте widget->show(), хотя не думаю, что проблема в этом.
Выложите минимально-компилируемый код с вашей проблемой..
Записан
like-nix
Гость
« Ответ #4 : Май 22, 2011, 19:23 »

>а много Как
itemAt
Записан
Ovoshlook
Гость
« Ответ #5 : Май 23, 2011, 21:11 »

Как я понял, вам нужны динамические формы. Но зачем у вас они создаются в разных классах?
Вам нужен только один класс формы с достаточным количеством методов, чтобы им управлять.
Только форма должна знать где и как расположены виджеты и лайауты, остальные вызывают AddVariant() и т.д.

В целом вы форму создаете в конструкторе (руками или дизайнером - не важно) и где-то имеете контейнер для динамического контента.
Сохраняйте указатель на него в классе формы и добавляйте в него виджеты в одном из методов.
.....

Выложите минимально-компилируемый код с вашей проблемой..

Собственно так и сделал. Перенес все методы в один класс. но так или иначе проблема осталась
Я немного не помнию что вы имеете ввиду под контейнером динамического объекта. К Виджету который находится на активном таббе я обращаюсь через currentWidget(). У меня была идея записывать в векторы основные значения, коорые принимает тот или иной виждет, но я пока что их еще не реализовал (в с++ я новичок). Собственно через currentWidget  я и собирался ообращаться к Layout. Идея с указателем на нужнй мне Layout понятна, но только не совсем понимаю как ее раелизовать. Есть идея обратиться каким либо образом к Layout нужному мне через его имя. Это возможно каким нибудь образом?

По поводу кода я могу выложить сюда саму прогу. мне не жалко да так и понятнее будет что я и как делаю и хочу сделать:

Код:
/* добавляю много виджетов на форму*/
void Question::SingleOrManyVariantsQuestionForm(QTabWidget *TabWidget)

{
    QuestionAndAnsversVBoxLayout= new QVBoxLayout;
    AnsversVBoxLayout= new QVBoxLayout;

    ButtonsForDellAndAddVariantsHBoxLayout= new QHBoxLayout;
    QustionAndPictureHBoxLayout= new QHBoxLayout;

    PictureContainer=new QLabel;
    TextContainer= new QTextEdit;

    AddVariantButton =new QPushButton;
    DeleteVariantButton =new QPushButton;
    AddPictureButton =new QPushButton;

    AddPictureButton->setText(tr("Add Picture"));
    AddVariantButton->setText(tr("Add Variant"));
    DeleteVariantButton->setText(tr("Delete Variant"));

    Layout=static_cast<QVBoxLayout*>(TabWidget->currentWidget()->layout());
    Layout->addLayout(QuestionAndAnsversVBoxLayout);
    //GlobalVaribles::NewLayout=Layout->layout();
    Layout->addLayout(ButtonsForDellAndAddVariantsHBoxLayout);

    QuestionAndAnsversVBoxLayout->addLayout(QustionAndPictureHBoxLayout);
    QuestionAndAnsversVBoxLayout->addLayout(AnsversVBoxLayout);

    QustionAndPictureHBoxLayout->addWidget(TextContainer);
    QustionAndPictureHBoxLayout->addWidget(PictureContainer);

    ButtonsForDellAndAddVariantsHBoxLayout->addWidget(AddPictureButton);
    ButtonsForDellAndAddVariantsHBoxLayout->addStretch();
    ButtonsForDellAndAddVariantsHBoxLayout->addWidget(AddVariantButton);
    ButtonsForDellAndAddVariantsHBoxLayout->addWidget(DeleteVariantButton);
    connect (AddVariantButton,SIGNAL (clicked()),this,SLOT(AddVariantForSingleAnsverQuestion()));
}


//------------------------------------------------------------------------------------------------------------------------------//
void Question::AddVariantForSingleAnsverQuestion()
/*пытаюсь добавить в нужный Layout нужные Layout'ы и Widget'ы. Я понимаю что так неправильно но пока остановился на вот этом*/
{
   AnsverRadioButton= new QRadioButton;
   TextForAnsverContainer= new QTextEdit;
   RadioOrCheckButtonAndAnsverHBoxLayout=new QHBoxLayout;


   //GlobalVaribles::NewLayout->addLayout( RadioOrCheckButtonAndAnsverHBoxLayout);
   RadioOrCheckButtonAndAnsverHBoxLayout->addWidget(AnsverRadioButton,1);
   RadioOrCheckButtonAndAnsverHBoxLayout ->addWidget(TextForAnsverContainer,5);
}
Вся прога тут http://files.mail.ru/Y6LTBC
(после запуска жмите на Ок)
Записан
Ovoshlook
Гость
« Ответ #6 : Май 23, 2011, 21:18 »

>а много Как
itemAt
А вот это очень кстати) спасибо) сейчас буду смотреть)
Записан
Ovoshlook
Гость
« Ответ #7 : Май 24, 2011, 13:58 »

>а много Как
itemAt
Спасибо еще раз за помощь! itemAt +static_cast сделали свое дело))
Записан
Ovoshlook
Гость
« Ответ #8 : Май 24, 2011, 14:03 »

контейнер для динамического контента.
Сохраняйте указатель на него в классе формы и добавляйте в него виджеты в одном из методов.


А вы имеете в виду что то конкретное под контейнером? или это абстрактное понятие? Просто если что то конкретное то какие контейнеры лучше всего использовать?
Как я уже писал я буду реализовывать подобное с помощью векторов. только хранить табм буду не указатели а определенные значения соответствующие определенным состояниям.
Записан
Fess
Гость
« Ответ #9 : Май 25, 2011, 06:09 »

Зачем вам GlobalVaribles.h?
TimesSettingsButtonClicked - внутренняя переменная окна регистрации, а NumberOfTab и SummOfTabAndTypeOfQuestionForCurrentTab - главного окна. Инкапсулируйте их в нужные классы форм.
Далее.
Не следует создавать главное окно в окне регистрации. Где оно будет удаляться?
Тогда уж допишите так: newMainWindow->setAttribute(Qt::WA_DeleteOnClose);
А лучше так:
Код:
OTS_AuthorizationWindow w;
if(w.exec() != QDialog::Accepted)
        return -1;
OTS_AuthorizationWindow w;
w.show();

По главному:
Я не сразу вас понял. На главной форме много вопросов (по табам). В каждом табе вопрос, ответ, неск-ко вариантов и кнопок управления.
В таком случае, выделение класса вопроса было правильным решением. Еще лучше сделать класс вопроса CQuestion (и ответа CAnswer), содержащий только данные по нему и свой виджет (QuestionWidget), умеющий их отображать.

В таком случае, при добавлении нового вопроса, вы создаете таб, добавляете на него QuestionWidget. Он в свою очередь берет данные из своего экземпляра CQuestion и генерирует нужное количество виджетов для их отображения.
Для того, чтобы добавлять динамическое количество ответов на вопросы вы должны в QuestionWidget сохранять указатель на QLayout где они все будут размещаться (то, что я имел в виду под "динамическим контейнером") и применять к нему addWidget по мере необходимости.

И еще: используйте редактор форм. На вкус и цвет, конечно, фломастеры разные и кому-то нравится писать все руками, но думаю, ясности в коде будет больше.

ЗЫ: забавно код оформляете Улыбающийся
Код:
void foo()

{
        //code here
}

var= val;
varvar= valval;
varvarvar= vvv;

ЗЫЫ: не нужно сохранять в хедере указатели на виджеты, которые вам не нужны для работы. Родительский виджет удалит все дочерние самостоятельно.
« Последнее редактирование: Май 25, 2011, 06:13 от Fess » Записан
Ovoshlook
Гость
« Ответ #10 : Май 25, 2011, 09:24 »

Спасибо большое за советы! GlobalVaribles.h я создавал для себя так сказать, для наглядности, хотя я понимаю что это не совсем правильно и безсмысленно хранить переменную, которая по идее должна быть уничтожена после закрытия окна. А векторы мне нужны будут для записи значений в конфигурационные файлы. Ну это лирика.

Сейчас уже не буду переделывть обратно на классы так как время поджимает.
Но я очень рад что вы подтвердили то что я мыслил правильно) спасибо вам еще раз за помощь!)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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