Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Ales от Февраль 04, 2014, 00:51



Название: QStackedWidget замена Widgeta при нажатии на кнопку
Отправлено: Ales от Февраль 04, 2014, 00:51
Пытаюсь, сделать так, чтобы при нажатии на кнопку изменялось содержимое окна, делаю через QStackWidget

пишет ошибку : QObject::connect: No such slot QWidget::clickRules () , не понимаю в чём дело

вот код:
Код:
#include "mainwindow.h"
#include <QApplication>
#include <QtGui>
#include <QStackedWidget>
#include <QPushButton>
#include <QWidget>
#include <QGroupBox>
#include <QLayout>
#include <QObject>
#include <QtDebug>

class MainWidget : public QWidget {
    public :
        QPushButton* buttonRules;
        MainWidget( );
};

class RulesWidget : public QWidget {
    public:
        QPushButton* mainButton;
        RulesWidget();
};

MainWidget :: MainWidget () {
    buttonRules = new QPushButton("Rules");
    QVBoxLayout* buttonLayout = new QVBoxLayout;
    buttonLayout->addWidget(buttonRules);
    setLayout(buttonLayout);
}

RulesWidget :: RulesWidget () {
    mainButton = new QPushButton("Main");
    QVBoxLayout* buttonLayout = new QVBoxLayout;
    buttonLayout->addWidget(mainButton);
    setLayout(buttonLayout);
}


class TheMainestWidget : public QWidget {
    private:

    public:
        MainWidget* menu;
        RulesWidget* rules;
        QStackedWidget* stackOfWidgets;
        TheMainestWidget ();
    public slots:
        void clickMenu (QStackedWidget*);
        void clickRules ();
};

TheMainestWidget :: TheMainestWidget () {
    menu = new MainWidget;
    rules = new RulesWidget;

    stackOfWidgets = new QStackedWidget;
    stackOfWidgets->addWidget(menu);
    stackOfWidgets->addWidget(rules);
    stackOfWidgets->setCurrentWidget(menu);
   // stackOfWidgets->show();

    connect(rules->mainButton, SIGNAL(clicked()), qApp, SLOT(quit()));
    connect(menu->buttonRules, SIGNAL(clicked()), SLOT(clickRules () ));
    stackOfWidgets->show();
}

void TheMainestWidget :: clickMenu(QStackedWidget* stackOfWidgets) {
    stackOfWidgets->setCurrentWidget(menu);
    stackOfWidgets->show();
}

void TheMainestWidget :: clickRules() {
    stackOfWidgets->setCurrentWidget(rules);
    stackOfWidgets->show();
}


int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
 //   MainWindow w;
 //   w.show();

    TheMainestWidget game;


    return a.exec();
}


да, я знаю код плохой, плохие названия, все данные public,))  должно быть, что при нажатии на кнопку, появляется другая кнопка в окне, вместо этой, и при нажатии на появившуюся кнопку виджета закрывается.
Буду благодарен за помощь)


Название: Re: QStackedWidget замена Widgeta при нажатии на кнопку
Отправлено: Bepec от Февраль 04, 2014, 17:57
По пунктам.
1) используйте тег Code для кода - значок вот такой на панельке "#".
2) ЧТО ЭТО?
Код:
TheMainestWidget :: TheMainestWidget (QApplication &a)
и зачем?
3) макроса Q_OBJECT нету в объявлении класса со слотами.
4) разделяйте классы. Разделяйте Cpp и h.

оффтоп: у вас глаза не выпучиваются когда в эти макароны смотрите? у меня вылезли :D

PS посмотрел просто потому что хорошее настроение было. А так бы и не сунулся, извиняйте :)


Название: Re: QStackedWidget замена Widgeta при нажатии на кнопку
Отправлено: Ales от Февраль 04, 2014, 21:43
Спасибо,)
1) исправил, не знал как такое делать))
2) я предаю в конструктор
Код:
 QApplication &a 
, чтобы при нажатии на кнопку можно было выйти из программы, может можно как-то по другому, но у меня не получалось)
3) почему-то когда я объявляю этот макрос, то выскакивает такая ошибка : LNK2001: неразрешенный внешний символ ""public: virtual struct QMetaObject const *, ну и такая ошибка не одна
4) да я знаю, что нужно разделять, но тут хотел быстрее сделать, решил всё в одном файле писать, получилось наоборот)

Ещё раз спасибо за информацию  :)


Название: Re: QStackedWidget замена Widgeta при нажатии на кнопку
Отправлено: gil9red от Февраль 05, 2014, 01:02
2) Уберите у конструктора передачу ссылки на экземпляр QApplication - он не нужен, потому что есть статичные методы + можно использовать макрос qApp, для получения указателя на QApplication :)

Код
C++ (Qt)
connect( rules->mainButton, SIGNAL(clicked()), qApp , SLOT(quit())) ;

PS. так как ваш класс является наследников QObject, то использовать QObject:: не нужно!

3) Очистите проект (на всякий случай), после запустите qmake :)
Просто, классы с макросом Q_OBJECT должны были пройти через метакомпилятор qt (вызов qmake), но этого не случилось :)


Название: Re: QStackedWidget замена Widgeta при нажатии на кнопку
Отправлено: Ales от Февраль 05, 2014, 11:57
Спасибо, :)
2) Ага, с этим разобрался, всё исправил )) мне тоже не нравилась эта передача параметра по ссылке.
3) А вот тут всё сложнее, что-то у меня не получается всё равно :-\  как я понял запустить qmake можно нажатий правой кнопки на проект, потом qmake ), но всё равно у меня те же самые ошибки, может я делаю что-то неправильно или не в той последовательности, ведь как сначала добавляем макрос Q_OBJECT, потом запускаем qmake?
P.S. Ещё раз благодарю за помощь :)


Название: Re: QStackedWidget замена Widgeta при нажатии на кнопку
Отправлено: Bepec от Февраль 05, 2014, 12:31
Я обычно советую удалить креатор и поставить студию :D

Но по слухам помогает clean проекта (или удалить нафиг все сгенерированные файлы) и заного собрать.


Название: Re: QStackedWidget замена Widgeta при нажатии на кнопку
Отправлено: gil9red от Февраль 05, 2014, 15:51
Я обычно советую удалить креатор и поставить студию :D
Креатор хороший, не нужно его обижать :)

Ales, правой кнопкой и выберите Очистить проект, а потом выберите qmake
Или вручную удалите папку build (или как она у вас там называется) после делайте сборку :)
Должно помочь ;)


Название: Re: QStackedWidget замена Widgeta при нажатии на кнопку
Отправлено: Ales от Февраль 06, 2014, 22:38
Эх, что я не пытался сделать ничего не помогло, и очищал после запускал qmake, и удалял папку build потом делал тоже самое)
ничего не помогло : пишет эти ошибки : LNK2001: неразрешенный внешний символ ""public: virtual struct QMetaObject const *,
что делать не знаю) в чём же тут дело?


Название: Re: QStackedWidget замена Widgeta при нажатии на кнопку
Отправлено: Bepec от Февраль 06, 2014, 23:32
макроса Q_OBJECT может находиться только в классе, наследованном от QObject.


Название: Re: QStackedWidget замена Widgeta при нажатии на кнопку
Отправлено: gil9red от Февраль 07, 2014, 00:17
Автор темы еще может сбросить сюда проект, так будет проще (возможно) найти ошибку и решение :)


Название: Re: QStackedWidget замена Widgeta при нажатии на кнопку
Отправлено: Bepec от Февраль 07, 2014, 00:44
А я думаю, что как обычно, читают первые 3 строки, читают следующий коммент :D


Название: Re: QStackedWidget замена Widgeta при нажатии на кнопку
Отправлено: Ales от Февраль 07, 2014, 14:27
Как просили скидываю проект)
Вот архив проекта; как я понимаю, то остальные файлы роли сильной не играют.  :)

Ну и с наследованием наверное всё правильно, мои классы наследуются от QWidget, а  QWidget это же наследник QObject, значит и мои объекты наследуются от QObject.
P.S Спасибо всем за помощь в этом запутанном деле :) ;)


Название: Re: QStackedWidget замена Widgeta при нажатии на кнопку
Отправлено: gil9red от Февраль 07, 2014, 22:13
Для каждого класса нужно создавать h и cpp файлы ;)
Вот проверьте :)


Название: Re: QStackedWidget замена Widgeta при нажатии на кнопку
Отправлено: Ales от Февраль 13, 2014, 02:45
Очень благодарен, только сейчас смог посмотреть хотя вы уже ответили давно :)
Спасибо большое,  :) всё работает как надо  :)
вы не подключаете так много библиотек как подключал я; так гораздо лучше, код с разбиением на файлы стал чище и понятнее),
Хотя всё равно не понятно почему не работал мой последний вариант.
Ещё раз спасибо за помощь :)


Название: Re: QStackedWidget замена Widgeta при нажатии на кнопку
Отправлено: gil9red от Февраль 13, 2014, 08:06
Пожалуйста ;)