1 Востаннє редагувалося FastForward (03.03.2014 16:17:57)

Тема: Доступ до елемента іншого класу

C++ i Qt
Допоможіть, через QtDesigner створив форму і помістив на неї віджет, який перетворив на MyWidget, тепер потрібно мати доступ до елементів форми (ui) через MyWidget, як це реалізувати?
знайшов багато рішень проблеми в інтернеті, але багато не підходить, через те, що об’єкт  MyWidget є елементом класу Widget.
пробував зробити через методи get i set, але нічого не вийшло, бо виходить що обидва класи невизначені і йде таке собі зациклення(
ось код:
widget.h

Прихований текст
#ifndef WIDGET_H
#define WIDGET_H

#include "ui_widget.h"

class Widget : public QWidget, private Ui::mainWidget
{
    Q_OBJECT
    
public:
    explicit Widget(QWidget *parent = 0);
};

#endif // WIDGET_H

widget.cpp

Прихований текст
#include "widget.h"
Widget::Widget(QWidget *parent) :
    QWidget(parent)
{
    setupUi(this);
}

mywidget.h

Прихований текст
#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>
#include <QPainter>

class MyWidget : public QWidget
{
    Q_OBJECT
public:
    explicit MyWidget(QWidget *parent = 0);
    
signals:
    
public slots:
    
protected:
    void paintEvent(QPaintEvent *);
    QPainter paint;
};

#endif // MYWIDGET_H

mywidget.cpp

Прихований текст
#include "mywidget.h"

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent)
{
}

void MyWidget::paintEvent(QPaintEvent *)
{

    int w = this->width();
    int h = this->height();

    QPainter p(this);
    //p.drawLine(0,0,w, h);
    p.drawLine(w/2, 0, w/2, h);
    p.drawLine(0, h/2, w, h/2);
    for(int i = 10; i < h; i+=10)
    {
        p.drawLine(w/2 - 1, i, w/2 + 1, i);
    }
    for(int i = 10; i < w; i+=10)
    {
        p.drawLine(i, h/2 - 1, i, h/2 + 1);
    }
}

main.cpp

Прихований текст
#include <QtGui/QApplication>
#include "widget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    
    return a.exec();
}

ui_widget.h

Прихований текст
#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QHeaderView>
#include <QtGui/QPushButton>
#include <QtGui/QWidget>
#include "mywidget.h"

QT_BEGIN_NAMESPACE

class Ui_mainWidget
{
public:
    MyWidget *drawWidget;
    QPushButton *pushButton;

    void setupUi(QWidget *mainWidget)
    {
        if (mainWidget->objectName().isEmpty())
            mainWidget->setObjectName(QString::fromUtf8("mainWidget"));
        mainWidget->resize(531, 300);
        drawWidget = new MyWidget(mainWidget);
        drawWidget->setObjectName(QString::fromUtf8("drawWidget"));
        drawWidget->setGeometry(QRect(60, 50, 261, 211));
        pushButton = new QPushButton(mainWidget);
        pushButton->setObjectName(QString::fromUtf8("pushButton"));
        pushButton->setGeometry(QRect(380, 70, 98, 27));

        retranslateUi(mainWidget);

        QMetaObject::connectSlotsByName(mainWidget);
    } // setupUi

    void retranslateUi(QWidget *mainWidget)
    {
        mainWidget->setWindowTitle(QApplication::translate("mainWidget", "Widget", 0, QApplication::UnicodeUTF8));
        pushButton->setText(QApplication::translate("mainWidget", "do it", 0, QApplication::UnicodeUTF8));
    } // retranslateUi

};

namespace Ui {
    class mainWidget: public Ui_mainWidget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H

2

Re: Доступ до елемента іншого класу

1. Користуйтеся теґом spoiler. І пишіть назви файлів, якщо вони один на одного посилаються; ні, інклудгарда не досить.
2. Описуйте не свої враження ("йде таке собі зациклення"), а конкретно те, що відбувається (повідомлення компілятора, скріншот і т.д.). Звісно, якщо до опису того, що відбувається, ви додасте свої роздуми, це буде вам плюс, але роздуми без опису нічого не дають - хоча б тому, що вони можуть базуватися на хибному припущені.
3.
class Widget
...
void setupUi(QWidget *Widget)
Щось зробіть з ідентифікаторами; наприклад, тут є непогані поради (одні з можливих).

Подякували: FastForward1

3

Re: Доступ до елемента іншого класу

Якщо закритість даних не грає особливої ролі - гляньте у бік friend-класів.

4 Востаннє редагувалося FastForward (03.03.2014 16:34:36)

Re: Доступ до елемента іншого класу

мої роздуми спочатку були такі:
1. До класу Widget додати

private:
    Ui::mainWidget myui;
public:
    Ui::mainWidget * GetUi(void)
    {
        return &myui;
    }

2. До класу MyWidget додати

private:
    Ui::mainWidget *ui;
public:
    void SetUi(Ui::mainWidget *pt)
    {
        ui = pt;
    }

3. В файлі ui_widget.h передати ui, але наступною проблемою є те що класи залежні і код не компілюється (ui_widget.h не бачить клас MyWidget та й не по оопешному це), тож шукаю інший варіант вирішення

5

Re: Доступ до елемента іншого класу

Повертати форму (або ще ліпше - вказівник на неї) - не файно.

Варіантів у лоб - два:
1. Якщо у класі А є форма Б, у якої є поле В, то можна зробити public-метод A::getMyField(), який поверне Б.В по значенню.
2. Якщо треба налагодити тісну взаємодію між об'єктами різних класів, можна зробити їх дружніми (friend).

6

Re: Доступ до елемента іншого класу

Я все ще чекаю на п.2. Мені здається, ви не знаєте, що таке попереднє проголошення (forward declaration), але це тільки здається.

7 Востаннє редагувалося FastForward (03.03.2014 17:01:02)

Re: Доступ до елемента іншого класу

koala написав:

Я все ще чекаю на п.2. Мені здається, ви не знаєте, що таке попереднє проголошення (forward declaration), але це тільки здається.

що таке попереднє оголошення я знаю, або думаю що знаю, тобто мені потрібно було б перед класом Widget написати

class MyWidget;

але тут в мене була не в тому проблема, в класі MyWidget - елемент Widget, а в класі Widget - елемент MyWidget, тобто жоден з класів не оголошений повністю і компілятор мені видавав помилку, що не бачить клас MyWidget. тільки якось я заплутано написав

8

Re: Доступ до елемента іншого класу

Тобто скопіювати сюди повідомлення компілятора ви не здатні засадничо. Дякую.

9

Re: Доступ до елемента іншого класу

Bartash написав:

Повертати форму (або ще ліпше - вказівник на неї) - не файно.

Варіантів у лоб - два:
1. Якщо у класі А є форма Б, у якої є поле В, то можна зробити public-метод A::getMyField(), який поверне Б.В по значенню.
2. Якщо треба налагодити тісну взаємодію між об'єктами різних класів, можна зробити їх дружніми (friend).

я не зовсім зрозумів перший варіант, можна трішки детальніше, передавати окремо значення кожного елемента форми (кнопки, рядка і тд)?

10 Востаннє редагувалося mike (03.03.2014 17:35:06)

Re: Доступ до елемента іншого класу

в мене є один приклад, я створив форму, і на ній віджет в дезігнері, там же задав їй імя, наприклад:
імя - m_pTableOrders

потім це же віджет перетворив в клас, наприклад:
класс - QOrdersView

а потім в констукторі самої форми при ініціалізації, зробив таке:

m_pOrdersView = (QOrdersView*)ui->m_pTableOrders;

все, тепер я можу звертатись до віджета на формі як до свого. Думаю це те що вам потрібно

Подякували: FastForward1

11

Re: Доступ до елемента іншого класу

ще одне, файли типу ui_*.h вони генеряться автоматично, в них щось поправляти нема сенсу, оскільки їх створює ui-генератор

Подякували: FastForward1

12 Востаннє редагувалося FastForward (03.03.2014 23:55:12)

Re: Доступ до елемента іншого класу

muhasjo написав:

в мене є один приклад, я створив форму, і на ній віджет в дезігнері, там же задав їй імя, наприклад:
імя - m_pTableOrders

потім це же віджет перетворив в клас, наприклад:
класс - QOrdersView

а потім в констукторі самої форми при ініціалізації, зробив таке:

m_pOrdersView = (QOrdersView*)ui->m_pTableOrders;

все, тепер я можу звертатись до віджета на формі як до свого. Думаю це те що вам потрібно

дякую)
детальніше знайшов тут http://stackoverflow.com/questions/1280 … is-widgets