寫在前面:因爲Qt的GUI界面座標和數學座標系不同,所在顯示時要進行座標轉換,GUI界面是以左上角爲原點座標的
頭文件:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
private slots:
int OnSettingsChanged();
};
#endif // MAINWINDOW_H
sinwidget.h(繼承於QWidget)#ifndef SINWIDGET_H
#define SINWIDGET_H
#include <QWidget>
#include <QPainter>
#include <math.h>
#include <QPoint>
#include <QPaintEvent>
class SinWidget : public QWidget
{
Q_OBJECT
public:
explicit SinWidget(QWidget *parent = 0);
public:
void Adjust(int period, int grain, int radius);
QPoint origin(); // 座標原點位置
QPoint toCoord(QPoint p); // 將GUI窗口的點(x,y)轉換成座標系統裏的點
QPoint fromCoord(QPoint p); // 將座標系內的(x,y)轉成GUI的座標
signals:
public slots:
private:
virtual void paintEvent(QPaintEvent *event );
int m_period, m_grain, m_radius;
};
#endif // SINWIDGET_H
源文件:
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.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->m_ctlPeriod->setValue(50);
ui->m_ctlGrain->setValue(1);
ui->m_ctlRadius->setValue(50);
connect(ui->m_ctlRadius, SIGNAL(valueChanged(int)),
this, SLOT(OnSettingsChanged()));
connect(ui->m_ctlGrain, SIGNAL(valueChanged(int)),
this, SLOT(OnSettingsChanged()));
connect(ui->m_ctlPeriod, SIGNAL(valueChanged(int)),
this, SLOT(OnSettingsChanged()));
OnSettingsChanged();
}
MainWindow::~MainWindow()
{
delete ui;
}
int MainWindow::OnSettingsChanged()
{
ui->frame->Adjust(ui->m_ctlPeriod->value(),
ui->m_ctlGrain->value(),
ui->m_ctlRadius->value());
return 0;
}
sinwidget.cpp
#include "sinwidget.h"
SinWidget::SinWidget(QWidget *parent) :
QWidget(parent)
{
m_period = 20; //週期
m_grain = 1; //粒度
m_radius = 10; // 振幅
}
void SinWidget::Adjust(int period, int grain, int radius)
{
m_period = period;
m_grain = grain;
m_radius = radius;
update(); // 更新重繪
}
QPoint SinWidget::origin()
{
QRect r = this->rect();
return r.center();
}
// 將GUI窗口的點(x,y)轉換成數學座標系統裏的點
QPoint SinWidget::toCoord(QPoint p)
{
// 圓心
QPoint o = this->origin();
QPoint result = p - o;
result.setY(0 - result.y()); // y座標反轉
return result;
}
// 將數學座標系內的(x,y)轉成GUI的座標
QPoint SinWidget::fromCoord(QPoint p)
{
// 圓心
QPoint o = this->origin();
p.setY(0 - p.y()); // y座標反轉
return p + o;
}
void SinWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
int width = this->width();
int height = this->height();
QRect rect(0,0, width, height);
// 設置背景爲黑色
painter.setBrush(QBrush(QColor(0x00,0x00, 0x00)));
painter.drawRect(rect);
painter.setPen(QPen(QColor(0, 255, 0))); // 設置線條爲綠色
QPoint o = origin();
painter.drawLine(QPoint(0, o.y()), QPoint(width, o.y())); // x軸
painter.drawLine(QPoint(o.x(), 0), QPoint(o.x(), height));// y軸
// 正弦曲線: 從座標原點,向左、向右伸展
QPoint p1(0,0);
for(int x=0; x<width/2; x+=m_grain)
{
// y=sin(x)
double angle = (double) x / m_period * 2 * 3.1415926;
double y = m_radius * sin(angle);
QPoint p2(x, y);
// 右側
painter.drawLine(fromCoord(p1), fromCoord(p2));
// 左側
QPoint base(0,0);
painter.drawLine(fromCoord(base-p1), fromCoord(base-p2));
p1 = p2;
}
}
設計界面:(用到了Spin Box 、Label、Widget、部件)注:Widget部件爲提升的自定義部件,即如下圖;
效果圖: