Форум программистов, компьютерный форум, киберфорум
Наши страницы

Qt

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 47, средняя оценка - 4.62
Speedy Gonzales
6 / 6 / 1
Регистрация: 22.10.2010
Сообщений: 82
#1

Программное добавление элемента на форму - C++ Qt

25.11.2012, 18:17. Просмотров 6985. Ответов 21
Метки нет (Все метки)

Доброе всем со-товарищам!
Перехожу на Qt с C# и возникло пару проблем с динамическим добавлением на форму элементов управления. На шарпе все было просто, создаем элемент класса, добавляем его хар-ки и через координаты размещаем его на Form Все очень хорошо работает, что через дизайнер, что чисто программное размещение к уже имеющимся элементам. В Qt возникла сложность с этим. В дизайнере создал форму:

http://s6.image1.org/images/2012/11/...6e91a1e79f.jpg
потом я задаю функцию, при нажатии кнопку должно, допустим, получится такое:

http://s6.image1.org/images/2012/11/...bc06c879d3.jpg
пробовал сделать похожим, как на шарпе способом, но New_GB с NewButton растягиваются на всю форму и никакие setGeometry не помогают. Сделайте маленький ЛикБез по этому вопросу, пожалуйста. Наверное многим это бы пригодилось бы.
Заранее спасибо.
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void MainWindow::on_pushButton_clicked()
{
    qDebug()<<centralWidget()->children(); 
    newFun();
}
 
void MainWindow::newFun()
{
    QGridLayout *grid = new QGridLayout;
    QGroupBox *gb = new QGroupBox(tr("New GroupBox"));
    gb->setGeometry(90, 100, 100, 100);
    QPushButton *pb=new QPushButton(tr("NewButton"));
    pb->setGeometry(20, 20, 50, 50);
    grid->addWidget(gb);
 
    
    ui->centralWidget->setLayout(grid);
    
}
без
C++ (Qt)
1
QGridLayout *grid = new QGridLayout;
вообще ничего не хотелось вставляться. Думал, что можно просто добавлять в centralWidget любые элементы, но мне сказали - ФИГ...

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
void MainWindow::newFun()
{
    QGroupBox *gb = new QGroupBox(tr("New GroupBox"));
    gb->setGeometry(90, 100, 100, 100);
    QPushButton *pb=new QPushButton(tr("NewButton"));
    pb->setGeometry(20, 20, 50, 50);
 
    gb->setLayout(pb);
    
    ui->centralWidget->setLayout(gb);
    
}


так нельзя.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.11.2012, 18:17
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Программное добавление элемента на форму (C++ Qt):

Добавление картинки на форму - C++ Qt
Тект в qlabel добавляется, а картинка нет. Что я делаю не так? MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ...

Добавление картинок в форму - C++ Qt
Имхо простейшая задача, но почему-то не смог сам найти решение. Как добавить картинку на форму?

Qt, добавление на существующую форму (не динамически) - C++ Qt
есть Qtшная форма. давно созданная, к ней есть её хеддер(как я понимаю сгенерированный автоматически) на форму нужно добавить 1 лэйбл и...

