출처 : https://weekly-geekly.github.io/articles/212137/index.html
Qwt and Qt Creator. Part 3: Graph as a Designer Form Element
The examples used are Qt Creator 3.0.0 (MinGW) and Qwt-6.1.0.
To understand this article, the reader must have initial experience in developing windows applications in the Qt Creator environment, and understand the concept of signal-slot. It is also recommended to get acquainted with part 1 and 2 of the series of my articles on Qwt:
')
Qwt is a graphic library that allows you to significantly simplify the process of data visualization in the program. Simplification is as follows: there is no need to manually prescribe display elements, such as scales of coordinates, grids, data curves, and so on. It is only necessary to set the parameters of these elements.
In the previous parts of the cycle of articles, schedule controls were added by manual coding. I think most programmers would prefer to use Qt Creator tools.
In part number 3, we will do the following:
• add a widget to display the graphic in the Designer Form, which allows using Qt Creator controls;
• we will build a demo curve, we will implement the basic convenience of working with the schedule: the ability to move around the schedule field, its approach / delete, we will display the coordinates of the cursor as it moves;
• display click coordinates in the Designer Form status bar;
• move the curve along the x axis using standard Qt Creator controls.
The content of this article to some extent duplicates the content of part 2. This was done on purpose, since I wanted to make the articles independent of each other.
Add a widget to display the graph in the Designer Form
1. Create a project with Mainwindow. Let me remind you of the required procedure for using Qwt: add the line "CONFIG + = qwt" to the project's .pro file and launch qmake via the context menu (right-click on the project root folder).
2. Open the form editor and find the widget “Widget”. Place it on the form.
3. Change the name of the added “Widget” to “Qwt_Widget”.
4. Right click on "Qwt_Widget" and select "Promote to ..."
5. In the Promoted class name field, type “QwtPlot”. In the Header file field, change “qwtplot.h” to “qwt_plot.h”. Click Add and close the window.
We will construct a demonstration curve, we will implement the basic convenience of working with the schedule
Below is the code, in many respects similar to that published in Part 2. The code is slightly improved, the fragments responsible for the “manual” addition of controls are removed.
Pay special attention to the following. Previously, we created a private variable QwtPlot * d_plot, and then used such a construct as, for example:
d_plot->setTitle( "Qwt demonstration" );
Now for the properties of the chart, we will use the following structure:
ui->Qwt_Widget->setTitle( "Qwt demonstration" );
Moreover, if there are no such constructions in the code, then “Qwt_Widget” is empty. After adding a line with the setting, this widget starts displaying the graph field.
The contents of the mainwindow.h file
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <qwt_plot.h> #include <qwt_plot_grid.h> #include <qwt_legend.h> #include <qwt_plot_curve.h> #include <qwt_symbol.h> #include <qwt_plot_magnifier.h> #include <qwt_plot_panner.h> #include <qwt_plot_picker.h> #include <qwt_picker_machine.h> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private Q_SLOTS: void click_on_canvas( const QPoint &pos ); private: Ui::MainWindow *ui; void addPlot(); void addPlotGrid(); QwtPlotCurve *curve; QPolygonF points; void addCurve(); void enableMagnifier(); void enableMovingOnPlot(); void enablePicker(); }; #endif // MAINWINDOW_H
The contents of the mainwindow.cpp file
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); // addPlot(); // addPlotGrid(); // addCurve(); // / enableMagnifier(); // enableMovingOnPlot(); // // enablePicker(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::addPlot() { // #include <qwt_plot.h> ui->Qwt_Widget->setTitle( "Qwt demonstration" ); ui->Qwt_Widget->setCanvasBackground( Qt::white ); // ui->Qwt_Widget->setAxisTitle(QwtPlot::yLeft, "Y"); ui->Qwt_Widget->setAxisTitle(QwtPlot::xBottom, "X"); ui->Qwt_Widget->insertLegend( new QwtLegend() ); } void MainWindow::addPlotGrid() { // #include <qwt_plot_grid.h> QwtPlotGrid *grid = new QwtPlotGrid(); grid->setMajorPen(QPen( Qt::gray, 2 )); // grid->attach( ui->Qwt_Widget ); } void MainWindow::addCurve() { //#include <qwt_plot_curve.h> curve = new QwtPlotCurve(); curve->setTitle( "Demo Curve" ); curve->setPen( Qt::blue, 6 ); // // // #include <qwt_symbol.h> QwtSymbol *symbol = new QwtSymbol( QwtSymbol::Ellipse, QBrush( Qt::yellow ), QPen( Qt::red, 2 ), QSize( 8, 8 ) ); curve->setSymbol( symbol ); // // , // for (int i = 0; i < 5; i++) { points << QPointF( 1.0 * i, 1.0 * i); // } curve->setSamples( points ); // curve->attach( ui->Qwt_Widget ); // } void MainWindow::enableMagnifier() { // #include <qwt_plot_magnifier.h> QwtPlotMagnifier *magnifier = new QwtPlotMagnifier(ui->Qwt_Widget->canvas()); // , / magnifier->setMouseButton(Qt::MidButton); } void MainWindow::enableMovingOnPlot() { // #include <qwt_plot_panner.h> QwtPlotPanner *d_panner = new QwtPlotPanner( ui->Qwt_Widget->canvas() ); // , d_panner->setMouseButton( Qt::RightButton ); } void MainWindow::enablePicker() { // #include <qwt_plot_picker.h> // QwtPlotPicker *d_picker = new QwtPlotPicker( QwtPlot::xBottom, QwtPlot::yLeft, // QwtPlotPicker::CrossRubberBand, // QwtPicker::AlwaysOn, // ui->Qwt_Widget->canvas() ); // // d_picker->setRubberBandPen( QColor( Qt::red ) ); // d_picker->setTrackerPen( QColor( Qt::black ) ); // d_picker->setStateMachine( new QwtPickerDragPointMachine() ); }
The performed actions allow us to display the graph directly in the form, and the dimensions of its canvas correspond to the dimensions of “Qwt_Widget”. Try resizing the form after compiling and running the program. The dimensions of "Qwt_Widget", of course, do not change. For this to happen, you must use the "Layout". I decided not to describe this standard (well-trodden and traversed) procedure in the article.
Display click coordinates in the Designer Form status bar.
1. Add the code to the prototype of the MainWindow class in the mainwindow.h file
private Q_SLOTS: void click_on_canvas( const QPoint &pos );
implement the slot (function) in mainwindow.cpp:
void MainWindow::click_on_canvas( const QPoint &pos ) { // double x = ui->Qwt_Widget->invTransform(QwtPlot::xBottom, pos.x()); double y = ui->Qwt_Widget->invTransform(QwtPlot::yLeft, pos.y()); statusBar()->showMessage("x= " + QString::number(x) + "; y = " + QString::number(y)); }
Add the following line to the function enablePicker ():
connect( d_picker, SIGNAL( appended( const QPoint & ) ), SLOT( click_on_canvas( const QPoint & ) ) );
Alternatively, one could declare d_picker a private variable of the MainWindow class and make the above signal-slot connection in the constructor, or in a special method.
Move the curve along the x axis
Here, since the visualizer is added using Widget, everything is simple and familiar:
1. Add the “Double Spin box” control to the form and rename it to “changeXSpinBox”.
2. Add the “PushButton” control to the form and rename it to “moveByXButton”. Change the text on the button to “Change x”.
3. For "moveByXButton", execute the command "Go to slot" -> clicked.
4. The function should look like this:
void MainWindow::on_moveByXButton_clicked() { double x = 0.0; // ',' '.' , // spinBox double QString spinBoxText = ui->changeXSpinBox->text().replace( QLocale().decimalPoint(), QLatin1Char('.')); double xChangeValue = spinBoxText.toDouble(); for (int i = 0; i <points.size(); i++) { x = points[i].x(); points[i].setX(x + xChangeValue); } curve->setSamples(points); ui->Qwt_Widget->replot(); }
Conclusions: we successfully used the Qt Creator design tools to create a visualizer and its demonstration controls. With the spinBox and button, we can change the x-coordinate of the displayed curve.
In part 4 of the article cycle, we will implement additional ways to increase / decrease graphics, sample points with the mouse, editing tools for displaying graphics and curves, and exporting graphics.
PS I express my great appreciation to Riateche for the valuable comments on articles No. 1 and No. 2, which were taken into account when writing this article.
References:
Sources:
댓글 없음:
댓글 쓰기