Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Реюз интерфейса...
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Общие вопросы
LE0N
Имеется форма, в которой разный функционал, но одинаковый интерфейс(GUI).
Хотелось бы эту форму использывать в двух разных классах отнаследованных от QDialog....
Прикрутил ui_form.h к хиадеру с новым ребёнком QDalog, форма всё нормально отображается. Но вот слоты, почему то, не работают.(Они подключаются в ui_form.h ) Ругается примерно так:
Цитата
Object::connect: No such slot QDialog::select_product_type(int) in ui_shipmentform.h:77
Object::connect: (sender name: 'comboBox')
Object::connect: (receiver name: 'ShipmentFormClass')

Хотя слот объявлен....
Во второй форме, где тоже объявлен этот слот, всё работает на 5+.
В чём проблема?
Litkevich Yuriy
Цитата(LE0N @ 27.3.2009, 15:40) *
QDialog::select_product_type(int)
в этом и проблема, у QDialog нет такого слота.
LE0N
Так я наследника QDialog передаю...
class shipment_operation : public QDialog {
public:
    shipment_operation(const QString &,QWidget *);
    ~shipment_operation();
public slots:
void select_product_type(int);
private:
    Ui::ShipmentFormClass ui;
    QString id_store;
    QSqlQueryModel *model;
    QSqlQueryModel *products_model;

};

shipment_operation::shipment_operation(const QString &id_store,QWidget *parent):QDialog(parent)
{
    ui.setupUi(this);
    #...
}
Litkevich Yuriy
Цитата(LE0N @ 27.3.2009, 16:31) *
Так я наследника QDialog передаю...
ошибка, которую сообщает Qt, говорит о том, что в соединении учавствует слот, которого нет. наследник тут непричем, смотри как соединение происходит.
LE0N
QT_BEGIN_NAMESPACE

class Ui_ShipmentFormClass
{
public:
    QGroupBox *groupBox;
    QComboBox *comboBox;
    QPushButton *pushButton_3;
    QTableView *listView;

    void setupUi(QDialog *ShipmentFormClass)
    {
        if (ShipmentFormClass->objectName().isEmpty())
            ShipmentFormClass->setObjectName(QString::fromUtf8("ShipmentFormClass"));
        ShipmentFormClass->setWindowModality(Qt::WindowModal);
        ShipmentFormClass->resize(870, 390);
        ShipmentFormClass->setModal(true);
        #Далее создаются элементы ГУИ я их удалил, что бы кода меньше было...
        #А здесь коннектятся слоты...
        QObject::connect(comboBox, SIGNAL(currentIndexChanged(int)), ShipmentFormClass, SLOT(select_product_type(int)));
        QObject::connect(pushButton, SIGNAL(clicked()), ShipmentFormClass, SLOT(accept()));
        QObject::connect(pushButton_2, SIGNAL(clicked()), ShipmentFormClass, SLOT(reject()));
        QObject::connect(pushButton_3, SIGNAL(clicked()), ShipmentFormClass, SLOT(load_to_store()));

        QMetaObject::connectSlotsByName(ShipmentFormClass);
    } // setupUi
};

namespace Ui {
    class ShipmentFormClass: public Ui_ShipmentFormClass {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_SHIPMENTFORM_H

Ну и, собственно, ui.setupUi(QDialog*) коннектит сигналы к слотам наследника.
Я так понимаю, что QT ругается на QDialog потому что в setupUi передаётся указатель на QDialog типа...
НО! Тоже самое делается во второй форме. И там всё работает....
igor_bogomolov
Цитата(LE0N @ 27.3.2009, 12:40) *
Цитата
Object::connect: No such slot QDialog::select_product_type(int) in ui_shipmentform.h:77
Object::connect: (sender name: 'comboBox')
Object::connect: (receiver name: 'ShipmentFormClass')

Всю информацию компилятор вам сообщил, что тут еще непонятного?

Смотрим приведенный код:
Слот select_product_type(int) принадлежит классу shipment_operation.
Коннект делается в классе ShipmentFormClass, следущим образом
Цитата
QObject::connect(comboBox, SIGNAL(currentIndexChanged(int)), ShipmentFormClass, SLOT(select_product_type(int)));

Приемщик сигнала в данном случае ShipmentFormClass.
Есть у него слот select_product_type(int)?
НЕТ.
Об этом компилятор вам подробно и сообщает.
LE0N
Цитата
void setupUi(QDialog *ShipmentFormClass);

ШипментФормКласс в данном случае - указатель на shipment_operation
Это следует из:
Цитата
ui.setupUi(this);

В конструкторе shipment_operation
Или я чего-то не понимаю?
Litkevich Yuriy
Помоему всё дело в этих строчках:
Цитата(LE0N @ 27.3.2009, 16:31) *
class shipment_operation : public QDialog {
public:
а где макрос Q_OBJECT?
igor_bogomolov
Цитата(LE0N @ 27.3.2009, 17:44) *
ШипментФормКласс в данном случае - указатель на shipment_operation
Это следует из:

Да, это я недоглядел, признаю.
Талько тогда исходя из
void setupUi(QDialog *ShipmentFormClass)

Это уже указатель на QDialog, в котором так же нет слота select_product_type(int) :rolleyes:
Litkevich Yuriy
Цитата(igor_bogomolov @ 27.3.2009, 21:27) *
Это уже указатель на QDialog,
указатель показывает на shipment_operation, в котором есть такая функция, но она ещё не слот, т.к. нет макроса Q_OBJECT
igor_bogomolov
Цитата(Litkevich Yuriy @ 27.3.2009, 19:11) *
указатель показывает на shipment_operation, в котором есть такая функция

Извените Юрий, но насколько я понимаю, в данном случае Вы не правы
void setupUi(QDialog *ShipmentFormClass)
ShipmentFormClass указатель именно на QDialog, который ничего не знает о данном слоте.
Сделайте тестовое приложение, проверьте :rolleyes: Хотя из объявления и так все понятно.
LE0N
Добавил Q_OBJECT всё заработало :)))
Не мог предположить даже :)))
igor_bogomolov
???
Цитата(LE0N @ 27.3.2009, 23:11) *
Добавил Q_OBJECT всё заработало ))

