Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.55/47: Рейтинг темы: голосов - 47, средняя оценка - 4.55
0 / 0 / 0
Регистрация: 19.09.2014
Сообщений: 32

Динамическое создание и удаление объектов VCL

27.09.2014, 19:28. Показов 10406. Ответов 33
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Не получается сделать программу на C++ Bilder

Разработать приложение, которое динамически создает и удаляет объекты VCL.

На форме размещены 3 компонента TGroupBox. Под каждым компонентом TGroupBox размещен компонент TCheckBox. Внизу формы размещены кнопки «Добавить» и «Удалить».

По нажатию на кнопку «Добавить» в выбранных TGroupBox на свободном месте создать объект на основе TPanel и размещенных внутри ее компонентов TLabel и TEdit. В Label записать номер TGroupBox, а в TEdit – координаты созданного компонента – X и Y.

При нажатии на кнопку «Удалить» – удалить все компоненты с выбранных TGroupBox.

Количество компонентов не ограничено.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.09.2014, 19:28
Ответы с готовыми решениями:

Динамическое создание VCL-объектов из dll
Тренируюсь использовать динамически dll. Пока все вроде получается, но есть одна неясность. Задача примерно такая: сделать из dll...

VCL удаление динамически созданых объектов с формы
Написал игру ханойские башни, так чтобы можно было задавать любое количество колец. Я делаю такой цикл for( int i = 0 ; i<count...

Создание собственного VCL компонента. Динамическое изменение количества колонок в зависимости от размера объекта
Доброго времени суток всем. Решил при создании своего компонента на основе TStringGrid инкапсулировать в него ряд свойств. Хочется...

33
0 / 0 / 0
Регистрация: 19.09.2014
Сообщений: 32
28.09.2014, 17:49  [ТС]
Студворк — интернет-сервис помощи студентам
У меня проблема в том , что при повторном нажатии на кнопку добавить выскакивает ошибка A component named Panel0 already exists, а не создает еще одну панель

Добавлено через 4 минуты
Извиняюсь, понял в чем дело
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
28.09.2014, 17:52
Цитата Сообщение от andrei1994 Посмотреть сообщение
выскакивает ошибка A component named Panel0
А попробовать показанные уточнения не судьба?
Цитата Сообщение от BRcr Посмотреть сообщение
C++
1
P->Name = "";
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
28.09.2014, 17:59
Что касается удаления:

C++
1
2
3
4
5
6
7
//---------------------------------------------------------------------------
void __fastcall TForm2::Button2Click(TObject *Sender)
{
  while(GroupBox1->ControlCount)
     delete GroupBox1->Controls[0];
}
//---------------------------------------------------------------------------
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
28.09.2014, 18:50
Ну, и что касается удаления - зачем все подряд-то? Такого условия не было.
0
0 / 0 / 0
Регистрация: 19.09.2014
Сообщений: 32
28.09.2014, 19:09  [ТС]
может кто знает как это делать "Хочешь четко по заданию - размещай панельки одну рядом с другой, как клетки шахматной доски"?
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
28.09.2014, 19:10
Цитата Сообщение от BRcr Посмотреть сообщение
Между "индитификацией" и идентификацией нет ничего общего. Надо же, только после ссылки на вики я наконец поимел счастье понять оппонента...
Про dynamic_cast и type_id я знаю. Какое отношение это имеет к теме?
К тому что нет смысла что-то к чему-то кастовать перед вызовом delete, ибо очевидно что иерархия типов VCL cама собой подразумевает наличие виртуальных деструкторов, иначе бы наследование было бы невозможным.

Цитата Сообщение от BRcr Посмотреть сообщение
Ну, и что касается удаления - зачем все подряд-то? Такого условия не было.
Читаем вслух и про себя:
Цитата Сообщение от andrei1994 Посмотреть сообщение
При нажатии на кнопку «Удалить» – удалить все компоненты с выбранных TGroupBox.
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
28.09.2014, 21:42
Цитата Сообщение от Avazart Посмотреть сообщение
К тому что нет смысла что-то к чему-то кастовать перед вызовом delete, ибо очевидно что иерархия типов VCL cама собой подразумевает наличие виртуальных деструкторов, иначе бы наследование было бы невозможным.
Мне - было бы совершенно неочевидно, при условии, что я не копался бы особо в библиотеке.

Вот пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class base
{
    char * c_arr;
 
public:
    base( )
    {
        c_arr = new char[ 20 ];
        ShowMessage( "base constr" );
    }
 
    ~base( )
    {
        delete[ ]c_arr;
        ShowMessage( "base destr" );
    }
} ;
 
class der1 : public base
{
    int * i_arr;
 
public:
    der1( ) :
        base( )
    {
        i_arr = new int[ 20 ];
        ShowMessage( "der1 constr" );
    }
 
    ~der1( )
    {
        delete[ ]i_arr;
        ShowMessage( "der1 destr" );
    }
} ;
 
class der2 : public der1
{
} ;
 
//...
 
    der2 * d2 = new der2( );
    base * bs = reinterpret_cast < base * > ( &d2 );
    delete bs;
Возможно ли наследование в данном случае? Чем эта иерархия принципиально отличается от VCL? Будет ли вызван деструктор der1?
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
28.09.2014, 21:57
Цитата Сообщение от BRcr Посмотреть сообщение
Возможно ли наследование в данном случае?
Очевидно что нет.
Ошибка новичка к примеру наследоваться от STL контейнеров типа std::vector<> которые не предназначены для наследования.
Или вы думаете что разработчики совершают часто такие ошибки, что нужно разводить параною ?
Цитата Сообщение от BRcr Посмотреть сообщение
Мне - было бы совершенно неочевидно, при условии, что я не копался бы особо в библиотеке.
Ну так возьмите и загляните в чем проблема?
Тем более что само собой разумеется что VCL объекты в основе своей создаются только динамически.
0
0 / 0 / 0
Регистрация: 19.09.2014
Сообщений: 32
28.09.2014, 23:20  [ТС]
Кто-нибудь знает как сделать чтобы не налаживалась Panel одна на одну , а только на свободном месте??
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
28.09.2014, 23:27
Цитата Сообщение от andrei1994 Посмотреть сообщение
Кто-нибудь знает как сделать чтобы не налаживалась Panel одна на одну , а только на свободном месте??
Запоминать положение/ширину предыдущей панели и следующую располагать чуть ниже.
0
 Аватар для kodv
1449 / 1121 / 347
Регистрация: 11.04.2011
Сообщений: 2,621
29.09.2014, 06:42
Цитата Сообщение от BRcr Посмотреть сообщение
По условию принципа ООП мы знать не знаем о реализации деструкторов в иерархии TControl => TPanel. Поэтому, если деструктор родительского класса не виртуальный, то деструктор TPanel вызван не будет.
Виртуальность деструктора к его реализации не имеет никакого отношения. Виртуальность деструктора являеются частью описания класса, а описание, по условию принципа ООП, знать не запрещается. Поэтому, можно легко глянуть в справку билдераи и не кастовать каждый раз к TPanel, так как деструктор в TControl виртуальный, как и деструкторы во всей иерархии TControl = > TPanel.
2
Модератор
 Аватар для D1973
9952 / 6487 / 2461
Регистрация: 21.01.2014
Сообщений: 27,485
Записей в блоге: 3
29.09.2014, 09:10
Ну а пока мэтры ломают копья в решении высокоэмперических проблем, мы вернемся к нашим баранам, т.е. ГрупБоксам...
Предлагаю следующий вариант...
*.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
    TGroupBox *GroupBox1;
    TButton *Button1;
    TButton *Button2;
    TGroupBox *GroupBox2;
    TCheckBox *CheckBox1;
    TCheckBox *CheckBox2;
    void __fastcall Button1Click(TObject *Sender);
    void __fastcall FormCreate(TObject *Sender);
    void __fastcall Button2Click(TObject *Sender);
private:    // User declarations
    int nPanel, nLabel, nEdit; //Переменные имен компонент
    int dh, dw, dl, dt; //Переменные начального размещения панели
    int aPos[4][2]; //Массив переменных размещения панели (второй индекс - количество GroupBox-ов)
    void __fastcall CreatePanel(TGroupBox *G, int numG);
    void __fastcall DeletePanel(TGroupBox *G);
public:     // User declarations
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif


*.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
 
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::CreatePanel(TGroupBox *G, int numG)
{
//Создаем панель
  TPanel *P = new TPanel(G);
  if(G->ControlCount == 0)
   {
     aPos[0][numG] = dh; aPos[1][numG] = dw; aPos[2][numG] = dl; aPos[3][numG] = dt;
   }
  P->Parent = G;
  P->Name = "Panel" + IntToStr(nPanel++);
  P->Caption = "";
  P->Left = aPos[2][numG];
  P->Top = aPos[3][numG];
  P->Width = aPos[1][numG];
  P->Height = aPos[0][numG];
  aPos[2][numG] = P->Left + P->Width + 2;
  if(aPos[2][numG] > G->Width)
   {
     aPos[2][numG] = dl;
     aPos[3][numG] = P->Top + P->Height + 2;
   }
//Создаем метку
  TLabel *L = new TLabel(P);
  L->Parent = P;
  L->Name = "Label" + IntToStr(nLabel++);
  L->AutoSize = true;
  L->Caption = String().sprintf(L"%s на %s", P->Name, P->Parent->Name);
  L->Left = 6;
  L->Top = 3;
//Создаем Едит
  TEdit *E = new TEdit(P);
  E->Parent = P;
  E->Name = "Edit" + IntToStr(nEdit++);
  E->Top = L->Top + L->Height + 4;
  E->Left = L->Left;
  E->Text = String().sprintf(L"%s: X = %d, Y = %d", P->Name, P->Left, P->Top);
  G->Caption = String().sprintf(L"%s содержит %d компонентов", G->Name, G->ControlCount);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  if(CheckBox1->Checked) CreatePanel(GroupBox1, 1);
  if(CheckBox2->Checked) CreatePanel(GroupBox2, 2);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  nPanel = nLabel = nEdit = 1;
  dh = 50; dw = 180; dl = 8; dt = 20;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::DeletePanel(TGroupBox *G)
{
  TPanel *P;
  for(int i(0); i < G->ControlCount;)
   {
     if (P = dynamic_cast <TPanel*>(G->Controls[i]))
      delete P;
     else ++i;
   }
  G->Caption = String().sprintf(L"%s содержит %d компонентов", G->Name, G->ControlCount);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
  if(CheckBox1->Checked) DeletePanel(GroupBox1);
  if(CheckBox2->Checked) DeletePanel(GroupBox2);
}
//---------------------------------------------------------------------------
Миниатюры
Динамическое создание и удаление объектов VCL  
0
 Аватар для kodv
1449 / 1121 / 347
Регистрация: 11.04.2011
Сообщений: 2,621
29.09.2014, 11:08
Цитата Сообщение от andrei1994 Посмотреть сообщение
Кто-нибудь знает как сделать чтобы не налаживалась Panel одна на одну , а только на свободном месте??
Немножко поковырял билдер. Следующая функция возвращаетс случайные координаты места в объекте наследника TWinControl (TGroupBox, TRadioGroup), в которое можно вписать объект наследника TControl. Чтобы программка не зависала, выполняется ограниченное количество попыток поиска, по истечению которых вываливается исключение.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
TPoint FindFreePlace(TWinControl* winControl, TControl* control, int tryCount = 1000)
{
        randomize();
        bool success;
        TPoint ret;
        do
        {
                ret.x = random(winControl->Width - control->Width);
                ret.y = random(winControl->Height - control->Height);
                if(!(success = !winControl->ControlCount))
                {
                        success = true;
                        for(int i(0); i < winControl->ControlCount; ++i)
                                success &= winControl->Controls[i]->Left > (ret.x + control->Width)
                                        || winControl->Controls[i]->Top > (ret.y + control->Height)
                                        || ret.x > (winControl->Controls[i]->Left + winControl->Controls[i]->Width)
                                        || ret.y > (winControl->Controls[i]->Top + winControl->Controls[i]->Height);
                }
                if(!--tryCount)
                        throw Exception("Превышено число попыток найти свободного место для размещения контрола");
        }
        while(!success);
        return ret;
}
PS: функции с неслучайным размещеним добавляемых контролов есть выше.
0
0 / 0 / 0
Регистрация: 19.09.2014
Сообщений: 32
29.09.2014, 22:51  [ТС]
D1973 я пробую запустить твой код и не получается, косяк в том что при нажатии на кнопку пишется что создается но не отображается в GroupBox в чем проблема??

Добавлено через 3 часа 30 минут
С большего разобрался , всем большое спасибо!)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.09.2014, 22:51

Динамическое создание объектов
Здравствуйте, подскажите пожалуйста как решить задачку... Пусть известно кол-во строк = 10 как сделать так чтоб в одной строке было:...

Динамическое создание объектов
Всем привет! Задача По нажатию кнопки &quot;Create&quot; создается двумерный массив элементов TCheckBox и располагается на форме. По...

Динамическое создание объектов класса
Всем привет. При компиляции выдает ошибку Unit1.cpp(26): E2451 Undefined symbol 'product' и Unit1.cpp(43): E2451 Undefined symbol...

Динамическое создание и удаление компонентов.
Понадобилось динамическое создание нескольких компонентов, при нажатии на кнопку. Несколько нажатий - несколько раз создаются компоненты....

HELP::Создание->удаление динамических объектов
Доброй ночи! У меня возникла такая проблема я динамически создаю объекты типа кнопка: void __fastcall TMainForm::Button1Click(TObject...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
34
Ответ Создать тему
Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru