crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> Qwt и Qmdiarea, график qwt не работает в subwindow
gvenihvivar
  опции профиля:
сообщение 22.8.2014, 10:41
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 36
Регистрация: 6.11.2013
Пользователь №: 3967

Спасибо сказали: 0 раз(а)




Репутация:   0  


Добрый день.

Я взяла пример из библиотеки qwt и переделала немного под нужный мне вариант. Но в итоговом интерфейсе виджет должен работать в одном из subwindow элемента qmdiarea, но он не работает. Отдельно, как полноценный виджет, пожалуйста, а вот внутри никак. Причем не работает он частично, не рисуется сами графики в реальном времени и нет подложки для графика, хотя поле для этого выделено.

Вот код класса
cpuplot.h
Раскрывающийся текст

#ifndef CPUPLOT_H
#define CPUPLOT_H
#define HISTORY 300 // seconds
#include <qwt_plot.h>
#include <qapplication.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qpainter.h>
#include <qwt_plot_layout.h>
#include <qwt_plot_curve.h>
#include <qwt_scale_draw.h>
#include <qwt_scale_widget.h>
#include <qwt_legend.h>
#include <qwt_legend_item.h>
#include <qwt_plot_canvas.h>
#include <QObject>
#include <QTime>


class CpuPlot : public QwtPlot
{
Q_OBJECT
public:
CpuPlot(QWidget *parent = 0);
enum CpuData
{
Pressure,
Flow,
Temp,
Density,

NCpuData
};


void statistic(double &flow, double &pressure, double &temp, double &density);
QTime upTime() const;
private slots:
void showCurve(QwtPlotItem *, bool on);
protected:
void timerEvent(QTimerEvent *e);
private:
struct
{
QwtPlotCurve *curve;
double data[HISTORY];
} data[NCpuData];
int dataCount;
double timeData[HISTORY];
float Q;
float Ro;
float P;
float Te;
public slots:
void slotPoint(float Q1,float Ro1,float P1,float T1,QDateTime dt, quint8 table);
};

#endif // CPUPLOT_H



cpuplot.cpp
Раскрывающийся текст

#include "cpuplot.h"


class TimeScaleDraw: public QwtScaleDraw
{
public:
TimeScaleDraw(const QTime &base):
baseTime(base)
{
}
virtual QwtText label(double v) const
{
QTime upTime = baseTime.addSecs((int)v);
return upTime.toString();
}
private:
QTime baseTime;
};

class Background: public QwtPlotItem
{
public:
Background()
{
setZ(0.0);
}

virtual int rtti() const
{
return QwtPlotItem::Rtti_PlotUserItem;
}

virtual void draw(QPainter *painter,
const QwtScaleMap &, const QwtScaleMap &yMap,
const QRectF &rect) const
{
QColor c(Qt::white);
QRectF r = rect;

for ( int i = 25; i > 0; i -= 5 )
{
r.setBottom(yMap.transform(i - 5));
r.setTop(yMap.transform(i));
painter->fillRect(r, c);

c = c.dark(110);
}
}
};

class CpuCurve: public QwtPlotCurve
{
public:
CpuCurve(const QString &title):
QwtPlotCurve(title)
{
setRenderHint(QwtPlotItem::RenderAntialiased);
}

void setColor(const QColor &color)
{
QColor c = color;
c.setAlpha(150);
setPen©;
// setBrush©; //fill space under curve
}
};

CpuPlot::CpuPlot(QWidget *parent):
QwtPlot(parent),
dataCount(0)
{

setAutoReplot(false);

canvas()->setBorderRadius( 10 ); // skruglenije reqtangle

plotLayout()->setAlignCanvasToScales(true); // rastjagivaet seryj color do krajev reqt

QwtLegend *legend = new QwtLegend;
legend->setItemMode(QwtLegend::CheckableItem);
insertLegend(legend, QwtPlot::RightLegend);

setAxisTitle(QwtPlot::xBottom, " Time [h:m:s]");
setAxisScaleDraw(QwtPlot::xBottom,
new TimeScaleDraw(/*cpuStat.*/upTime()/*up*/)); // time on scale
setAxisScale(QwtPlot::xBottom, 0, HISTORY); // horizontal scale 60
setAxisLabelRotation(QwtPlot::xBottom, -50.0); // pod uglov scale
setAxisLabelAlignment(QwtPlot::xBottom, Qt::AlignLeft | Qt::AlignBottom); // ???????????????????

QwtScaleWidget *scaleWidget = axisWidget(QwtPlot::xBottom); //??
const int fmh = QFontMetrics(scaleWidget->font()).height();
scaleWidget->setMinBorderDist(0, fmh / 2);

setAxisTitle(QwtPlot::yLeft, "Parameters "); // vertical scale
setAxisScale(QwtPlot::yLeft, 0, 25);

Background *bg = new Background(); // grey background
bg->attach(this);

CpuCurve *curve;

curve = new CpuCurve("Pressure");
curve->setColor(Qt::red);
curve->attach(this);
curve->setStyle(QwtPlotCurve::Lines);
data[Pressure].curve = curve;

curve = new CpuCurve("Flow");
curve->setColor(Qt::blue);
curve->setZ(curve->z() - 1);
curve->attach(this);
data[Flow].curve = curve;

curve = new CpuCurve("Temp");
curve->setColor(Qt::black);
curve->setZ(curve->z() - 2);
curve->attach(this);
data[Temp].curve = curve;

curve = new CpuCurve("Density");
curve->setColor(Qt::darkGreen);
curve->setZ(curve->z() - 3);
curve->attach(this);
data[Density].curve = curve;

showCurve(data[Pressure].curve, true);
showCurve(data[Flow].curve, true);
showCurve(data[Temp].curve, true);
showCurve(data[Density].curve, true);

for ( int i = 0; i < HISTORY; i++ )
timeData[HISTORY - 1 - i] = i;

(void)startTimer(1000); // 1 second

connect(this, SIGNAL(legendChecked(QwtPlotItem *, bool)),
SLOT(showCurve(QwtPlotItem *, bool)));
}
void CpuPlot::timerEvent(QTimerEvent *)
{
for ( int i = dataCount; i > 0; i-- )
{
for ( int c = 0; c < NCpuData; c++ )
{
if ( i < HISTORY )
data[c].data[i] = data[c].data[i-1];
}
}

if ( dataCount < HISTORY )
dataCount++;

for ( int j = 0; j < HISTORY; j++ )
timeData[j]++;

setAxisScale(QwtPlot::xBottom,
timeData[HISTORY - 1], timeData[0]);

for ( int c = 0; c < NCpuData; c++ )
{
data[c].curve->setRawSamples(
timeData, data[c].data, dataCount);
}

replot();
}
void CpuPlot::showCurve(QwtPlotItem *item, bool on)
{
item->setVisible(on);
QWidget *w = legend()->find(item);
if ( w && w->inherits("QwtLegendItem") )
((QwtLegendItem *)w)->setChecked(on);

replot();
}

void CpuPlot::slotPoint(float Q1, float Ro1, float P1, float T1, QDateTime dt,quint8 table)
{
data[Flow] .data[0] = Q1;
data[Pressure].data[0] = P1;
data[Temp] .data[0] = T1;
data[Density] .data[0] = Ro1/100;

}
QTime CpuPlot::upTime() const
{
QTime t(QTime::currentTime().addSecs(-HISTORY));
//for ( int i = 0; i < NValues; i++ )
t = t.addSecs(1);

return t;

}

void CpuPlot::statistic(double &flow, double &pressure, double &temp,double &density)
{
flow = Q;
pressure = P;
temp = Te;
density = Ro/100;
}


Так он работает

часть main
Раскрывающийся текст

QWidget vBox;
vBox.setWindowTitle("Cpu Plot");
CpuPlot *plot = new CpuPlot(&vBox);
plot->setTitle("History");

const int margin = 5;
plot->setContentsMargins(margin, margin, margin, margin);

QObject::connect(&ct, SIGNAL(toGraph(float, float, float, float, QDateTime,quint8)),
plot, SLOT(slotPoint(float,float,float,float,QDateTime,quint8)));

QHBoxLayout *lay = new QHBoxLayout;
lay->addWidget(plot);
vBox.setLayout(lay);
vBox.show();


А так он написан в виде части mdiarea

Раскрывающийся текст

QMdiSubWindow *subWindow1 = new QMdiSubWindow;
subWindow1->setWindowTitle(tr(" График параметров Замерного узла"));

CpuPlot *plot = new CpuPlot(subWindow1);
plot->setTitle("History");

const int margin = 5;
plot->setContentsMargins(margin, margin, margin, margin);


QObject::connect(this, SIGNAL(toGraph(float, float, float, float, QDateTime,quint8)),
plot, SLOT(slotPoint(float,float,float,float,QDateTime,quint8)));

QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(plot);

subWindow1->setWidget(plot);
subWindow1->setAttribute(Qt::WA_DeleteOnClose);
ui->mdiarea->addSubWindow(subWindow1);
subWindow1->show();


Возможно я не знаю какой-то элементарной вещи.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Trisch
  опции профиля:
сообщение 22.8.2014, 12:56
Сообщение #2


Активный участник
***

Группа: Участник
Сообщений: 379
Регистрация: 30.1.2012
Из: Запорожье
Пользователь №: 3169

Спасибо сказали: 24 раз(а)




Репутация:   0  


Цитата(gvenihvivar @ 22.8.2014, 10:41) *
QObject::connect(&ct, SIGNAL(toGraph(float, float, float, float, QDateTime,quint8)),
plot, SLOT(slotPoint(float,float,float,float,QDateTime,quint8)));


Что такое "ct"?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gvenihvivar
  опции профиля:
сообщение 22.8.2014, 13:02
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 36
Регистрация: 6.11.2013
Пользователь №: 3967

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Trisch @ 22.8.2014, 12:56) *
Цитата(gvenihvivar @ 22.8.2014, 10:41) *
QObject::connect(&ct, SIGNAL(toGraph(float, float, float, float, QDateTime,quint8)),
plot, SLOT(slotPoint(float,float,float,float,QDateTime,quint8)));


Что такое "ct"?


"ct" это класс сервера, который принимает данные. Находится он в другом потоке и через это соединение передает данные в основной поток, а потом и непосредственно в класс с графиком
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Trisch
  опции профиля:
сообщение 22.8.2014, 14:49
Сообщение #4


Активный участник
***

Группа: Участник
Сообщений: 379
Регистрация: 30.1.2012
Из: Запорожье
Пользователь №: 3169

Спасибо сказали: 24 раз(а)




Репутация:   0  


А когда виджет графика является частью mdiarea слот slotPoint отрабатывает?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gvenihvivar
  опции профиля:
сообщение 22.8.2014, 15:44
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 36
Регистрация: 6.11.2013
Пользователь №: 3967

Спасибо сказали: 0 раз(а)




Репутация:   0  


да, отрабатывает. В массив данные собираются. И событие по таймеру тоже отрабатывает. Получается, что теоретически он перерисовывает и есть, что там перерисовывать
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 22.8.2014, 20:11
Сообщение #6


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Не увидел вызова setLayout во втором варианте.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gvenihvivar
  опции профиля:
сообщение 22.8.2014, 21:02
Сообщение #7


Студент
*

Группа: Участник
Сообщений: 36
Регистрация: 6.11.2013
Пользователь №: 3967

Спасибо сказали: 0 раз(а)




Репутация:   0  


layout это не рабочий код, с ним тоже не работает, говорит, что у subwindow mdi уже есть layout и другого ему не нужно
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Trisch
  опции профиля:
сообщение 23.8.2014, 0:12
Сообщение #8


Активный участник
***

Группа: Участник
Сообщений: 379
Регистрация: 30.1.2012
Из: Запорожье
Пользователь №: 3169

Спасибо сказали: 24 раз(а)




Репутация:   0  


Цитата(gvenihvivar @ 22.8.2014, 21:02) *
layout это не рабочий код, с ним тоже не работает, говорит, что у subwindow mdi уже есть layout и другого ему не нужно


такая ошибка может быть из-за того что вы передаете объекту layout при инициализации не того "родителя", но, зачастую, программа все равно отрабатывает правильно.

В общем, можете скинуть весь проект в архиве?

Сообщение отредактировал Trisch - 23.8.2014, 0:14
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gvenihvivar
  опции профиля:
сообщение 23.8.2014, 7:24
Сообщение #9


Студент
*

Группа: Участник
Сообщений: 36
Регистрация: 6.11.2013
Пользователь №: 3967

Спасибо сказали: 0 раз(а)




Репутация:   0  


Возможно. С началом рабочей недели во вторник выложу проект.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 23.8.2014, 15:29
Сообщение #10


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Цитата(gvenihvivar @ 22.8.2014, 22:02) *
layout это не рабочий код, с ним тоже не работает, говорит, что у subwindow mdi уже есть layout и другого ему не нужно

this->layout()->addWidget(...)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.3.2024, 12:44