Russian Qt Forum

Qt => Вопросы новичков => Тема начата: alexxx_1992 от Апрель 05, 2011, 20:54



Название: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: alexxx_1992 от Апрель 05, 2011, 20:54
Проблема состоит в следующем: при попытке использования в качестве аргумента сигнала свой класс (унаследованный от QObject), компиллятор выдает следующую ошибку
   error C2248: 'QObject::operator =' : cannot access private member declared in class 'QObject'
      see declaration of 'QObject::operator ='
      see declaration of 'QObject'
компиллятор отправляет на строку: Q_DISABLE_COPY(QObject)
пробовал использовать qRegisterMetaType - не помогло. Компиллятор тот что с VisualStudio 2008.
Помогите пожалуйста.


Название: Re: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: kibsoft от Апрель 05, 2011, 22:31
Передавай указатель..


Название: Re: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: alexxx_1992 от Апрель 05, 2011, 22:52
Спасибо за ответ, но Не помогает  :(


Название: Re: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: serg_hd от Апрель 05, 2011, 22:58
То же самое, но с gcc сделать пробовал? Если да, то неплохо бы было выложить тут компиляберный пример, т.к. суть проблемы до конца не ясна. Может быть поэтому и ответов по сабжу мало.


Название: Re: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: alexxx_1992 от Апрель 05, 2011, 23:10
Этот класс передается в качестве параметра сигнала:
Код
C++ (Qt)
#ifndef CARD_H
#define CARD_H
 
#include <QtGui/QtGui>
 
class Card: public QObject
{
Q_OBJECT
 
enum Suit
{
Crosses, Spades, Hearts, Diamonds
} m_suit;
 
enum Value
{
Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace
} m_value;
 
QPixmap m_face;
public:
Card (Suit _suit, Value _value, QObject *_parent = NULL);
/*Card (const Card &_card);
Card ();*/

};
 
#endif // CARD_H
 
cpp:
Код
C++ (Qt)
#include "card.h"
 
Card::Card (Suit _suit, Value _value, QObject *_parent)
: QObject (_parent)
{
m_suit = _suit;
m_value = _value;
 
 
в этом классе слот, соединенный со злополучным сигналом:
Код
C++ (Qt)
#ifndef ABSTRACTPOKERPLAYER_H
#define ABSTRACTPOKERPLAYER_H
 
#include "card.h"
#include "abstractplayer.h"
 
class AbstractPokerPlayer: public AbstractPlayer
{
Q_OBJECT
QVector<Card> m_cards;
 
public:
AbstractPokerPlayer (const QString& _name, double _balance = 10000.0, QObject *_parent = NULL);
 
public slots:
void slotAddCard (const Card &_card);
virtual void slotDoStep (QString& _playerName, const QVector<AbstractStep> &_steps);
};
 
#endif // ABSTRACTPOKERPLAYER_H
 
cpp:
Код
C++ (Qt)
#include "abstractpokerplayer.h"
 
AbstractPokerPlayer::AbstractPokerPlayer (const QString &_name, double _balance, QObject *_parent)
: AbstractPlayer(_name, _balance, _parent)
{
m_cards.resize (2);
}
 
void AbstractPokerPlayer::slotAddCard (const Card &_card)
{
if (m_cards.size () <= 2)
m_cards.push_back (_card);
}
 
Компиллятор:
Цитировать
c:\users\александр\documents\visual studio 2008\projects\casino\casino\card.h(25) : error C2248: 'QObject::QObject' : cannot access private member declared in class 'QObject'
1>        c:\qt\4.7.2\include\qtcore\../../src/corelib/kernel/qobject.h(309) : see declaration of 'QObject::QObject'
1>        c:\qt\4.7.2\include\qtcore\../../src/corelib/kernel/qobject.h(122) : see declaration of 'QObject'
1>        This diagnostic occurred in the compiler generated function 'Card::Card(const Card &)'
1>c:\users\александр\documents\visual studio 2008\projects\casino\casino\card.h(25) : error C2248: 'QObject::operator =' : cannot access private member declared in class 'QObject'
1>        c:\qt\4.7.2\include\qtcore\../../src/corelib/kernel/qobject.h(309) : see declaration of 'QObject::operator ='
1>        c:\qt\4.7.2\include\qtcore\../../src/corelib/kernel/qobject.h(122) : see declaration of 'QObject'
1>        This diagnostic occurred in the compiler generated function 'Card &Card::operator =(const Card &)'
на gcc не пробовал.


Название: Re: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: serg_hd от Апрель 06, 2011, 00:37
то есть и соединяешь примерно так?:
Код
C++ (Qt)
MyClass* obj = new MyClass;
AbstractPokerPlayer* obj2 = new AbstractPokerPlayer;
QObject::connect(obj, SIGNAL(mySignal(const Card&)), obj2, SLOT(slotAddCard(const Card&)));
 


Название: Re: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: kibsoft от Апрель 06, 2011, 00:42
Проблема в slotAddCard (const Card &_card).

У QObject отключен оператор =, так же как и конструктор копирования, т.е. QObject не относится к assignable data type. Соответственно, либо добавляешь оператор = в Card, либо передаешь как указатель (в слоте принимаешь соответственно тоже указатель).


Название: Re: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: alexxx_1992 от Апрель 06, 2011, 09:11
Соединяю именно так. Переопределил оператор =, исчезла только ошибка про оператор =, а 'QObject::QObject' : cannot access private member declared in class 'QObject' - осталась. Сейчас буду пробовать с указателем. Спасибо за быстрые ответы!


Название: Re: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: alexxx_1992 от Апрель 06, 2011, 09:21
Изменил на указатели
Код:
#ifndef ABSTRACTPOKERPLAYER_H
#define ABSTRACTPOKERPLAYER_H

#include "card.h"
#include "abstractplayer.h"

class AbstractPokerPlayer: public AbstractPlayer
{
Q_OBJECT
QVector<Card> m_cards;

public:
AbstractPokerPlayer (const QString& _name, double _balance = 10000.0, QObject *_parent = NULL);

public slots:
void slotAddCard (Card *_card);
virtual void slotDoStep (QString& _playerName, QVector<AbstractStep> *_steps);
};

#endif // ABSTRACTPOKERPLAYER_H
cpp:
Код:
#include "abstractpokerplayer.h"

AbstractPokerPlayer::AbstractPokerPlayer (const QString &_name, double _balance, QObject *_parent)
: AbstractPlayer(_name, _balance, _parent)
{
m_cards.resize (2);
}

void AbstractPokerPlayer::slotAddCard (Card *_card)
{
if (m_cards.size () <= 2)
m_cards.push_back (*_card);
}
Те же ошибки:
Цитировать
c:\users\александр\documents\visual studio 2008\projects\casino\casino\card.h(25) : error C2248: 'QObject::QObject' : cannot access private member declared in class 'QObject'
1>        c:\qt\4.7.2\include\qtcore\../../src/corelib/kernel/qobject.h(309) : see declaration of 'QObject::QObject'
1>        c:\qt\4.7.2\include\qtcore\../../src/corelib/kernel/qobject.h(122) : see declaration of 'QObject'
1>        This diagnostic occurred in the compiler generated function 'Card::Card(const Card &)'
1>c:\users\александр\documents\visual studio 2008\projects\casino\casino\card.h(25) : error C2248: 'QObject::operator =' : cannot access private member declared in class 'QObject'
1>        c:\qt\4.7.2\include\qtcore\../../src/corelib/kernel/qobject.h(309) : see declaration of 'QObject::operator ='
1>        c:\qt\4.7.2\include\qtcore\../../src/corelib/kernel/qobject.h(122) : see declaration of 'QObject'
1>        This diagnostic occurred in the compiler generated function 'Card &Card::operator =(const Card &)'


Название: Re: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: alexxx_1992 от Апрель 06, 2011, 09:25
Я также пытался на другом простом примере переопределить оператор = и конструктор по умолчанию и вызвать qRegisterMetaType, все ошибки исчезли, но сигнал не заработал вообще.


Название: Re: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: twp от Апрель 06, 2011, 11:46
вот тут срабатывает кострустор копии который в привате
Код:
m_cards.push_back (*_card);
стало быть нужно хранить указатели: QVector<Card *> m_cards;

Кроме того, мне непонятно зачем Card наследуется от QObject если не используется ни слоты не сигналы ни другие фичи QObject


Название: Re: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: alexxx_1992 от Апрель 06, 2011, 12:02
Спасибо большое! Дело именно в шаблоне вектора! Card наследуется от QObject, потому что изначально я не очень задумывался что в нем будет))) ну и кончено чтобы деструктор не писать, если динамически что-то буду выделять)


Название: Re: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: twp от Апрель 06, 2011, 12:06
ну и кончено чтобы деструктор не писать, если динамически что-то буду выделять)
одно из другого не вытекает, можно тут по-подробнее?


Название: Re: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: Пантер от Апрель 06, 2011, 12:08
twp, он скорее всего имеет ввиду то, что родитель сам убивает своих детей.
alexxx_1992, если я прав, то твое решение неверное.


Название: Re: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: alexxx_1992 от Апрель 06, 2011, 12:18
я имел в виду, что если я еще где-нибудь, в другом классе сделаю поле Card, не буду его совать) в вектор или еще куда-нибудь, то деструктор мне писать не придется. Но это все лирика, я наверное как тут и писали не буду наследовать QObject.


Название: Re: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: twp от Апрель 06, 2011, 12:35
наверно под деструктором имеется в виду оператор delete? Тогда да, как написал выше Пантер родитель берет на себя обязанности по удалению чайлдов.


Название: Re: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: kibsoft от Апрель 06, 2011, 16:34
twp прав:
Цитировать
стало быть нужно хранить указатели: QVector<Card *> m_cards;

Читайте доку! Там же все написано  ???
Цитировать
If you attempt to instantiate a QList<QWidget>, the compiler will complain that QWidget's copy constructor and assignment operators are disabled. If you want to store these kinds of objects in a container, store them as pointers, for example as QList<QWidget *>.

Раздел Container classes в данном случае.

P.S. Если не хочешь использовать указатели, добавь operator= и конструктор копирования (оба public) в твой класс.


Название: Re: Как использовать в качестве аргумента сигнала/слота свой класс?
Отправлено: alexxx_1992 от Апрель 06, 2011, 22:54
Проблема решена, всем БОЛЬШОЕ СПАСИБО!)