![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
gvenihvivar |
![]()
Сообщение
#1
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 6.11.2013 Пользователь №: 3967 Спасибо сказали: 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 |
![]()
Сообщение
#2
|
![]() Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 379 Регистрация: 30.1.2012 Из: Запорожье Пользователь №: 3169 Спасибо сказали: 24 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
gvenihvivar |
![]()
Сообщение
#3
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 6.11.2013 Пользователь №: 3967 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
QObject::connect(&ct, SIGNAL(toGraph(float, float, float, float, QDateTime,quint8)), plot, SLOT(slotPoint(float,float,float,float,QDateTime,quint8))); Что такое "ct"? "ct" это класс сервера, который принимает данные. Находится он в другом потоке и через это соединение передает данные в основной поток, а потом и непосредственно в класс с графиком |
|
|
Trisch |
![]()
Сообщение
#4
|
![]() Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 379 Регистрация: 30.1.2012 Из: Запорожье Пользователь №: 3169 Спасибо сказали: 24 раз(а) Репутация: ![]() ![]() ![]() |
А когда виджет графика является частью mdiarea слот slotPoint отрабатывает?
|
|
|
gvenihvivar |
![]()
Сообщение
#5
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 6.11.2013 Пользователь №: 3967 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
да, отрабатывает. В массив данные собираются. И событие по таймеру тоже отрабатывает. Получается, что теоретически он перерисовывает и есть, что там перерисовывать
|
|
|
lanz |
![]()
Сообщение
#6
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Не увидел вызова setLayout во втором варианте.
|
|
|
gvenihvivar |
![]()
Сообщение
#7
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 6.11.2013 Пользователь №: 3967 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
layout это не рабочий код, с ним тоже не работает, говорит, что у subwindow mdi уже есть layout и другого ему не нужно
|
|
|
Trisch |
![]()
Сообщение
#8
|
![]() Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 379 Регистрация: 30.1.2012 Из: Запорожье Пользователь №: 3169 Спасибо сказали: 24 раз(а) Репутация: ![]() ![]() ![]() |
layout это не рабочий код, с ним тоже не работает, говорит, что у subwindow mdi уже есть layout и другого ему не нужно такая ошибка может быть из-за того что вы передаете объекту layout при инициализации не того "родителя", но, зачастую, программа все равно отрабатывает правильно. В общем, можете скинуть весь проект в архиве? Сообщение отредактировал Trisch - 23.8.2014, 0:14 |
|
|
gvenihvivar |
![]()
Сообщение
#9
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 6.11.2013 Пользователь №: 3967 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Возможно. С началом рабочей недели во вторник выложу проект.
|
|
|
lanz |
![]()
Сообщение
#10
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
![]() ![]() ![]() |
![]() |
|
Текстовая версия | Сейчас: 3.5.2025, 5:50 |