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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Использование слотов и наследование  (Прочитано 5649 раз)
Ced
Гость
« : Апрель 27, 2017, 22:32 »

Хотелось так:

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

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

Похоже так нельзя. Что посоветуете? Есть похожая допустимая схема?
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #1 : Апрель 27, 2017, 23:28 »

Классное описание Улыбающийся Почему так нельзя? Можно.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #2 : Апрель 28, 2017, 06:25 »

Я так понял, что ТС хочет приватно наследоваться от QObject.
Записан
Ced
Гость
« Ответ #3 : Апрель 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 отсутствует. А если его включить, компилятор сообщает о неоднозначном определении.
« Последнее редактирование: Апрель 28, 2017, 06:44 от Ced » Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #4 : Апрель 28, 2017, 09:08 »

Ах, так нужно наследоваться публично...

не:
Код:
class B : A

а:
Код:
class B : public A

PS: Как Old уже заметил..
« Последнее редактирование: Апрель 28, 2017, 09:14 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
Ced
Гость
« Ответ #5 : Апрель 28, 2017, 12:07 »

Ах, так нужно наследоваться публично...

не:
Код:
class B : A

а:
Код:
class B : public A

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


Согласен. Но в реальном коде этой ошибки нет.
Источник проблемы в другом. В классе-наследнике нельзя определить Q_OBJECT. Он уже определен в родителе. Компилятор второй Q_OBJECT не признает. А если его не определять, все слоты наследника воспринимаются компилятором, как слоты предка. Компилятор законно сообщает, что в предке таких слотов нет. Если в указателе this при выполнении connect написать (B *)this, компилятор понимает, где искать слоты. Но присоединить их к сигналам не может, так как в потомке Q_OBJECT объявить невозможно.
Записан
Ced
Гость
« Ответ #6 : Апрель 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
.....

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

Вот теперь все вроде точно.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


Просмотр профиля WWW
« Ответ #7 : Апрель 28, 2017, 12:29 »

>ругается на неоднозначное определение
Полный текст ошибки приведи.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 861


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #8 : Апрель 28, 2017, 12:30 »

Описание действительно не точное.

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

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #9 : Апрель 28, 2017, 12:31 »

Источник проблемы в другом. В классе-наследнике нельзя определить Q_OBJECT. Он уже определен в родителе. Компилятор второй Q_OBJECT не признает.
Не может такого быть. Посмотрите на дерево классов Qt, там в каждом классе определен Q_OBJECT.
Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #10 : Апрель 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...". Но так лучше не делать, тем более новичкам.
Записан
Ced
Гость
« Ответ #11 : Апрель 28, 2017, 20:20 »

Спасибо всем, кто откликнулся. К сожалению прогу уже переделал по другому. Но схему обязательно проверю. Если она раочая, то мне представляется удобной.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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