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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: [Решено] Множественное наследование и слоты  (Прочитано 11460 раз)
surendil
Гость
« : Июнь 21, 2011, 18:19 »

Я попробовал написать так:
Код
C++ (Qt)
class PPIDisplay : public QObject
{
 Q_OBJECT
public slots:
 virtual void createTarget(int id, int type, qreal x, qreal y) = 0;
 virtual void destroyTarget(int id) = 0;
 virtual void moveTarget(int id, qreal x, qreal y) = 0;
 virtual void moveRay(qreal delta) = 0;
};

и...
Код
C++ (Qt)
class SceneView : public PPIDisplay, public QGraphicsView
{
 Q_OBJECT
public:
 explicit SceneView(QWidget *parent = 0);
};

В итоге я получил:
Код:
Warning: Class SceneView inherits from two QObject subclasses PPIDisplay and QGraphicsView. This is not supported!

Что мне делать? Плачущий
« Последнее редактирование: Июнь 23, 2011, 22:12 от surendil » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Июнь 21, 2011, 18:33 »

Простой ответ "так нельзя" - как и написал Вам компилятор. Но интересно проверить так:
Код
C++ (Qt)
class PPIDisplay : public virtual QObject
 
Записан
surendil
Гость
« Ответ #2 : Июнь 21, 2011, 18:56 »

Простой ответ "так нельзя" - как и написал Вам компилятор. Но интересно проверить так:
Код
C++ (Qt)
class PPIDisplay : public virtual QObject
 

Я попробовал, так тоже не работает Улыбающийся
В Википедии написано, что проблема решается так:
Код
C++ (Qt)
class Animal {
public:
 virtual void eat();
};
 
class Mammal : public virtual Animal {
public:
 virtual Color getHairColor();
};
 
class WingedAnimal : public virtual Animal {
public:
 virtual void flap();
};
 
class Bat : public Mammal, public WingedAnimal {};

Но ведь мне неподвластно "подправить" QGraphicsView?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #3 : Июнь 21, 2011, 19:11 »

Простой ответ "так нельзя" - как и написал Вам компилятор. Но интересно проверить так:
Код
C++ (Qt)
class PPIDisplay : public virtual QObject
 
В самой ОО модели Qt запрещено множественное наследование от QObject.
Записан

Qt 5.11/4.8.7 (X11/Win)
surendil
Гость
« Ответ #4 : Июнь 21, 2011, 19:38 »

Прошу прощения, я очень сильно ошибся: мне нужно наследовать не от QGraphicsView, а от QGraphicsScene.

QGaphicsScene унаследован от QObject, но следующее -- если не работает, то по крайней мере компилируется. Не должно ведь, правда? Улыбающийся
Код
C++ (Qt)
class PPIDisplay
 : public QObject
{
 Q_OBJECT
public slots:
 virtual void createTarget(int id, int type, qreal x, qreal y) = 0;
 virtual void destroyTarget(int id) = 0;
 virtual void moveTarget(int id, qreal x, qreal y) = 0;
 virtual void moveRay(qreal delta) = 0;
};

Код
C++ (Qt)
class SceneDisplay
 : public QGraphicsScene, public PPIDisplay
{
public:
 SceneDisplay();
public slots:
 void createTarget(int id, int type, qreal x, qreal y) {}
 void destroyTarget(int id) {}
 void moveTarget(int id, qreal x, qreal y) {}
 void moveRay(qreal delta) {}
};
 
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Июнь 21, 2011, 20:21 »

QGaphicsScene унаследован от QObject, но следующее -- если не работает, то по крайней мере компилируется. Не должно ведь, правда? Улыбающийся
Не должно. Абстрактный класс PPIDisplay имеет неабстрактные члены унаследованные от QObject, значит результатом должно быть  множественное наследование от QObject которое (как нас уверяют) невозможно
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #6 : Июнь 21, 2011, 21:12 »

QGaphicsScene унаследован от QObject, но следующее -- если не работает, то по крайней мере компилируется. Не должно ведь, правда? Улыбающийся
Не должно. Абстрактный класс PPIDisplay имеет неабстрактные члены унаследованные от QObject, значит результатом должно быть  множественное наследование от QObject которое (как нас уверяют) невозможно
Невозможно не сточки зрения С++, а иерархической модели Qt.
Записан

Qt 5.11/4.8.7 (X11/Win)
surendil
Гость
« Ответ #7 : Июнь 21, 2011, 21:30 »

Невозможно не сточки зрения С++, а иерархической модели Qt.

Я правильно вас понимаю, что у меня сама идея изначально неправильная и отсюда косяки?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #8 : Июнь 21, 2011, 21:40 »

Типа того.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
surendil
Гость
« Ответ #9 : Июнь 21, 2011, 21:47 »

Типа того.

Как быть? Я хотел сделать абстрактный класс, чтобы обязать его наследников реализовать необходимые слоты... а слоты, насколько мне известно, можно делать только в наследниках QObject (и с макросом Q_OBJECT).
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Июнь 21, 2011, 21:48 »

Невозможно не сточки зрения С++, а иерархической модели Qt.
Ну наверное MOC-компилятору будет затруднительно собрать воедино слоты/сигналы из разных базовых классов - отсюда и "иерархическая модель" и все такое  Улыбающийся

Я правильно вас понимаю, что у меня сама идея изначально неправильная и отсюда косяки?
Я бы так себя не ругал но цель лучше поменять. Допустим это было бы возможно - и что? Имели бы только массу (ненужных) забот - поди разберись который из базовых классов должен получать сигнал. Проще по-народному сделать указатель на PPIDisplay членом класса SceneDisplay и пусть SceneDisplay получает сигналы и отдает их на обработку PPIDisplay (членство вместо наследования). "Отношения" между этими 2-мя классами можно оформить в виде интерфейсов которые включить уже множественным наследованием.
Записан
surendil
Гость
« Ответ #11 : Июнь 21, 2011, 21:57 »

Я бы так себя не ругал но цель лучше поменять. Допустим это было бы возможно - и что? Имели бы только массу (ненужных) забот - поди разберись который из базовых классов должен получать сигнал. Проще по-народному сделать указатель на PPIDisplay членом класса SceneDisplay и пусть SceneDisplay получает сигналы и отдает их на обработку PPIDisplay (членство вместо наследования). "Отношения" между этими 2-мя классами можно оформить в виде интерфейсов которые включить уже множественным наследованием.

Проблема определения получателя сигнала встаёт ведь когда есть одинаковые слоты, правильно? У меня они вряд ли будут повторяться: то, что находится в PPIDisplay, фактически, являются командами "нарисуй это здесь", а SceneDisplay должен реализовать эти отрисовки на сцене. Какой-нибудь PainterDisplay -- с помощью QPainter (в этом, собственно, и весь смысл поставленной мне задачи).

Про ваше предложение не понял, разжуйте пожалуйста.. Обеспокоенный
« Последнее редактирование: Июнь 21, 2011, 22:05 от surendil » Записан
surendil
Гость
« Ответ #12 : Июнь 21, 2011, 23:32 »

Проблема решена. SceneDisplay стал наследником PPIDisplay и получил возможность участвовать в обмене сигналами, кроме того в него попали и виртуальные слоты, как мне и хотелось. QGraphicsScene я сделал атрибутом класса SceneDisplay, думаю, это нормально (по сравнению со множественным наследованием).

Код
C++ (Qt)
class PPIDisplay : public QObject
{
 Q_OBJECT
 
public:
 PPIDisplay(QObject *parent = 0) : QObject(parent) {}
 
public slots:
 virtual void createTarget(int id, int type, qreal x, qreal y) = 0;
 virtual void destroyTarget(int id) = 0;
 virtual void moveTarget(int id, qreal x, qreal y) = 0;
 virtual void moveRay(qreal delta) = 0;
};

Код
C++ (Qt)
class SceneDisplay : public PPIDisplay
{
 Q_OBJECT
 
public:
 SceneDisplay(QObject *parent = 0) : PPIDisplay(parent) {}
 
public slots:
 void createTarget(int id, int type, qreal x, qreal y);
 void destroyTarget(int id);
 void moveTarget(int id, qreal x, qreal y);
 void moveRay(qreal delta);
 
private:
 QGraphicsScene *m_scene;
};
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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