Значит я ничего не понимаю в программировании.
Объясните мне где я был не прав?

P.S. Про Q_OBJECT все понятно.
Вот здесь непонятно
void setupUi(QDialog *ShipmentFormClass);

Ну QDialog же это!!!
LE0N
Цитата
Ну QDialog же это!!!

Я тоже задавался этим вопросом ещё до создания топика. Но тот факт, что в другой форме всё работает, отбросил все вопросы на эту тему на задний план...
Скорее всего в макросе Q_OBJECT есть функция, которая возвращает текущее имя объекта. После чего в функции connect идёт автоматический автокаст...Что то такое хитрое, скорее всего...

И ещё один ньюанс - для того, что бы использывать Q_OBJECT нужно запускать qmake который, в свою очередь, создаёт моки...
Там тоже, скорее всего, часть реализации скрыта.
Но вникать в систему, пока нет ни времени не желания...
igor_bogomolov
Можете приложить архивчик с полным текстом своего проекта. Хочу посмотреть полностью что там происходит.
У меня в тестовом проекте ничего подобного не получается.
В принципе не понимаю откуда в ui_***.h, который, по идее, должен генерироваться из ui формы, берется
QObject::connect(comboBox, SIGNAL(currentIndexChanged(int)), ShipmentFormClass, SLOT(select_product_type(int)));
Откуда там вообще конекты?
Вы просто сохранили у себя ui_***.h чтоли, а эти строки добавили сами?
Litkevich Yuriy
Цитата(igor_bogomolov @ 28.3.2009, 2:40) *
Вот здесь непонятно
void setupUi(QDialog *ShipmentFormClass);

Ну QDialog же это!!!
нет! Это в певую очередь указатель! просто он имеет тип QDialog, т.е. может ссылаться на QDialog и его наследников.
А класс shipment_operation как раз и есть наследник QDialog. И в конструкторе этого класса в функцию setupUi передается указатель именно на shipment_operation.

См. пояснение в сообщении №7.

П.С. Я в начале тоже стрмозил, и не посмотрел на объявление иначе б проблема раньше всплыла.

Для справки:
Троли рекомендуют у всех прямых или косвенных наследников QObject в обявлении класса писать макрос Q_OBJECT, даже если не исполуются сигналы и слоты.
igor_bogomolov
Создал у себя тестовый проект.
Добавил после компиляции в ui_**.h коннект
QObject::connect(pushButton, SIGNAL(clicked()), new_testClass, SLOT(myslot()));

На самом деле слот вызывается.

Сделал далее
new_testClass->myslot();
Естественно получил ошибку при компиляции, потому что new_testClass указатель на QDialog, и о myslot() ему ничего неизвестно.

Видимо надо мне книжечки по С++ еще почитать, востановить пробелы в образовании, а то докоца логика мне так и непонятна. :rolleyes:
Litkevich Yuriy
Цитата(igor_bogomolov @ 28.3.2009, 6:04) *
new_testClass->myslot();
Естественно получил ошибку при компиляции, потому что new_testClass указатель на QDialog, и о myslot() ему ничего неизвестно.
все верно, т.к. new_testClass указатель на базовый класс, в котором нет такой функции. А в наследнике есть.
И соединение Qt выполняет во время выполнения программы, когда этот указатель, если програмист всё сделал правильно, будет указывать на объект-наследник QDialog распологающий этой функцией. Если она помечена как слот (нужен: макрос Q_OBJECT и ключевое слово slots), то во время выполнения Qt сможет произвести соединение.
igor_bogomolov
Спасибо за науку. Надо будет еще раз почитать про RTTI.
Litkevich Yuriy
Цитата(igor_bogomolov @ 28.3.2009, 6:20) *
про RTTI.
про нее бессмысленно, если я не ошибаюсь, в Qt свой механизм реализован, чтобы не зависить от компилятора. Их целая куча поддерживается в основном благодаря этому. (см. сообщение и выше, я не помню, где начало)
LE0N
Цитата
В принципе не понимаю откуда в ui_***.h, который, по идее, должен генерироваться из ui формы, берется
QObject::connect(comboBox, SIGNAL(currentIndexChanged(int)), ShipmentFormClass, SLOT(select_product_type(int)));
Откуда там вообще конекты?

Не знаю как у вас, но у меня в эклипсе (едиторе форм) имеется возможность работы со слотами 8)
Вот оттуда у меня она и берётся 8))))
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.