Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Передача значений из метода paintEvent в другой класс в тот же самый метод
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Система рисования. Печать
zuze
1. Есть класс

#ifndef L_H
#define L_H

#include <QLabel>
#include <QPainter>
#include <QTimer>
#include <math.h>

class l : public QLabel
{
    Q_OBJECT
public:
    explicit l(QWidget *parent = 0);
    float alpha; // Угол поворота

signals:

public slots:

protected:
    void paintEvent(QPaintEvent *);

};

#endif // L_H


#include "l.h"

l::l(QWidget *parent) :
    QLabel(parent)
{
    alpha = -1.0;
}
// Ввывод окружности и линию
void l::paintEvent(QPaintEvent *)
{
        alpha += 2*M_PI/1000;
}


2. Как alpha передать в другой класс и в такой же метод?

например в такой

#ifndef P_H
#define P_H

#include <QLabel>
#include <QPainter>

class p : public QLabel
{
    Q_OBJECT
public:
    explicit p(QWidget *parent = 0);
    float d;

signals:

public slots:

private:
    void paintEvent(QPaintEvent *);

};

#endif // P_H


#include "p.h"

p::p(QWidget *parent) :
    QLabel(parent)
{
}
void p::paintEvent(QPaintEvent *)
{
    d = alpha;
}


В классе 'p' не видна же alpha. Как же правильно передать alpha? Через Сигналы и Слоты вроде надо, но я не пойму как это сделать. Помогите пожалуйста разобраться.
RazrFalcon
Через сигналы:

В class l в signals добавляем
signals:
void alphaChanged(int);

void l::paintEvent(QPaintEvent *)
{
        alpha += 2*M_PI/1000;
        emit alphaChanged(alpha);
}
Затем:
class p : public QLabel
{
...
public slots:
        void setAlpha(int value)

В MainWindow, где вы имеете доступ к обоим классам:
connect(lbl1, SIGNAL(alphaChanged(int), lbl2, SLOT(setAlpha(int)));
zuze
RazrFalcon, я сделал, как Вы написали и объявил ещё lbl1, lbl2.

В MainWindow.h

public:
    locator *lbl1;
    pryamaya *lbl2;


В MainWindow.cpp (в конструкторе)

lbl1 = new l();
lbl2 = new p();


А в результате компилятор всё равно выдаёт ошибку:
In mamber function 'virtual void p::paintEvent(QPaintEvent *)':
'alpha' was not declared in this scope.

То есть всё равно переменная alpha не видна. Что же не так?
RazrFalcon
Конечно не видет.
Вы должны в QLabel создать переменную alpha и задает ее значение через слот setAlpha(int)
zuze
RazrFalcon, то есть мне надо в класс p.h добавить

public:
    int alpha;


А как вот значение переменной alpha задать через слот setAlpha(int)?

Прошу прощения, что я такие "тупые" вопросы спрашиваю, по мере понимания всех процессов в Qt их будет всё меньше.
RazrFalcon
Пример во вложении.
zuze
RazrFalcon, а вот так правильно, я это использую в коде побольше и у меня линия не двигается как будто в переменную ничего не передаётся.

Файлы h

#ifndef L_H
#define L_H

#include <QLabel>

class l : public QLabel
{
    Q_OBJECT
public:
    explicit l(QWidget *parent = 0);
    float alpha;

signals:
    void alphaChanged(float);

public slots:
    void paintEvent(QPaintEvent *);

};

#endif // L_H


#ifndef P_H
#define P_H

#include <QLabel>

class p : public QLabel
{
    Q_OBJECT
public:
    explicit p(QWidget *parent = 0);
    float alpha, d;

signals:

public slots:
    void paintEvent(QPaintEvent *);
    void setAlpha(float value);
};

#endif // P_H


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "l.h"
#include "p.h"

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    l *lbl1;
    p *lbl2;

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H


Файлы cpp

#include "l.h"
#include "math.h"

l::l(QWidget *parent) :
    QLabel(parent)
{
}
void l::paintEvent(QPaintEvent *)
{
        alpha = 2*M_PI/1000;
        emit alphaChanged(alpha);
}


#include "p.h"

p::p(QWidget *parent) :
    QLabel(parent)
{
}
void p::paintEvent(QPaintEvent *)
{
    setAlpha(alpha);
    d = alpha;
}
void p::setAlpha(float value)
{
    alpha = value;
}


#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    lbl1 = new l();
    lbl2 = new p();
    connect(lbl1, SIGNAL(alphaChanged(float)), lbl2, SLOT(setAlpha(float)));

}

MainWindow::~MainWindow()
{
    delete ui;
}
RazrFalcon
Цитата
void p::setAlpha(float value)
{
alpha = value;
update();
}
zuze
RazrFalcon, я не могу поставить в эту процедуру update(); , так как у меня линии вращаются по таймеру. И update(); я вызываю там, где запускаю таймер. Может как-то иначе можно? Запуск таймеров у меня производится в файле mainwindow.cpp.
Моя задача состоит в том что я нажимаю на кнопочку, вертится одна линия (в полярных координатах), как нажимаю другую кнопку то рисуется другая линия, которая передвигается (по прямоугольным координатам). И что бы при переключении линия вертелась с последнего момента перед переключением, а не с нуля. Вот для этих целей я хочу что бы переменная из одного класса была видна в другом классе.
RazrFalcon
Так если нужно просто сохранить последние значение - зачем его вообще выносить из класса?
Не проще ли сделать что бы при первом старте alpha=-1, а при последующих alpha проверялась на равенство -1, и если не -1 - то рисуем с текущей alpha.
Какие проблемы.
zuze
RazrFalcon, если рисовать линии не зависящие друг от друга. То всё прекрасно рисуется. То есть класс "l" рисует по нажатию вращающуюся линию (по параллельным координатам). Класс "p" рисует по нажатию передвигающуюся линию (по прямоугольным координатам). Но если я переключаю на передвижение линии (по прямоугольным координатам), а линия в полярных координатах была допустим на 150 градусах, то и линия в прямоугольных координатах должна начинаться со 150 градусов, а не с нуля.
RazrFalcon
Тогда нужно в обе стороны передавать alpha.
Я то хз как у вас там прога устроена и что делает...

connect(lbl1, SIGNAL(alphaChanged(float)), lbl2, SLOT(setAlpha(float)));
connect(lbl2, SIGNAL(alphaChanged(float)), lbl1, SLOT(setAlpha(float)));
zuze
RazrFalcon, это понятно, что нужно в две стороны alpha передавать. Я пока разбираюсь что бы alpha передать в одну сторону, а именно прямоугольным координатам. Я вроде всё сделал, alpha передаётся, но линия в прямоугольных координатах начинает двигаться от нуля, а не там, где были полярные координаты в момент переключения. Что же я не так сделал?
Для понимания, я напишу подробный код:

Файлы h

#ifndef L_H
#define L_H

#include <QLabel>
#include <QPainter>
#include <QTimer>
#include <math.h>

class l : public QLabel
{
    Q_OBJECT
public:
    explicit l(QWidget *parent = 0);
    bool FlagDraw; // Флаг разрешения и запрещения рисования на label
    float alpha; // Угол поворота

signals:
    void alphaChanged(float);

public slots:

protected:
    void paintEvent(QPaintEvent *);

};

#endif // L_H


#ifndef P_H
#define P_H

#include <QLabel>
#include <QPainter>

class p : public QLabel
{
    Q_OBJECT
public:
    explicit p(QWidget *parent = 0);
    bool FlagDraw; // Флаг разрешения и запрещения рисования на label
    float d;
    float alpha;

signals:

public slots:
    void setAlpha(float value);

protected:
    void paintEvent(QPaintEvent *);

};

#endif // P_H


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QDialog>
#include <QTextCodec>
#include "l.h"
#include "p.h"

namespace Ui {
    class mainwindow;
}

class mainwindow : public QDialog
{
    Q_OBJECT

public:
    explicit mainwindow(QWidget *parent = 0);
    ~mainwindow();
    QTimer *timer;
    QTimer *timer1;
    l *lbl1;
    p *lbl2;
    bool FlagRunStop;
    bool FlagPolaris;
    bool FlagRect;
    int FlagTimer; // Указывает какой таймер сейчас запущен или остановлен

public slots:
    void onClick();
    void onClick1();
    void onTimer();
    void onTimer1();
    void BlockTimer();

private:
    Ui::mainwindow *ui;

};

#endif // MAINWINDOW_H


Файлы cpp

#include "l.h"

l::l(QWidget *parent) :
    QLabel(parent)
{
    FlagDraw = false;
    alpha = 0.0;
}
// Вывод окружности и линию
void l::paintEvent(QPaintEvent *)
{
    float x2 = 0.0, y2 = 0.0;
    if (FlagDraw == true)
    {
        // рисуем окружность
        QPainter Ellipse(this);
        Ellipse.setBrush(QBrush(Qt::black));
        Ellipse.drawEllipse(0, 0, l::width(), l::height());

        // Рисуем линию
        QPainter Line(this);
        Line.setPen(Qt::green);

        Line.translate(300, 300);
        alpha += 2*M_PI/1000;
        x2 = 300 * cos(alpha);
        y2 = 300 * sin(alpha);
        Line.drawLine(0, 0, x2, y2);
        Line.rotate(alpha);
        emit alphaChanged(alpha);
    }
}


#include "p.h"
#include "math.h"

p::p(QWidget *parent) :
    QLabel(parent)
{
    FlagDraw = false;
    d = 0.0;
}
// Вывод окружности и линию
void p::paintEvent(QPaintEvent *)
{
    float x;
    if (FlagDraw == true)
    {
        // рисуем прямоугольник
        QPainter painterRect(this);
        painterRect.setBrush(QBrush(Qt::black));
        painterRect.drawRect(0, 0, p::width(), 600);

        // Рисуем линию
        QPainter Line(this);
        Line.setPen(Qt::green);

        if (d <= p::width())
        {
           setAlpha(alpha);
           d += cos(alpha);
           Line.drawLine(x, 600, x, 0);
        }
        else
           d = 0.0;
    }
}
void p::setAlpha(float value)
{
    alpha = value;
}


#include "mainwindow.h"
#include "ui_mainwindow.h"

mainwindow::mainwindow(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::mainwindow)
{
    ui->setupUi(this);
    lbl1 = new l();
    lbl2 = new p();
    connect(lbl1, SIGNAL(alphaChanged(float)), lbl2, SLOT(setAlpha(float)));

    FlagPolaris = false; // Начальное задание флага нажата ли кнопка "Полярные" первый раз или нет
    FlagRect = false; // Начальное задание флага нажата ли кнопка "Прямоугольные" первый раз или нет
    FlagRunStop = false; // Начальное задание флага для нажатия на кнопку "Запустить / Остановить"

    // Для кодировки русского языка на виджетах
    QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale()); // Без этого кодировки БД не работает
    QTextCodec::setCodecForTr(QTextCodec::codecForName("CP-1251"));

    ui->pushButton_3->setEnabled(false); // По умолчанию кнопка "Запустить / Остановить" заблокирована

    // Запуск полярных координат
    connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(onClick()));
    // Запуск прямоугольных координат
    connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(onClick1()));
    // Пауза таймера
    connect(ui->pushButton_3, SIGNAL(clicked()), this, SLOT(BlockTimer()));
}

mainwindow::~mainwindow()
{
    delete ui;
}
void mainwindow::onClick()
{
     timer = new QTimer(this);
     connect(timer, SIGNAL(timeout()), this, SLOT(onTimer()));
     timer->start(1);
     ui->pushButton->setEnabled(false);
}
void mainwindow::onClick1()
{
     connect(lbl1, SIGNAL(alphaChanged(float)), lbl2, SLOT(setAlpha(float)));
     timer1 = new QTimer(this);
     connect(timer1, SIGNAL(timeout()), this, SLOT(onTimer1()));
     timer1->start(1);
     ui->pushButton_2->setEnabled(false);
}
void mainwindow::onTimer()
{
    FlagTimer = 1;
    FlagPolaris = true;

    if (FlagRect == true)
    {
       timer1->blockSignals(true); // Блокировка таймера прямолинейных координат
       FlagRect = false;
   }

    ui->pushButton_2->setEnabled(true); // Блокировка кнопки "Параллельные"

    ui->label_3->setVisible(false); // Скрытие виджета вывода параллельных координат
    ui->label->setVisible(true); // Открытие виджета вывода полярных координат

    ui->label->FlagDraw = true;
    ui->label->update(); // Рисование полярных координат

    ui->pushButton->setEnabled(false);
    ui->pushButton_3->setEnabled(true); // Разблокировать кнопку "Запустить / Остановить"

    FlagRunStop = false;
    ui->pushButton_3->setText(tr("Остановить"));
}
// Блокирование таймера
void mainwindow::BlockTimer()
{
        if (FlagRunStop == true)
        {
            if (FlagTimer == 1)
            {
               timer->blockSignals(false); // Запустить таймер
               ui->pushButton_3->setText(tr("Остановить"));
               FlagRunStop = false;
            }
            else
            {
                timer1->blockSignals(false); // Запустить таймер
                ui->pushButton_3->setText(tr("Остановить"));
                FlagRunStop = false;
            }
        }
        else
        {
            if (FlagTimer == 2)
            {
                timer1->blockSignals(true); // Остановить таймер
                ui->pushButton_3->setText(tr("Запустить"));
                FlagRunStop = true;
            }
            timer->blockSignals(true); // Остановить таймер
            ui->pushButton_3->setText(tr("Запустить"));
            FlagRunStop = true;
        }
}
void mainwindow::onTimer1()
{
    FlagTimer = 2;
    FlagRect = true;

    ui->pushButton->setEnabled(true); // Блокировка кнопки "Полярные"

    //if (FlagPolaris > 1)
    if (FlagPolaris == true)
    {
       timer->blockSignals(true); // Блокировка таймера полярных координат
       FlagPolaris = false;
   }

    ui->label->setVisible(false); // Скрытие виджета вывода полярных координат
    ui->label_3->setVisible(true); // Открытие виджета параллельных координат

    ui->label_3->FlagDraw = true;
    ui->label_3->update(); // Рисование прямолинейных координат

    ui->pushButton_2->setEnabled(false);
    ui->pushButton_3->setEnabled(true); // Разблокировать кнопку "Запустить / Остановить"
    FlagRunStop = false;
    ui->pushButton_3->setText(tr("Остановить"));
}
zuze
Задача решена:
А где переходил на другую систему координат сделал


connect(lbl1, SIGNAL(alphaChanged(float)), lbl2, SLOT(setAlpha(float)));



Кстати начиналась от нуля, так как я эту строчку в конструкторе ввёл.
zuze
Что всё нормально - это окозалось ложно. Так как я брал cos и думал проблема в чём-то другом, а не в передаче alpha из класса в класс. Но благадоря что я сделал qDebuq(). Я понял что именно в передаче alpha проблемы.
Последнее значение alpha в классе "l" положительное, например 1.0354, а в классе "p" оно сразуже сильно отрицательное, например 4.03456-33. Значит как-то не так я передаю переменную из класса в класс хотя вроде всё описал как Вы сказали. Как это поправить?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.