通过重写QT中QWidget类中的paintEvent函数,我们就可以做到在widget中进行函数图像的绘制。(我使用的是QCreator的UI设计器)
首先我们需要从QWidget继承一个子类,并重写他的paintEvent
class show_location : public QWidget
{
Q_OBJECT
protected:
void paintEvent(QPaintEvent *);//重写函数,函数定义在源文件中
public:
show_location(QWidget *parent = nullptr);
~show_location(){}
int m_count;
double x;
int axis_x[240];//储存轴的值
double axis_y[240];//储存y轴的值
QTimer* m_Timer;//定时器,用于刷新图像计时
public slots:
void creatData();//得到需要绘制的图像的函数值
private:
Ui::show_location *ui;
};
在绘制时,需要用到QPainter,QPainter在定义时需要“绑定”widget,否则会显示为未激活。
下面是类中函数的定义:
show_location::show_location(QWidget *parent) : QWidget(parent)
{
m_count = 0;
m_Timer = new QTimer(this);
m_Timer->start(125);//计时周期为125ms
connect(m_Timer,SIGNAL(timeout()),this,SLOT(creatData()));125ms刷新一次函数
}
void show_location::creatData()
{
if(m_count<240)//图像x轴为时间,显示范围为0.125*240 = 30s,
{
axis_x[m_count] = m_count;
axis_y[m_count] = 0.5*m_count;//得到的函数数据的大小放在这即可
}
else //30s后让更新x轴各点处大小
{
for(int i = 0;i<240;i++)
{
axis_x[i]+=1;
if(i)
axis_y[i-1] = axis_y[i];
else
axis_y[0] = axis_y[1];
}
axis_y[239] = 120;//得到的力的大小放在这即可
}
m_count++;
update();//update函数可以调用paintEvent函数,进行图像的重绘
}
void show_location::paintEvent(QPaintEvent *)
{
int temp;
QPainter painter(this);//建立QPainter并绑定widget
QPen pen;//生成画笔
QFont font1("宋体",5,QFont::Bold,true);//生成字体
pen.setColor(Qt::gray);
pen.setStyle(Qt::SolidLine);
pen.setWidthF(2);//此函数可定义宽度可精确到小数
painter.setPen(pen);//画笔画布绑定
painter.setFont(font1);字体画布绑定
painter.setViewport(0, 0, width(), height());设置画布视窗大小大小为窗口(widget)大小
painter.setWindow(0, 0, 256, 200); // (-10, 2) (10, -2)都是100倍//设置逻辑坐标范围
painter.fillRect(0, 0, 256, 200, Qt::white);背景颜色
painter.drawLine(QPointF(0, 199), QPointF(256, 199)); // x
painter.drawLine(QPointF(0, 0), QPointF(0, 200)); // y
for(int i = 64;i<240;i+=64)//x轴
{
painter.drawLine(QPointF(i, 200), QPointF(i, 190)); //绘制x轴上的点
if(m_count<240)
temp = 240;
else {
temp = m_count;
}
painter.drawText(QPointF(i-10,185),QString::number(int((temp-240+i)/8))); //绘制文本
}
painter.drawText(QPoint(220,185),QString("t/s"));
for(int i = 150;i>0;i-=50)//y轴
{
painter.drawLine(QPointF(0, i), QPointF(3, i)); //绘制x轴上的点
painter.drawText(QPointF(6,i+10),QString::number(200-i)); //绘制文本
}
painter.drawText(QPoint(5,20),QString("y/cm"));
pen.setColor(Qt::blue);
painter.setPen(pen);
for(int i = 0; i < 240&&i<m_count; i++)
{
if(i == 0)
painter.drawPoint(QPointF(0, 200-axis_y[i]));
else
painter.drawLine(QPointF(i-1, 200-axis_y[i-1]), QPointF(i, 200-axis_y[i]));
}
}
如果窗口内只有一个widget用于显示图像,则可以直接生成实例后,使用成员函数show()来生成新窗口。
如果有其他组件的话,可以在ui设计界面,在widget组件上右键选择提升为,在弹出窗口填入类的名称,以及类的头文件,点击提升即可
最后效果如图所示: