Как строить графики с помощью Qt5? Qwt3D не обновлялся с 2007 года и вроде для Qt4. Находил решение от частных лиц. Хочется что то официальное.
Если нет решения, может хотя бы такое кто поможет реализовать:
Ответ про 2D графики и gnuplot.
Я написал простенькое приложение с одной кнопкой (пример внизу). Нажимаете кнопку - выбираете файл с графиком для gnuplot (пример ниже), после этого запускается gnuplot с помощью QProcess, и когда QProcess рапортует об остановке процесса, то пытаюсь загрузить результат Output.png в QPixmap и отобразить в окне. Всё это дело работает только если есть gnuplot в переменной PATH, иначе нужно будет прописать полный путь до программы gnuplot.
proof:
Проект на github.
Пример самого графика (взят из демо gnuplot под Windows и немного отредактирован, чтобы график рендерился в картинку Output.png)
airfoil.plt:
#
# $Id: airfoil.dem,v 1.9 2004/09/28 06:06:10 sfeam Exp $
#
# This demo shows how to use bezier splines to define NACA four
# series airfoils and complex variables to define Joukowski
# Airfoils. It will be expanded after overplotting in implemented
# to plot Coefficient of Pressure as well.
# Alex Woo, Dec. 1992
#
# The definitions below follows: "Bezier presentation of airfoils",
# by Wolfgang Boehm, Computer Aided Geometric Design 4 (1987) pp 17-22.
#
# Gershon Elber, Nov. 1992
#
# m = percent camber
# p = percent chord with maximum camber
mm = 0.6
# NACA6xxx
thick = 0.09
# nine percent NACAxx09
pp = 0.4
# NACAx4xx
# Combined this implies NACA6409 airfoil
#
# Airfoil thickness function.
#
set xlabel "NACA6409 -- 9% thick, 40% max camber, 6% camber"
x0 = 0.0
y0 = 0.0
x1 = 0.0
y1 = 0.18556
x2 = 0.03571
y2 = 0.34863
x3 = 0.10714
y3 = 0.48919
x4 = 0.21429
y4 = 0.58214
x5 = 0.35714
y5 = 0.55724
x6 = 0.53571
y6 = 0.44992
x7 = 0.75000
y7 = 0.30281
x8 = 1.00000
y8 = 0.01050
#
# Directly defining the order 8 Bezier basis function for a faster evaluation.
#
bez_d4_i0(x) = (1 - x)**4
bez_d4_i1(x) = 4 * (1 - x)**3 * x
bez_d4_i2(x) = 6 * (1 - x)**2 * x**2
bez_d4_i3(x) = 4 * (1 - x)**1 * x**3
bez_d4_i4(x) = x**4
bez_d8_i0(x) = (1 - x)**8
bez_d8_i1(x) = 8 * (1 - x)**7 * x
bez_d8_i2(x) = 28 * (1 - x)**6 * x**2
bez_d8_i3(x) = 56 * (1 - x)**5 * x**3
bez_d8_i4(x) = 70 * (1 - x)**4 * x**4
bez_d8_i5(x) = 56 * (1 - x)**3 * x**5
bez_d8_i6(x) = 28 * (1 - x)**2 * x**6
bez_d8_i7(x) = 8 * (1 - x) * x**7
bez_d8_i8(x) = x**8
m0 = 0.0
m1 = 0.1
m2 = 0.1
m3 = 0.1
m4 = 0.0
mean_y(t) = m0 * mm * bez_d4_i0(t) + \
m1 * mm * bez_d4_i1(t) + \
m2 * mm * bez_d4_i2(t) + \
m3 * mm * bez_d4_i3(t) + \
m4 * mm * bez_d4_i4(t)
p0 = 0.0
p1 = pp / 2
p2 = pp
p3 = (pp + 1) / 2
p4 = 1.0
mean_x(t) = p0 * bez_d4_i0(t) + \
p1 * bez_d4_i1(t) + \
p2 * bez_d4_i2(t) + \
p3 * bez_d4_i3(t) + \
p4 * bez_d4_i4(t)
z_x(x) = x0 * bez_d8_i0(x) + x1 * bez_d8_i1(x) + x2 * bez_d8_i2(x) + \
x3 * bez_d8_i3(x) + x4 * bez_d8_i4(x) + x5 * bez_d8_i5(x) + \
x6 * bez_d8_i6(x) + x7 * bez_d8_i7(x) + x8 * bez_d8_i8(x)
z_y(x, tk) = \
y0 * tk * bez_d8_i0(x) + y1 * tk * bez_d8_i1(x) + y2 * tk * bez_d8_i2(x) + \
y3 * tk * bez_d8_i3(x) + y4 * tk * bez_d8_i4(x) + y5 * tk * bez_d8_i5(x) + \
y6 * tk * bez_d8_i6(x) + y7 * tk * bez_d8_i7(x) + y8 * tk * bez_d8_i8(x)
#
# Given t value between zero and one, the airfoild curve is defined as
#
# c(t) = mean(t1(t)) +/- z(t2(t)) n(t1(t)),
#
# where n is the unit normal to the mean line. See the above paper for more.
#
# Unfortunately, the parametrization of c(t) is not the same for mean(t1)
# and z(t2). The mean line (and its normal) can assume linear function t1 = t,
# -1
# but the thickness z_y is, in fact, a function of z_x (t). Since it is
# not obvious how to compute this inverse function analytically, we instead
# replace t in c(t) equation above by z_x(t) to get:
#
# c(z_x(t)) = mean(z_x(t)) +/- z(t) n(z_x(t)),
#
# and compute and display this instead. Note we also ignore n(t) and assumes
# n(t) is constant in the y direction,
#
airfoil_y1(t, thick) = mean_y(z_x(t)) + z_y(t, thick)
airfoil_y2(t, thick) = mean_y(z_x(t)) - z_y(t, thick)
airfoil_y(t) = mean_y(z_x(t))
airfoil_x(t) = mean_x(z_x(t))
unset grid
unset zeroaxis
set terminal png
set output 'Output.png'
set parametric
set xrange [-0.1:1.1]
set yrange [-0.1:.7]
set trange [ 0.0:1.0]
set title "NACA6409 Airfoil"
plot airfoil_x(t), airfoil_y(t) title "mean line" w l lt 2, \
airfoil_x(t), airfoil_y1(t, thick) title "upper surface" w l lt 1, \
airfoil_x(t), airfoil_y2(t, thick) title "lower surface" w l lt 1
*.pro файл:
#-------------------------------------------------
#
# Project created by QtCreator 2018-07-14T12:09:28
#
#-------------------------------------------------
QT += core gui widgets
TARGET = UseGnuPlotFromQt
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += c++11
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QProcess>
#include <QGraphicsScene>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_m_selectFile_clicked();
void onGnuplotFinished(int, QProcess::ExitStatus);
private:
Ui::MainWindow *ui;
QProcess* m_gnuplotProc;
QGraphicsScene* m_scene;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QStandardPaths>
#include <QDebug>
#include <QString>
#include <QProcess>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
m_gnuplotProc{nullptr},
m_scene{nullptr}
{
ui->setupUi(this);
m_gnuplotProc = new QProcess(this);
m_gnuplotProc->connect(m_gnuplotProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(onGnuplotFinished(int, QProcess::ExitStatus)));
m_scene = new QGraphicsScene(ui->centralWidget);
ui->m_imageView->setScene(m_scene);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_m_selectFile_clicked()
{
QString caption{"Select file for gnuplot"};
QString file = QFileDialog::getOpenFileName(this->ui->centralWidget, caption, QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation).first(),{"Plot (*.plt);;All Files (*.*)"});
QStringList args = {file};
m_gnuplotProc->start({"gnuplot"}, args);
}
void MainWindow::onGnuplotFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
qDebug() << "gnuplot finished with exit code:" << exitCode << "and exit status:" << exitStatus;
QPixmap pixmap;
if (pixmap.load("Output.png")){
m_scene->addPixmap(pixmap);
}else{
qDebug() << "can not load Output.png";
}
}
mainwindow.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGraphicsView" name="m_imageView"/>
</item>
<item>
<widget class="QPushButton" name="m_selectFile">
<property name="text">
<string>Выберите файл с графиком</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>20</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости