Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.93/40: Рейтинг темы: голосов - 40, средняя оценка - 4.93
0 / 0 / 0
Регистрация: 13.01.2015
Сообщений: 137
1

Доступ к виджетам другой формы

20.01.2015, 08:34. Показов 7306. Ответов 20
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
У меня есть форма camWindow.h, на нее в дизайнере навешен gridLayout

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
#ifndef CAMWINDOW_H
#define CAMWINDOW_H
 
#include <QDialog>
#include <cameraviewholder.h>
 
namespace Ui {
class camWindow;
}
 
class camWindow : public QDialog
{
    Q_OBJECT
public:
    explicit camWindow(QWidget *parent = 0);
    ~camWindow();
    CameraViewHolder* m_viewHolder;
    Ui::camWindow *ui;
public slots:
    void get_viewHolder(CameraViewHolder*);
};
 
#endif // CAMWINDOW_H
Так же, есть главное окно MainWindow , где создается QList с элементами класса camWindow (#include <camWindow.h> есть)
C++ (Qt)
1
QList<camWindow*> windowList;
Работаем в MainWindow. Создаем новый элемент , записываем его в QList
C++ (Qt)
1
windowList.append(new camWindow());
Теперь мне необходимо на виджет gridLayout кинуть элемент m_view. По моим скромным надеждам должна работать эта строчка
C++ (Qt)
1
windowList.last()->ui->gridLayout->addWidget(m_view)
Но они не оправдываются, windowList.last()->ui подсвечивается, все нормально, но вот после ui Qt уже не видит gridLayout.

Это, скорее всего, очень глупая ошибка. Но я на ней застрял(
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.01.2015, 08:34
Ответы с готовыми решениями:

Доступ к виджетам в QGridLayout
Есть QGridLayout gl. Если заполнить его текстовыми полями через gl-&gt;addWidget(new...

Как в классе QVBoxLayout получить доступ к виджетам?
Ребята всем привет, появился вопрос, вот абстрактный код QLabel* Data_Source = new...

Как, имея только указатель на сам QGroubBox получить доступ к виджетам на нем
Осваиваю Qt. Динамически расположил два виджета внутри третьего. Как теперь, имея только указатель...

Доступ к переменной другой формы
Как дать доступ к переменной второй форме из первой?Допустим переменная это путь к файлу.Подскажите...

20
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
20.01.2015, 09:37 2
tohtarov_ufa, По умолчанию ui private. Лучше всего в классе создать public функцию, которая будет работать с ui.
Кроме того причем здесь подсветка?.....эти анализаторы часто глючат и могут не выдавать то что надо.
Ты программу собери и посмотри какую ошибку покажет.
1
0 / 0 / 0
Регистрация: 22.01.2015
Сообщений: 36
22.01.2015, 10:30 3
У меня похожий вопрос. Есть список устройств(Device,DeviceN..). При добавления устройства необходимо создавать свои виджеты, поля и т.д. Для Device свой набор виджетов, для DeviceN свой набор. Я для каждого типа устройства создаю свой класс, в этом классе есть функция, которая создает виджеты и возвращает указатель(мне так подсказали сделать)
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
class Device: public QObject
{
Q_OBJECT
public:
    explicit Device(QObject parent=0);
    ~Device(){}
    
    
    QWidget* widget();
    
 
    void setData1(Type1 value);
    Type1 data1();
    //...
    void setDataN(TypeN value);
    TypeN dataN();
 
 
private:
//тут храним данные
    Type1 _data1;
    // ...
    TypeN _dataN;
 
}
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
QWidget *Device::widget()
{
   QLabel *lbl = new QLabel;
   QLabel *lbl2 = new QLabel;
    lbl->setText("TEST");
    lbl2->setText("TEST2");
    QPushButton *pb = new QPushButton("ОК");
    QWidget *window = new QWidget;
    QHBoxLayout *lay = new QHBoxLayout;
    lay->addWidget(pb);
    lay->addWidget(lbl);
    lay->addWidget(lbl2);
    window->setLayout(lay);
    return window;
}
В главном файле создаю список устройств для каждого типа устройства
C++ (Qt)
1
QList<Device*> list
и при нажатии кнопки добавить устройство делаю следующее
C++ (Qt)
1
2
list.append(new Device);
ui->stackedWidget->addWidget(list[list.size()-1]->widget());
Виджеты отображаются, все хорошо!
Вопрос следующий: Как сейчас можно обратиться к виджетам которые мы создали? Как правильно это все реализовать?
C++ (Qt)
1
list.at(index)->widget()->lbl->setText("УРААА!!");
Такое не прокатывает(((
0
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
22.01.2015, 10:40 4
Casper17, Ну так правильно. Вы хотите обратиться к lbl. А что это такое? Вы создали переменную lbl и указатель на нее удалился с концом выполнения функции widget(). С чего вдруг вы теперь обращаетесь к свойству, которое не создали?
Добавьте в класс Device поле
QLabel *lbl;
а в widget() напишите lbl = new QLabel;
и все будет работать.
Ну или тогда уже через lay пытайтесь доступ получить.
0
0 / 0 / 0
Регистрация: 22.01.2015
Сообщений: 36
22.01.2015, 10:50 5
Просто мне посоветовали сделать так "Добавление устройства - создание экземпляра класса (объекта), отображение странички с его настройками вызовом функции класса widget(), которая создаст виджет со всем его содержимым и вернёт указатель. Ну а данные хранить в виде полей этого класса". Вот я и пытаюсь понять как можно обратиться к виджетам через указатель который нам вернет функция widget() и как для этого правильно ее написать.
А поля в классе QLabel *lbl добавлять в Public, да?
0
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
22.01.2015, 10:58 6
Casper17, Хотя нет, я не обратил внимание, что у вас сделано каждый раз создание нового окна....тогда так конечно можно, но правильнее использовать QWidget::children () для доступа к объектам....
0
0 / 0 / 0
Регистрация: 22.01.2015
Сообщений: 36
22.01.2015, 11:52 7
solar_wind, Подскажите пожалуйста функция widget() правильно написана, то ли она возвращает, что бы можно было обращаться к виджетам(lbl,pb..) Если да почему не работает list.at(index)->widget()->lbl->setText("УРААА!!");
или так нельзя делать?
Чуть по гуглив нашел это. T QObject::findChild ( const QString & name = QString() ) const Это рекомендуете использовать?
0
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
22.01.2015, 12:00 8
Casper17, Просто у QWidget нет свойства lbl, вот и не работает.
Что касается правильности, то так то вообщем то все правильно с точки зрения программирования. Правильно ли с точки зрения логики работы программы, это уже тебе нужно думать.
Можно в том числе findChild использовать
0
0 / 0 / 0
Регистрация: 22.01.2015
Сообщений: 36
22.01.2015, 12:38 9
Пробую написать программу для отображения информации. Есть центральное устройство, которое принимает данные от других устройств(дом, баня, теплица, гараж) и посылает эти данные по COM порту. Программа считывает эти данные записывает в нужный поля класса и отображает их.
Слева меню выбора устройства, под ним кнопка для добавления устройств. Остальную часть программы занимает QStackedWidget в котором будут отображаться информация с датчиков от выбранного устройства из меню слева.
Может конечно я не в ту степь пошел.
Миниатюры
Доступ к виджетам другой формы  
0
0 / 0 / 0
Регистрация: 22.01.2015
Сообщений: 36
24.01.2015, 09:18 10
solar_wind, С помощью findChildren я получил список элементов в моей формы QPushButton, QLabel, QLabel
C++ (Qt)
1
2
3
4
QList<QWidget *> list2 = list.at(0)->widget()->findChildren<QWidget *>();
    foreach(QWidget *g, list2) {
        qDebug()  << g->metaObject()->className();
    }
Подскажите, как обратиться к этим элементам, что бы изменить параметры? К примеру текст в QLabel.
0
Заблокирован
24.01.2015, 10:14 11
Цитата Сообщение от Casper17 Посмотреть сообщение
К примеру текст в QLabel.
Ну у тебя же их много может быть, к какому именно ты хочешь получить доступ?
0
0 / 0 / 0
Регистрация: 22.01.2015
Сообщений: 36
24.01.2015, 10:19 12
Цитата Сообщение от DukeNukem Посмотреть сообщение
к какому именно ты хочешь получить доступ?
к lbl необходимо получить доступ и поменять текст.
0
Заблокирован
24.01.2015, 10:25 13
Цитата Сообщение от Casper17 Посмотреть сообщение
к lbl необходимо получить доступ и поменять текст.
Ты не понял, у тебя на форме может быть много QLabel-ов, к какому именно ты хочешь получить доступ, не понятно, но думаю догадаешься сам поставить какой - нибуть if для проверки, ну а чтоб поменять текст у всех QLabel в твоём случае, следует писать так:
C++ (Qt)
1
2
3
4
QList<QLabel *> list2 = list.at(0)->widget()->findChildren<QLabel *>();
            foreach(QLabel *g, list2) {
                g->setText("HELLO :-)");
            }
0
0 / 0 / 0
Регистрация: 22.01.2015
Сообщений: 36
24.01.2015, 10:51 14
DukeNukem, у меня на форма создается два QLabel
C++ (Qt)
1
2
QLabel *lbl = new QLabel;
QLabel *lbl2 = new QLabel;
А как узнать(получить) имя lbl что бы к ней обратиться? Спасибо!

Добавлено через 18 минут
Цитата Сообщение от DukeNukem Посмотреть сообщение
ну а чтоб поменять текст у всех QLabel в твоём случае, следует писать так:

C++ (Qt)
1
2
3
4
5
QList<QLabel *> list2 = list.at(0)->widget()->findChildren<QLabel *>();
   foreach(QLabel *g, list2) {
   g->setText("HELLO :-)");
   qDebug()  << "Меняем текст на QLabel";
}
Попробовал, но текст не меняется. Но цикл проходит два раза, т.к. два QLabel у меня))
0
Заблокирован
24.01.2015, 10:54 15
Цитата Сообщение от Casper17 Посмотреть сообщение
А как узнать(получить) имя lbl что бы к ней обратиться?
Какое имя? Ты имеешь ввиду текст, который написан на QLabel?
QLabel::text() ?

Добавлено через 1 минуту
Цитата Сообщение от Casper17 Посмотреть сообщение
Попробовал, но текст не меняется.
Меняется там, где ты его меняешь, а там - это здесь у тебя list.at(0)->widget()
Что это? Код весь показывай тогда или архив с проектом прикрепляй
0
0 / 0 / 0
Регистрация: 22.01.2015
Сообщений: 36
24.01.2015, 10:56 16
DukeNukem, Я создаю два QLabel с именами lbl и lbl2. Мне нужно получить доступ к lbl и поменять текст.
0
Заблокирован
24.01.2015, 11:06 17
Цитата Сообщение от Casper17 Посмотреть сообщение
с именами lbl и lbl2.
ты имеешь ввиду, что ты в рантайме хочешь получить название переменной, которую ты использовал для обозначения объекта класса QLabel в коде программы? Это не возможно (почти невозможно, но тема эта явно не для тебя, без обид )

Добавлено через 8 минут
Если ты хочешь как - то обособить свои лейблы друг от друга, наследуйся от QLabel и вводи какие - то свои нужные ID, ну или какой - нибуть класс инфо:
C++
1
2
3
4
5
 class MyClass
 {
     Q_OBJECT
     Q_CLASSINFO("author", "Sabrina Schweinsteiger")
     Q_CLASSINFO("url", "http://doc.moosesoft.co.uk/1.0/")
которое потом будешь читать через metaObject()->classInfo()
0
0 / 0 / 0
Регистрация: 22.01.2015
Сообщений: 36
24.01.2015, 11:18 18
mainwindow.h
Кликните здесь для просмотра всего текста
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
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
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
#include <QLabel>
#include <QSerialPort>
#include <QListWidgetItem>
#include <QList>
#include "device.h"
#include "bath.h"
 
 
 
namespace Ui {
class MainWindow;
}
class SettingsComPort;
class MainWindow : public QMainWindow
{
    Q_OBJECT
 
public:
    explicit MainWindow(QWidget *parent = 0);
    QString data;
    int value;
    QString namePort1;
 
 
    ~MainWindow();
 
 
private:
    Ui::MainWindow *ui;
    QLabel *lbl;
    QSerialPort *serial;
    SettingsComPort *settingsComPort;
    QList<Device*> list;
    QList<Bath*> listB;
 
private slots:
    void on_actionExit_triggered();
    void on_actionSettingsComPort_triggered();
 
    void readData();
    void on_actionConnectComPort_triggered();
 
    void on_actionDisconnectComPort_triggered();
 
    void on_pbAdd_clicked();
 
    void on_listWidget_currentRowChanged(int currentRow);
    void on_pushButton_clicked();
 
    void on_comboBox_activated(const QString &arg1);
};
 
#endif // MAINWINDOW_H


mainwindow.cpp
Кликните здесь для просмотра всего текста

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
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "settingscomport.h"
#include "device.h"
#include "bath.h"
#include <QDebug>
#include <QtSerialPort/QSerialPortInfo>
 
 
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),data(""),value(0),namePort1(""),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
 
    setWindowTitle("Умный дом");
 
    settingsComPort = new SettingsComPort();
    settingsComPort->setWindowTitle("Выбор СОМ порта");
 
    serial = new QSerialPort(this);
    ui->actionDisconnectComPort->setEnabled(false);
 
    ui->comboBox->setCurrentIndex(0);
 
    connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
 
 
        foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
        {
 
            QString s = info.description();
            s = s.mid(0,7);
 
            if(s == "Arduino")
            {
                namePort1 = info.portName();
                break;
            }
        }
 
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
void MainWindow::on_actionExit_triggered()
{
    serial->close();
    close();
}
 
void MainWindow::on_actionSettingsComPort_triggered()
{
    settingsComPort->show();
}
 
void MainWindow::readData()
{
    qDebug() << "Razmer        : " << serial->bytesAvailable();
    do {
            data.append(serial->readAll());
             qDebug() << "Name        : " << data;
        } while (serial->waitForReadyRead(50));
    if(data.endsWith("3"))
    {
        qDebug() << "///////OK/////////";
        QString y = data.mid(6, 3);
        qDebug() << "///////123/////////" << y;
        int x = y.toInt();
        ui->spinBox->setValue(value+=x);
        ui->label->setText(data.remove(data.size()));
        data.clear();
    }
    else
        qDebug() << "///////FALSE/////////";
    //ui->label->setText(data);
    qDebug() << "///////////////////";
 
}
 
void MainWindow::on_actionConnectComPort_triggered()
{
     serial->setPortName(namePort1);
    if(serial->open(QIODevice::ReadWrite)){
 
        serial->setBaudRate(QSerialPort::Baud9600);
        serial->setDataBits(QSerialPort::Data8);
        serial->setParity(QSerialPort::NoParity);
        serial->setStopBits(QSerialPort::OneStop);
        serial->setFlowControl(QSerialPort::NoFlowControl);
        ui->label->setText("OK");
        ui->actionConnectComPort->setEnabled(false);
        ui->actionDisconnectComPort->setEnabled(true);
        ui->statusBar->showMessage(tr("Подключение установлено!"));
}
else
    {
        ui->label->setText("NO CONNECT");
        ui->statusBar->showMessage(tr("Выбирите в настройках COM порт!"));
    }
}
 
void MainWindow::on_actionDisconnectComPort_triggered()
{
    ui->actionConnectComPort->setEnabled(true);
    ui->actionDisconnectComPort->setEnabled(false);
    serial->close();
    ui->statusBar->showMessage(tr("Подключение сброшено!"));
}
 
void MainWindow::on_pbAdd_clicked()
{
    ui->listWidget->addItem(ui->comboBox->currentText());
    //ui->stackedWidget->addWidget(new QLabel(ui->comboBox->currentText(),this));
    if (ui->comboBox->currentText()=="Баня")
        {
        listB.append(new Bath);
 
        ui->stackedWidget->addWidget(listB[listB.size()-1]->widget());
    }
    else{
        list.append(new Device);
        ui->stackedWidget->addWidget(list[list.size()-1]->widget());
 
    }
 
 
}
 
void MainWindow::on_listWidget_currentRowChanged(int currentRow)
{
    ui->stackedWidget->setCurrentIndex(currentRow);
}
 
void MainWindow::on_pushButton_clicked()
{
  /*
    QList<QWidget *> list2 = list.at(0)->widget()->findChildren<QWidget *>();
    foreach(QWidget *g, list2) {
        qDebug()  << g->metaObject()->className();
       }
       */
    QList<QLabel *> list2 = list.at(0)->widget()->findChildren<QLabel *>();
                foreach(QLabel *g, list2) {
                    g->setText("HELLO :-)");
                    qDebug()  << "Меняем текст на QLabel";
                }
 
}
 
 
void MainWindow::on_comboBox_activated(const QString &arg1)
{
    if (arg1=="Баня")
        {
        listB.append(new Bath);
         ui->listWidget->addItem(ui->comboBox->currentText());
        ui->stackedWidget->addWidget(listB[listB.size()-1]->widget());
    }
   // ui->comboBox->setCurrentIndex(0);
}


device.h
Кликните здесь для просмотра всего текста
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
#ifndef DEVICE_H
#define DEVICE_H
 
#include <QObject>
#include <QWidget>
#include <QLabel>
#include  <QPushButton>
#include <QHBoxLayout>
 
 
class Device : public QObject
{
    Q_OBJECT
public:
    explicit Device(QObject *parent = 0);
    ~Device();
 
    QWidget *widget();
 
signals:
 
public slots:
};
 
#endif // DEVICE_H


device.cpp
Кликните здесь для просмотра всего текста
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
27
28
29
30
#include "device.h"
 
 
 
 
Device::Device(QObject *parent) : QObject(parent)
{
 
}
 
Device::~Device()
{
 
}
 
QWidget *Device::widget()
{
    QLabel *lbl = new QLabel;
    QLabel *lbl2 = new QLabel;
    lbl->setText("TEST");
    lbl2->setText("TEST2");
    QPushButton *pb = new QPushButton("Кнопка");
    QWidget *window = new QWidget;
    QHBoxLayout *lay = new QHBoxLayout;
    lay->addWidget(pb);
    lay->addWidget(lbl);
    lay->addWidget(lbl2);
    window->setLayout(lay);
    return window;
}

Я из списка ComboBox выбираю первое устройство Device и нажимаю кнопку добавить. В QList добавляется устройство и в stackedWidget добавляется форма для этого устройства функцией widget. Код конечно кривой, много лишнего есть, т.к. экспериментирую)) Да я не обижаюсь))
0
5 / 5 / 1
Регистрация: 05.06.2018
Сообщений: 31
08.08.2018, 14:49 19
Виноват, разворошил старую тему, но в ней автор так и не получил ответа (и я ковыряю этот вопрос, хочу из диалога поменять текст на кнопке основного окна, формы приложения). Причем поражает, что отвечающие так и не уловили сути, которая понятна даже мне, новичку.

У автора имеется основное окно - mainwindow.cpp и дополнительное в виде диалога device.cpp
В основном окне он, понятное дело может сделать так: ui->lbl->setText( "sometext" ); но в диалоге не прокатит.
Если бы в диалоге было что-то вроде MainWindow->label->setText("OK"); то осталось бы подцепить лишь #include "maiwindow.h" но сказки нет. Все что может диалог, это подсветить MainWindow->ui;

Для передачи переменных между формами есть отличный пример "DemoWidget.rar " в восьмом посте "https://www.cyberforum.ru/qt/thread2183127.html" и можно наверное его "докрутить" с сигналами и слотами примерно до уровня "MainWindow->label->setText("OK");", но получится колхоз с костылями. Должно быть изящное решение. Кто-нибудь подскажет?
0
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
09.08.2018, 12:49 20
VladQtCr, Да суть вопроса как раз всем понятна.
Задача сама по себе элементарная.
Сигналы и слоты, если они к месту, то это совсем не костыль.
В данном случае объект диалога создан в основном окне. По всем правилам ООП диалог не должен знать кто его создал, но может иметь интерфейс для передачи своему создателю какой либо информации.
Самым адекватным и независимым методом для этого является механизм сигналов и слотов.
Подчиненный диалог должен иметь сигнал, через который он передает наружу данные.
Основное окно, при создании подчиненного диалога, должно определиться, как оно хочет с диалогом работать. И если основному окну интересны данные идущие от подчиненного диалога, то оно создает слот и связывает сигнал диалога с этим слотом.
Подчиненный диалог отправляет сигнал. Этот сигнал приходит в слот основного окна. Основное окно разбирает полученные данные и отображает все, что ему нужно.
1
09.08.2018, 12:49
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.08.2018, 12:49
Помогаю со студенческими работами здесь

Получить доступ обьекта из другой формы
Доброго времени суток дорогие программеры. Есть главное окно MainWindow, и второе окно Dialog; ...

Доступ к полям одной формы из другой формы
Программа состоит из двух windows form. В первой форме формируется структура массивов с данными. Во...

Доступ к элементу одной формы из другой формы
Здравствуйте. Есть Form2, в конструктор которой как Owner передаётся Form1. В ходе работы Form2...

Доступ из другой формы
мне нужно осуществить поиск из другой формы в datagridviev к которой подключена бд. Как осуществить...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru