Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Ced от Апрель 27, 2017, 22:32



Название: Использование слотов и наследование
Отправлено: Ced от Апрель 27, 2017, 22:32
Хотелось так:

class A : QObject
{
Q_OBJECT
.....
public slots:
    void slotA();
}

class B : A
{
Q_OBJECT
.....
public slots:
    void slotB();
}

Похоже так нельзя. Что посоветуете? Есть похожая допустимая схема?


Название: Re: Использование слотов и наследование
Отправлено: Alex Custov от Апрель 27, 2017, 23:28
Классное описание :) Почему так нельзя? Можно.


Название: Re: Использование слотов и наследование
Отправлено: Old от Апрель 28, 2017, 06:25
Я так понял, что ТС хочет приватно наследоваться от QObject.


Название: Re: Использование слотов и наследование
Отправлено: Ced от Апрель 28, 2017, 06:41
Описание действительно не точное.

class A : public QObject
{
Q_OBJECT
.....
public slots:
    void slotA();
}

class B : A
{
Q_OBJECT
...
QPushButton x
.....
void progB(...)

public slots:
    void slotB();
}

void B:progB(...)
{

....
connect(x, SIGNAL(clicked()), this, SLOT(slotB()));
}

Сообщение компилятора "Класс А не содержит slotB"

То бишь слот класса наследника воспринимается компилятором, как слот родителя. В этом проблема.

А если еще точнее, так происходит, если в классе B Q_OBJECT отсутствует. А если его включить, компилятор сообщает о неоднозначном определении.


Название: Re: Использование слотов и наследование
Отправлено: kuzulis от Апрель 28, 2017, 09:08
Ах, так нужно наследоваться публично...

не:
Код:
class B : A

а:
Код:
class B : public A

PS: Как Old уже заметил..


Название: Re: Использование слотов и наследование
Отправлено: Ced от Апрель 28, 2017, 12:07
Ах, так нужно наследоваться публично...

не:
Код:
class B : A

а:
Код:
class B : public A

PS: Как Old уже заметил..


Согласен. Но в реальном коде этой ошибки нет.
Источник проблемы в другом. В классе-наследнике нельзя определить Q_OBJECT. Он уже определен в родителе. Компилятор второй Q_OBJECT не признает. А если его не определять, все слоты наследника воспринимаются компилятором, как слоты предка. Компилятор законно сообщает, что в предке таких слотов нет. Если в указателе this при выполнении connect написать (B *)this, компилятор понимает, где искать слоты. Но присоединить их к сигналам не может, так как в потомке Q_OBJECT объявить невозможно.


Название: Re: Использование слотов и наследование
Отправлено: Ced от Апрель 28, 2017, 12:22
Вот решил привести кусок реального кода.

class MyClient : public QWidget, public SystemMember
{
Q_OBJECT
.....
public:
    MyClient(const QString& strHost, int nPort, SystemMember *member,
             Message *message, QWidget *pwgt=0);

private slots:
    void slotReadyRead ();
    void slotError     (QAbstractSocket::SocketError);
    void slotConnected ();
    void slotDestroyed ();

signals:
    void time_periods();
    void time_periods_given();
    void parametrs_List();
};

MyClient::MyClient(const QString& strHost, int nPort, SystemMember *member,
                   Message *message, QWidget *pwgt) :
           QWidget(pwgt, Qt::SplashScreen), SystemMember(member), m_nNextBlockSize(0)
{
    lastMessage = message;
    m_pTcpSocket = new QTcpSocket(this);
    m_pTcpSocket->connectToHost(strHost, nPort);

    connect(m_pTcpSocket, SIGNAL(connected()), SLOT(slotConnected()));
    connect(m_pTcpSocket, SIGNAL(readyRead()), SLOT(slotReadyRead()));
    connect(m_pTcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
            this,         SLOT  (slotError(QAbstractSocket::SocketError)));

    m_ptxtInfo  = new QTextEdit;
    m_ptxtInfo->setReadOnly(true);
}


class InputFileSelect : public MyClient
{

private:
..........

public:
    InputFileSelect(const QStringList arguments,
                    const QStringList extentions);

public slots:
    void slotStationMenuChois(QAction *chois);
    void slotDurationMin(const QDateTime &datetime);
    void slotGPAMenuChois(QAction *chois);
    void slotGTUMenuChois(QAction *chois);

    void slotDataSelected();
    void slotCancelSelection();
    void slotParamSelected();
    void slotParamSelectionCnacel();
};

InputFileSelect::InputFileSelect(const QStringList arguments,
                                 const QStringList extentions) :
                                 MyClient("localhost", 2323, this, NULL)
{
    ConverterArg.append(arguments);
    FileExtentions.append(extentions);

.....

    connect(stationSelect, SIGNAL(clicked()), this, SLOT(slotParamSelected()));
.......
}

Как написано, компилятор считает, что slotParamSelected() должен находиться в MyClient. Его там понятно нет.

Если написать
    connect(stationSelect, SIGNAL(clicked()), (InputFileSelect *)this, SLOT(slotParamSelected()));

Слот находит, но не соединяет его с сигналом.

Если написать

class InputFileSelect : public MyClient
{
Q_OBJECT
.....

ругается на неоднозначное определение.

Вот теперь все вроде точно.


Название: Re: Использование слотов и наследование
Отправлено: Пантер от Апрель 28, 2017, 12:29
>ругается на неоднозначное определение
Полный текст ошибки приведи.


Название: Re: Использование слотов и наследование
Отправлено: sergek от Апрель 28, 2017, 12:30
Описание действительно не точное.

....
connect(x, SIGNAL(clicked()), this, SLOT(slotB()));
}
Соединять надо указатель:
connect(&x, SIGNAL(clicked()), this, SLOT(slotB()));


Название: Re: Использование слотов и наследование
Отправлено: Old от Апрель 28, 2017, 12:31
Источник проблемы в другом. В классе-наследнике нельзя определить Q_OBJECT. Он уже определен в родителе. Компилятор второй Q_OBJECT не признает.
Не может такого быть. Посмотрите на дерево классов Qt, там в каждом классе определен Q_OBJECT.


Название: Re: Использование слотов и наследование
Отправлено: deMax от Апрель 28, 2017, 13:59
Не может такого быть. Посмотрите на дерево классов Qt, там в каждом классе определен Q_OBJECT.
Подтверждаю(все компилируется):

some.h
    class A: public QObject { Q_OBJECT };
    class B: A { Q_OBJECT };

enywhere.cpp/h
    A ca;
    B cb;

А вот если класс в cpp определить то нужно moc инклудить, иначе "undefined reference to vtable...". Но так лучше не делать, тем более новичкам.


Название: Re: Использование слотов и наследование
Отправлено: Ced от Апрель 28, 2017, 20:20
Спасибо всем, кто откликнулся. К сожалению прогу уже переделал по другому. Но схему обязательно проверю. Если она раочая, то мне представляется удобной.