Добавление виджетов на форму QtDesigner - C++ Qt
Здравствуйте. Помогите разобраться пожалуйста. Скачал QT, создал проект, но в конструкторе форм не удаётся бросить компоненты на форму (я...

Добавление данных на форму с текстового файла - C++ Qt
Здравствуйте, возникла необходимость сделать тоже самое что и в этой теме http://www.cyberforum.ru/vb-net/thread948561.html только на QT ...

Добавление виджетов на форму [QtDesigner или вручную] - C++ Qt
Где лучше всего делать виджеты в дизайнере или вручную.

21
KeyGen
384 / 291 / 6
Регистрация: 07.08.2011
Сообщений: 790
Записей в блоге: 1
26.11.2012, 00:50 #2
Могу посоветовать книгу: Макс Шлее, Qt4 Профессиональное программирование на С++. Читай такие вопросы отпадут.
1
Speedy Gonzales
6 / 6 / 1
Регистрация: 22.10.2010
Сообщений: 82
26.11.2012, 10:51  [ТС] #3
Спасибо большое, я купил его книгу и поизучал. Там используется система виджетов, а хотелось бы понять как можно работать без них. В дизайнере можно просто размещать элементы управления, так почему же нельзя их так же размещать программно?
0
Чистый
Автор FAQ
2710 / 1406 / 73
Регистрация: 08.09.2011
Сообщений: 3,741
Записей в блоге: 1
26.11.2012, 10:58 #4
а вы и размещаете виджеты, т.е. элементы управления это и есть виджеты
0
Dmitriy_M
1375 / 1258 / 114
Регистрация: 20.03.2009
Сообщений: 4,490
Записей в блоге: 11
26.11.2012, 10:58 #5
Цитата Сообщение от Speedy Gonzales Посмотреть сообщение
Спасибо большое, я купил его книгу и поизучал. Там используется система виджетов, а хотелось бы понять как можно работать без них. В дизайнере можно просто размещать элементы управления, так почему же нельзя их так же размещать программно?
Можно, но почти никто так не делает.
1
Speedy Gonzales
6 / 6 / 1
Регистрация: 22.10.2010
Сообщений: 82
26.11.2012, 11:56  [ТС] #6
Я пытаюсь сделать элементарное действие, через кнопку добавить groupBox на форму в определенном месте, а в итоге этот groupBox занимает все пространство centralWidget. Хотя я задавал координаты и размеры groupBox.
0
Dmitriy_M
1375 / 1258 / 114
Регистрация: 20.03.2009
Сообщений: 4,490
Записей в блоге: 11
26.11.2012, 12:01 #7
Цитата Сообщение от Speedy Gonzales Посмотреть сообщение
Я пытаюсь сделать элементарное действие, через кнопку добавить groupBox на форму в определенном месте, а в итоге этот groupBox занимает все пространство centralWidget. Хотя я задавал координаты и размеры groupBox.
Не надо было запихивать в компоновщик.
В качестве парента, для QGroupBox указываешь centralWidget и получаешь то что нужно.

Возможно проще создать объект за ранее и скрыть, а по нажатию сделать объект видимым.
1
_SASA_
133 / 137 / 6
Регистрация: 22.08.2011
Сообщений: 484
26.11.2012, 13:53 #8
Здравствуйте!
Dmitriy_M все правильно написал =
уберите Layout, если не хотите растягиваний,
а родителя можно задать и так:
C++ (Qt)
1
2
3
4
5
6
7
8
... // this - тот родитель внутри которого пишите...
QGroupBox *gb = new QGroupBox(tr("New GroupBox"),this);
gb->setGeometry(90, 100, 100, 100);
gb->show();
QPushButton *pb=new QPushButton(tr("NewButton"),this);
pb->setGeometry(20, 20, 50, 50);
pb->show();
...
Удачи!!
2
Speedy Gonzales
6 / 6 / 1
Регистрация: 22.10.2010
Сообщений: 82
26.11.2012, 17:35  [ТС] #9
Спасибо большое, оказалось просто нужно использовать
C++ (Qt)
1
Show();
Но так я просто смогу отобразить элемент в centralWidget и при этом он не растягивается по всей форме. А вот можно сделать, чтобы он был наследником centralWidget? И так же занимал любую позицию на форме (через setGeometry() )?

Догадался, что можно так

C++ (Qt)
1
gb->setParent(ui->centralWidget);
Добавлено через 3 часа 4 минуты
А еще не подскажите к получить все имена элементов формы

C++ (Qt)
1
2
for (var=0 var > ui->centralWidget->children().count() ++var)
ui->centralWidget->children.at(var);
Так я могу получить все элементы, а как можно получить только их name?
0
HomeR_J_SimpsoN
59 / 59 / 2
Регистрация: 15.10.2010
Сообщений: 356
26.11.2012, 21:30 #10
Цитата Сообщение от Speedy Gonzales Посмотреть сообщение
к получить все имена элементов формы
http://doc.qt.digia.com/qt/qobject.html#children
Любой виджет - наследник QObject. Соответственно ф-ией children() можно получить всех потомков любого виджета. Результат ф-ии -- QList< QObject * >.
Соответственно, перебирая контейнер поэлементно, можно получить доступ к любому объекту, являющемуся дочерним к данному.
Далее ф-ией QObject::objectName() получаем его имя.
1
Speedy Gonzales
6 / 6 / 1
Регистрация: 22.10.2010
Сообщений: 82
27.11.2012, 07:45  [ТС] #11
большое спасибо!
а можно немного расширить ответ и небольшой пример кода дать с QList< QObject * >
0
HomeR_J_SimpsoN
59 / 59 / 2
Регистрация: 15.10.2010
Сообщений: 356
27.11.2012, 12:14 #12
Цитата Сообщение от Speedy Gonzales Посмотреть сообщение
небольшой пример кода
Лично я не вижу особого смысла в переборе каждого компонента формы.
Проще запрашивать у родителя определенные виджеты, зная их тип и имя.

Например, был создан виджет с парой кнопок:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
QWidget *w = new QWidget(this);
w->setObjectName("containerWidget");
w->setLayout(new QVBoxLayout);
 
QPushButton *btn = new QPushButton;
btn->setText(tr("Кнопка 1");
btn->setObjectName("btn1");
w->layout()->addWidget(btn);
 
btn = new QPushButton;
btn->setText(tr("Кнопка 2");
btn->setObjectName("btn2");
w->layout()->addWidget(btn);
Теперь где то еще найдем эти кнопки и изменим их текст:
C++ (Qt)
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
// Попробуем сначала взять весь список сыновей для Виджета containerWidget
// Но для начала его надо тоже найти
QWidget *w = this->findChild< QWidget * >("containerWidget");
 
QObjectList l = w->children();
foreach (QObject *o, l)
{
    if (o->metaObject()->className() == "QPushButton")
    {
        QPushButton *b = static_cast< QPushButton * >(o);
        b->setText(tr("Текст изменен"));
    }
}
// Теперь просто найдем все кнопки с нашего виджета:
QList< QPushButton * > l1 = w->findChildren< QPushButton * >();
foreach (QPushButton *b, l1)
{
    if (b->objectName() == "btn1")
        b->setText(tr("Кнопка 1, текст изменен"));
    else if (b->objectName() == "btn2")
        b->setText(tr("Кнопка 2, текст изменен"));
}
 
// Теперь просто возьмем конкретную кнопку с виджета и изменим ее текст
w->findChild< QPushButton * >("btn1")->setText(tr("Нашли кнопку 1"));
w->findChild< QPushButton * >("btn2")->setText(tr("Нашли кнопку 2"));
0
Dmitriy_M
1375 / 1258 / 114
Регистрация: 20.03.2009
Сообщений: 4,490
Записей в блоге: 11
27.11.2012, 12:24 #13
Кликните здесь для просмотра всего текста
Цитата Сообщение от HomeR_J_SimpsoN Посмотреть сообщение
Лично я не вижу особого смысла в переборе каждого компонента формы.
Проще запрашивать у родителя определенные виджеты, зная их тип и имя.

Например, был создан виджет с парой кнопок:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
QWidget *w = new QWidget(this);
w->setObjectName("containerWidget");
w->setLayout(new QVBoxLayout);
 
QPushButton *btn = new QPushButton;
btn->setText(tr("Кнопка 1");
btn->setObjectName("btn1");
w->layout()->addWidget(btn);
 
btn = new QPushButton;
btn->setText(tr("Кнопка 2");
btn->setObjectName("btn2");
w->layout()->addWidget(btn);
Теперь где то еще найдем эти кнопки и изменим их текст:
C++ (Qt)
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
// Попробуем сначала взять весь список сыновей для Виджета containerWidget
// Но для начала его надо тоже найти
QWidget *w = this->findChild< QWidget * >("containerWidget");
 
QObjectList l = w->children();
foreach (QObject *o, l)
{
    if (o->metaObject()->className() == "QPushButton")
    {
        QPushButton *b = static_cast< QPushButton * >(o);
        b->setText(tr("Текст изменен"));
    }
}
// Теперь просто найдем все кнопки с нашего виджета:
QList< QPushButton * > l1 = w->findChildren< QPushButton * >();
foreach (QPushButton *b, l1)
{
    if (b->objectName() == "btn1")
        b->setText(tr("Кнопка 1, текст изменен"));
    else if (b->objectName() == "btn2")
        b->setText(tr("Кнопка 2, текст изменен"));
}
 
// Теперь просто возьмем конкретную кнопку с виджета и изменим ее текст
w->findChild< QPushButton * >("btn1")->setText(tr("Нашли кнопку 1"));
w->findChild< QPushButton * >("btn2")->setText(tr("Нашли кнопку 2"));


А не проще ли хранить указатели на созданные виджеты в QMap<QString, QWidget*>?
0
HomeR_J_SimpsoN
59 / 59 / 2
Регистрация: 15.10.2010
Сообщений: 356
27.11.2012, 12:33 #14
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
А не проще ли хранить указатели на созданные виджеты в QMap<QString, QWidget*>?
Мне проще так.
И работает быстрее чем сравнивать по хэш таблице строки.

Добавлено через 5 минут
Да и зачем мудрить свой огород, если есть отличные стандартные средства.
0
Dmitriy_M
1375 / 1258 / 114
Регистрация: 20.03.2009
Сообщений: 4,490
Записей в блоге: 11
27.11.2012, 12:47 #15
Цитата Сообщение от HomeR_J_SimpsoN Посмотреть сообщение
А если на форме 100500 элементов динамически там размещенных?
Эти 100500 элементов будут сжирать столько памяти, что на их фоне несколько сот килобайт или 1-2 мегабайта смотрятся скромно. Однако работать будет на порядок быстрее твоего перебора при помощи foreach

Добавлено через 4 минуты
Цитата Сообщение от HomeR_J_SimpsoN Посмотреть сообщение
И работает быстрее чем сравнивать по хэш таблице строки.
Обычно map реализуется деревьями поиска. А QHash может работать еще быстрее, т.к. хеш функция от строки вычисляется один раз.
C++ (Qt)
1
uint    qHash ( const QString & key )
2
27.11.2012, 12:47
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.11.2012, 12:47
Привет! Вот еще темы с ответами:

программное добавление объектов на форму - Delphi
не как не могу разобраться procedure TForm1.Button1Click(Sender: TObject); var b : TButton; begin b := TButton.Create(Self); ...

Программное добавление элементов в пользовательскую форму - VBA
Доброго времени суток! Есть пользовательская форма (см. вложение). Стоит нетривиальная задача (во всяком случае для меня). :) Нужно...

Программное добавление id элемента - JavaScript
Добрый день! Через скрип добавляю на страницу 9 кнопок function CreateTable(){ var index=0; var x=530;// положение...

Добавление уникального элемента на форму - HTML, CSS
ребят, помогите добавить что-то свое(уникальное) к этой форме, не могу ничего придумать


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru