Qt波形图


头文件:

#ifndef TEST_H
#define TEST_H

#include <QtGui>
#include "ui_test.h"

class testView : public QGraphicsView
{
	Q_OBJECT

public:
	testView(QWidget* parent = NULL);
	~testView();

private slots:
	void slot_update();
};

class testScene : public QGraphicsScene
{
	Q_OBJECT

public:
	testScene();
	~testScene();

private slots:
	void slot_update();

protected:
	virtual void drawBackground(QPainter *painter, const QRectF &rect);
	virtual void drawForeground(QPainter *painter, const QRectF &rect);

private:
	QPainterPath mPath;
};

class test : public QWidget
{
	Q_OBJECT

public:
	test();
	~test();

protected:
	void paintEvent ( QPaintEvent * event );

private:
	Ui::testClass ui;
};

#endif // TEST_H

源文件:

#include "test.h"
#include <QCompleter>
#include <QDebug>
#include <QTime>
#include <QTest>

using   namespace   std;

test::test()
{
	ui.setupUi(this);

	// View && Scene
	testView* tView = new testView(this);
	ui.verticalLayout->addWidget(tView);

	testScene* scene = new testScene();

	connect(ui.btn_update, SIGNAL(clicked()), scene, SLOT(slot_update()));
	connect(ui.btn_update, SIGNAL(clicked()), tView, SLOT(slot_update()));

	tView->setScene(scene);
}

test::~test()
{

}

void test::paintEvent( QPaintEvent * event )
{
	//qDebug()<<"paintEvenet()";

	//QPainter painter(this);
	//painter.drawPath(mPath);

	QWidget::paintEvent(event);
}

testScene::testScene()
{
	setSceneRect(QRectF(0,0,2000,600));

	qsrand(QTime::currentTime().msec());

	mPath.moveTo(0,0);
	for(int i=0; i<1500; i=i+20)
	{
		int x = i;
		int y = qrand()%500;
		mPath.lineTo(QPointF(x,y));
	}
}

testScene::~testScene()
{

}

void testScene::drawBackground( QPainter *painter, const QRectF &rect )
{
	qDebug()<<"drawBackground";

	painter->save();

	painter->setBrush(Qt::darkCyan);
	painter->drawRect(rect);

	painter->setPen(Qt::yellow);
	const double w = sceneRect().width();
	const double h = sceneRect().height();
	for(int i=0; i<h; i+=100)
	{
		QLineF line(QPointF(0,i),QPointF(w,i));
		painter->drawLine(line);
	}

	painter->restore();
}

void testScene::drawForeground( QPainter *painter, const QRectF &rect )
{
	qDebug()<<"drawForeground";

	painter->save();

	painter->setPen(QPen(Qt::red,5));
	painter->drawPath(mPath);
	
	painter->restore();
}

void testScene::slot_update()
{
	qsrand(QTime::currentTime().msec());

	mPath = QPainterPath();
	mPath.moveTo(0,0);
	for(int i=0; i<1500; i=i+20)
	{
		int x = i;
		int y = qrand()%500;
		mPath.lineTo(QPointF(x,y));
	}

	double w = sceneRect().width();
	double h = sceneRect().height();
	double step = w/10;

	for(int i=0; i<w; i+=step)
	{
		update (i,0,step,h);
		//QTest::qSleep(1000);
		qDebug()<<"scene update()"<<i;
	}
}

void testView::slot_update()
{
	//double w = rect().width();
	//double h = rect().height();
	//double step = w/10;

	//for(int i=0; i<w; i+=step)
	//{
	//	update (i,0,step,h);
	//	//QTest::qSleep(1000);
	//	qDebug()<<"view update()"<<i;
	//}
}

testView::testView( QWidget* parent /*= NULL*/ )
	: QGraphicsView(parent)
{
	centerOn(0,0);

	setCacheMode(QGraphicsView::CacheBackground);
	setRenderHint(QPainter::Antialiasing, true);
	//setRenderHint(QPainter::TextAntialiasing, true);
	setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
}

testView::~testView()
{

}


### 使用 Qt 绘制波形图的方法 以下是通过两种方式实现波形图绘制的示例代码:一种基于 `QWidget` 和 `QPainter` 的手动绘制方法,另一种利用 `QChart` 实现更复杂的实时波形图。 #### 方法一:使用 QWidget 和 QPainter 手动绘制波形图 此方法适用于简单的静态波形图绘制。以下是一个完整的示例: ```cpp #include <QWidget> #include <QPainter> class WaveformWidget : public QWidget { protected: void paintEvent(QPaintEvent *event) override { Q_UNUSED(event); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); // 抗锯齿效果 // 设置画笔颜色和宽度 painter.setPen(QPen(Qt::blue, 2)); // 波形数据 (x,y 坐标) QVector<QPointF> points; for (int i = 0; i < width(); ++i) { qreal y = qSin((qreal)i / 50.0) * height() / 4 + height() / 2; // 正弦曲线模拟 points.append(QPointF(i, y)); } // 连接点并绘制线条 if (!points.isEmpty()) { painter.drawPolyline(points.data(), points.size()); } } }; // 主窗口设置 #include <QApplication> #include <QVBoxLayout> int main(int argc, char **argv) { QApplication app(argc, argv); QWidget window; QVBoxLayout layout(&window); WaveformWidget waveformWidget; layout.addWidget(&waveformWidget); window.resize(800, 600); window.show(); return app.exec(); } ``` 上述代码定义了一个名为 `WaveformWidget` 的类[^1],该类继承自 `QWidget` 并重写了其 `paintEvent` 函数以完成波形图的手动绘制逻辑。 --- #### 方法二:使用 QChart 绘制动态实时波形图 如果需要支持动态更新或复杂交互,则可以借助 `QChart` 类库来简化开发过程。下面展示了一种基本的实现实时波形图的方式: ```cpp #include <QApplication> #include <QChartView> #include <QLineSeries> #include <QValueAxis> #include <QtCharts/QChart> #include <QTimer> using namespace QtCharts; class RealTimeWaveform : public QMainWindow { public: RealTimeWaveform(QWidget *parent = nullptr) : QMainWindow(parent), m_series(new QLineSeries(this)) { // 创建图表对象 QChart *chart = new QChart(); chart->addSeries(m_series); chart->setTitle("Real-Time Waveform"); chart->createDefaultAxes(); // 配置 X 轴范围 QValueAxis *axisX = static_cast<QValueAxis *>(chart->axes(Qt::Horizontal).at(0)); axisX->setRange(0, MAX_POINTS); // 配置 Y 轴范围 QValueAxis *axisY = static_cast<QValueAxis *>(chart->axes(Qt::Vertical).at(0)); axisY->setRange(-1, 1); // 添加到视图中 QChartView *chartView = new QChartView(chart); setCentralWidget(chartView); // 定义定时器刷新机制 QTimer *timer = new QTimer(this); connect(timer, &QTimer::timeout, this, [&]() { qreal x = m_series->count() > 0 ? m_series->at(m_series->count() - 1).x() + 1 : 0; qreal y = qSin(x / 50.0); // 模拟正弦信号 if (m_series->count() >= MAX_POINTS) { // 移除最旧的一个点 m_series->remove(0); } (*m_series) << QPointF(x, y); // 添加新点 }); timer->start(50); // 每隔 50ms 更新一次 } private: QLineSeries *m_series; const int MAX_POINTS = 200; // 最大显示点数 }; int main(int argc, char **argv) { QApplication app(argc, argv); RealTimeWaveform window; window.resize(800, 600); window.show(); return app.exec(); } #include "main.moc" ``` 在此示例中,我们使用了 `QChart` 来管理图表,并通过 `QLineSeries` 存储波形数据[^2]。为了实现动态更新的效果,还引入了 `QTimer` 对象定期向序列中追加新的数据点。 --- ### 总结 以上分别展示了如何通过传统绘图技术 (`QWidget`, `QPainter`) 或现代图表组件 (`QChart`) 在 Qt绘制波形图的具体方法。前者适合简单场景下的快速原型设计;后者则更适合处理更加复杂的动态需求。
评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值