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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Взаимное управление объектами равноправных классов.  (Прочитано 8504 раз)
Pupil
Гость
« : Август 26, 2010, 09:39 »

Доброе утро!

В примере два равноправных виджета (без наследования).
При обращении из первого класса к объекту второго класса c целью закрытия второго окна, при вызове слота Пример выдаёт ошибку:

"mywidget.cpp:29: error: cannot call member function `bool QWidget::close()' without object"
При этом вложенные методы и свойства объекта в редакторе Qt Creator доступны для выбора. (Библиотека Qt 4.5.3.)

Вопросы о "наследовании" классов и создании общего "дойного" класса прошу в данной теме не рассматривать.

Исходный код: 
MyWidget.cpp
Код:
#include "mywidget.h"
#include "ui_mywidget.h"
#include "form2.h"
#include "ui_form2.h"


MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent), ui(new Ui::MyWidget)
 {
 ui->setupUi(this);
 QObject::connect(ui->button, SIGNAL(clicked()), this, SLOT(Tst2()));
 }

MyWidget::~MyWidget()
{
delete ui;
}
void MyWidget::Tst()
{
    Form2 *w2 = new Form2();
    w2->setAttribute(Qt::WA_DeleteOnClose);
    w2->show();
}
void MyWidget::Tst2()
{
  Form2::close(); 
  MyWidget::close();
}
MyWidget.h
Код:
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QtGui/QWidget>
#include "form2.h"
#include "ui_form2.h"

namespace Ui
{
    class MyWidget;
}

class MyWidget : public QWidget
{
    Q_OBJECT

public:
    MyWidget(QWidget *parent = 0);
    ~MyWidget();
    Ui::MyWidget *ui;
   
public slots:
    void Tst();
    void Tst2();
};
#endif // MYWIDGET_H

Form2.h
Код:
#ifndef FORM2_H
#define FORM2_H
#include <QtGui/QWidget>

namespace Ui {
    class Form2;
}
class Form2 : public QWidget {
    Q_OBJECT
public:
    Form2(QWidget *parent = 0);
    ~Form2();
    Ui::Form2 *m_ui;
    void changeEvent(QEvent *e);

protected:

private:
 };
#endif // FORM2_H

Form2.cpp
Код:
#include "form2.h"
#include "ui_form2.h"
#include "mywidget.h"
#include "ui_mywidget.h"


Form2::Form2(QWidget *parent) :
    QWidget(parent),
    m_ui(new Ui::Form2)
{
    this->setWindowFlags(Qt::Window);
    m_ui->setupUi(this);

}

Form2::~Form2()
{
    delete m_ui;
}

void Form2::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;

    }
}
Записан
crossly
Гость
« Ответ #1 : Август 26, 2010, 09:45 »

а что
Цитировать
mywidget.cpp:29: error: cannot call member function `bool QWidget::close()' without object
вам не о чем не говорит... может стоит книжку по с++ почитать ??
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #2 : Август 26, 2010, 09:55 »

  Form2::close(); 
  MyWidget::close();
таким образом можно вызывать либо статические функции класса, либо методы базового класса.
П.С.
Надо подтягивать Си++
Записан

Юра.
Pupil
Гость
« Ответ #3 : Август 26, 2010, 10:34 »

В CBuilder такие решения без вопросов работают.  По данной же теме: при попытке изменения текста в QLabel из класса 2  приложение компилируется, но выдаёт ошибку: Инструкция по адресу "0x004038c6" обратилась к памяти по адресу "0xaa55aa71". Память не может быть "read".

form2.h
Код:
#ifndef FORM2_H
#define FORM2_H

#include <QtGui/QWidget>
#include "mywidget.h"
#include "ui_mywidget.h"

class MyWidget; // Класс 1

namespace Ui {
    class Form2;
    class MyWidget;
}


class Form2 :  public QWidget {
    Q_OBJECT
public:
    Form2(QWidget *parent = 0);
    ~Form2();
    Ui::MyWidget *uiX; // Указатель на Ui класса 1

protected:
    void changeEvent(QEvent *e);

private:
    Ui::Form2 *m_ui;


public slots:
    void slot1();
};


#endif // FORM2_H

form2.cpp
Код:
#include "form2.h"
#include "ui_form2.h"
#include "mywidget.h"
#include "ui_mywidget.h"


Form2::Form2(QWidget *parent) :
    QWidget(parent),
    m_ui(new Ui::Form2)
{
    this->setWindowFlags(Qt::Window);
    m_ui->setupUi(this);
    connect(m_ui->pushButton, SIGNAL(clicked()), this, SLOT(slot1()));
}

Form2::~Form2()
{
    delete m_ui;
}

void Form2::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}
void Form2::slot1()
{
    uiX->label->setText("12345");
}
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #4 : Август 26, 2010, 21:03 »

>>При обращении из первого класса к объекту второго класса c целью закрытия второго окна
выделенное и является сутью. Ты не обращаешься к объекту и компилятор тебе об этом явно говорит
« Последнее редактирование: Август 26, 2010, 21:08 от lit-uriy » Записан

Юра.
Pupil
Гость
« Ответ #5 : Август 30, 2010, 08:18 »

lit-uriy, это да. А как обратиться? Студент  Непонимающий.
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #6 : Август 30, 2010, 08:42 »

>>А как обратиться?
да также как и в CBuilder, всё одно Си++

имя_объекта.имя_поля
или
имя_указателя_на_объект->имя_поля
Записан

Юра.
Pupil
Гость
« Ответ #7 : Август 30, 2010, 13:24 »

Согласен, так вопрос в не том:
Есть компонент QLabel. Принадлежность: Класс 1. Имя: label.
Во втором классе, пытаясь изменить свойство text компонента QLabel,
пишу: ui->label->setText("12345"); Так как ui -это указатель доступа 1-го класса, то система логично выдаёт:

'ui'  undeclared

Если написать: label->setText("12345"); - система выдаёт:

'label'  undeclared. Логично: компонент приналежит классу 1, а класс 2-а, из которого вызывается компонент этого компонента не знает.

Делаю так:
Код:
class2.h

class MyWidget; // Класс 1

namespace Ui {
    class Form2;
    class MyWidget; // Класс 1
}


class Form2 :  public QWidget {
    Q_OBJECT
public:
    Form2(QWidget *parent = 0);
    ~Form2();
    Ui::MyWidget *uiX; // Указатель на класс 1, для видимости из класса 2.


Пишу так
 uiX->label->setText("12345");  -в данном случае от uiX->идёт подсказка автовыбора компонентов - т.е. label класса 1 - доступен для выбора, а
для label соответственно доступен метод setText(...). При этом пример компилируется, но при выполнении пример выдаёт ошибку с длинным номером и закрывается.
Если обеспечивается видимость в редакторе, что тогда неверно? Почему пример выдаёт ошибку?  Непонимающий
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #8 : Август 30, 2010, 16:58 »

Pupil, ключевая фраза - "как обращаться из одной формы к другой?"
это очень популярный вопрос на этом форуме, для тех, кто плохо знает Си++ и пробовал программировать в стиле Дельфи.

Поищи. Люди устали отвечать на один и тот же вопрос
Записан

Юра.
Pupil
Гость
« Ответ #9 : Август 30, 2010, 20:38 »

Приношу извинения за неинтересный вопрос. Вам труднобыло написать 2-а способа -одной строчкой или функцией - Ваше право. В любом случае всем искренне спасибо. Задачу, Слава Всевышнему, решил.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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