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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Связывание кнопки со слотом  (Прочитано 3551 раз)
SpiritFire
Гость
« : Ноябрь 16, 2009, 21:07 »

Извините за глупый вопрос, но пол дня про тр(CENSORED)лся с этой ерундой, ни черта понять не могу. Подскадите, пожалуйста, в чем я туплю?

Есть кнопка с произвольным внешним видом, добавляемая на виджет во время выполнения. Надо определить ее поведение при нажатии мыши (честно говоря и при вызове контекстного меню, но до него еще дожить надо).

Определил класс кнопки:
Код:
#ifndef MARKBUTTON_H
#define MARKBUTTON_H

#include <QObject>
#include <QPushButton>

class MarkButton : public QPushButton
{
    // Q_OBJECT    // -- 1
public:
    MarkButton(QWidget* parent = 0);

public slots:
    void click();

protected:
    void paintEvent(QPaintEvent* event);
};

#endif // MARKBUTTON_H

Написал обработчики:

Код:
#include "MarkButton.h"
#include <QPainter>


MarkButton::MarkButton(QWidget* parent)
 : QPushButton(parent)
{
    resize(50,50);

    QObject::connect(this, SIGNAL(clicked()), this, SLOT(click()));  // -- 2
}


void MarkButton::paintEvent(QPaintEvent* event)
{
    QPainter painter(this);

    painter.setPen  ( Qt::red );
    painter.drawRect( QRect(0,0, 50, 50) );
}


void MarkButton::click()
{
    int x = 5;

    x++;
    x++;   // тут брейкпоинт
    x++;

    int y = x;
}

Добавил ее на виджет:
Код:
 void f(QWidget* buttonPlace)
{
   m_linkedButton = new MarkButton(buttonPlace);
}

Комментарии:

// -- 1:  Если строку раскомментировать не компилится:
Цитировать
../src/MarkButton.cpp:7: undefined reference to `vtable for MarkButton'
:-1: error: collect2: ld returned 1 exit status

// -- 2: Если строку закомментировать, обработчик не вызывается, если оставить - хз что вызывается, но на клике возникает сигнал в дебрях системы, прога падает.

Объясните пожалуйста дятлу, каким образом добавить кнопку на виджет во время выполнения и связвать её с обработчиком?
« Последнее редактирование: Ноябрь 16, 2009, 23:49 от SpiritFire » Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #1 : Ноябрь 16, 2009, 21:24 »

Цитировать
// -- 1:  Если строку раскомментировать не компилится:
запусти qmake, для всех наследников QObject, сразу определяй макрос Q_OBJECT, чтобы потом опять qmake не запускать, когда тебе этот макрос вдруг приспичет
Записан

Юра.
MoPDoBoPoT
Гость
« Ответ #2 : Ноябрь 16, 2009, 21:37 »

Во-первых, Q_OBJECT нужен для использования сигнал-слотов (еще для свойств и tr(), по-моему), во-вторых,
если ты создал некий класс (без Q_OBJECT) и делаешь qmake, а затем решил добавить Q_OBJECT, то компиляция не пройдет, т.к. надо по новой сгенерировать Makefile.
Записан
SpiritFire
Гость
« Ответ #3 : Ноябрь 17, 2009, 01:39 »

Цитировать
запусти qmake,
Да qmake я запускал, точнее не я, а QtCreator. Проблема нашлась, когда сделал тестовый проект и потихонбку навешивал на него все то, что в реальном. Вот так работает:
Код:
#ifndef BUTTONCREATOR_H
#define BUTTONCREATOR_H

#include <QObject>
#include <QGraphicsItem>

class ButtonCreator : public QObject, public QGraphicsItem
{
    Q_OBJECT

public:
    ButtonCreator(QWidget* parent = 0);

    QRectF boundingRect() const                                                 { return QRectF(); }
    void   paint(QPainter* p, const QStyleOptionGraphicsItem* o, QWidget* w)    { }

public slots:
    void onClick();

private:
    QWidget* m_parent;
};

#endif // BUTTONCREATOR_H
Код:
#include "buttoncreator.h"
#include <QMessageBox>
#include <QPushButton>

ButtonCreator::ButtonCreator(QWidget* parent)
 : m_parent(parent)
{
    QPushButton* button = new QPushButton("Dynamic buton", parent);

    button->setVisible(true);
    button->setEnabled(true);

    QObject::connect(button, SIGNAL(clicked()), this, SLOT(onClick()));
}


void ButtonCreator::onClick()
{
    QMessageBox::information(m_parent, "123", "123");
}

Если сделать порядок наследования наоборот (:public QGraphicsItem, public QObject), тогда сыпятся ошибки. Не знаю, с чем связано, да и ковырять в 12 ночи неохота.

Здесь первоначальный вариант, класс, создающий кнопку - это потомок QGraphicsItem, потом так как этот не прошел попробовал коннектить сигнал в переопределенном классе кнопки, видимо, там та же беда с наследованием.
В любом случае постараюсь избежать множественного наследования в реальной задаче.

Проблема решена, всем спасибо за участие, но если кто для общего развития прольет свет на то, почему от порядка наследования зависит успешность компиляции - буду весьма принателен.

Исходники прилагаются.
« Последнее редактирование: Ноябрь 17, 2009, 01:42 от SpiritFire » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #4 : Ноябрь 17, 2009, 09:49 »

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


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