QT c++ 书中plotter 的简化版 利于初学者理解

在学习C++ GUI QT4一书中的绘图功能时,给的例子还是太复杂,为了搞清楚最基本的关系,将例子的类函数和不重要的事件删除,写成简单版本的plotter。方便初学者理解。

首先是plotter.pro文件,QT4还是沿用QtGUI模块,在QT5要换成QtWidgets。

TEMPLATE      = app
HEADERS       = plotter.h
SOURCES       = main.cpp \
                plotter.cpp

其次是main.cpp文件,很简单,就是将plotter进行show一下即可,同时规定窗口为400*400大小。

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

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Plotter plotter;
    plotter.resize(400,400);
    plotter.show();
    return app.exec();
}

其次看plotter类的头文件,这里规定了继承与widget的派生类,重点要实现其中的paintevent函数。

#ifndef PLOTTER_H
#define PLOTTER_H
#include <QWidget>
class Plotter : public QWidget
{
    Q_OBJECT
public:
    Plotter(QWidget *parent = 0);
protected:
    void paintEvent(QPaintEvent *event);
private:
    enum { Margin = 50 };
};
#endif

枚举类型matgin规定了距离窗体的距离大小,设定为50.

最后看一下plotter类的实现文件。

#include <QtGui>
#include <cmath>
#include "plotter.h"

Plotter::Plotter(QWidget *parent): QWidget(parent){}

void Plotter::paintEvent(QPaintEvent * /* event */)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    QRect rect(Margin, Margin, width() - 2 * Margin, height() - 2 * Margin);
    if (!rect.isValid()) {return;} //绘制外框 随窗口变化
    for (int i = 0; i < 5; ++i)
    {
        for (int j = 0; j < 5; ++j)
        {   //绘制网格
            int x1 = rect.left()   + (i * (rect.width()  - 1)/ 5+1);
            int y1 = rect.bottom() - (j * (rect.height() - 1)/ 5+1);
            int x2 = rect.left()   + ((i+1) * (rect.width()  - 1)/ 5-1);
            int y2 = rect.bottom() - ((j+1) * (rect.height() - 1)/ 5-1);
            painter.fillRect(QRect(x1,y1,x2-x1,y2-y1),Qt::yellow);
        }
    }

    for (int i = 0; i <= 5; ++i)
    {   //绘制垂向网格和x坐标
        int x = rect.left() + (i * (rect.width() - 1)/ 5);
        double label = i * 20;
        painter.drawLine(x, rect.top(), x, rect.bottom());
        painter.drawLine(x, rect.bottom(), x, rect.bottom() + 5);
        painter.drawText(x - Margin, rect.bottom() + 5, 100, 20,
                          Qt::AlignHCenter | Qt::AlignTop, QString::number(label));
    }
    for (int j = 0; j <= 5; ++j)
    {   //绘制横向网格和y坐标
        int y = rect.bottom() - (j * (rect.height() - 1)/ 5);
        double label = j * 20;
        painter.drawLine(rect.left(), y, rect.right(), y);
        painter.drawLine(rect.left() - 5, y, rect.left(), y);
        painter.drawText(rect.left()-Margin, y-10, Margin-5, 20,
                          Qt::AlignRight | Qt::AlignVCenter, QString::number(label));
    }

    QPolygonF line(11);
    for (int j = 0; j < 11; ++j)
    {   //绘制曲线
        int x1 = rect.left()   + (j * (rect.width()  - 1)/ 10);
        int y1 = rect.bottom() - (j * (rect.height() - 1)/ 10);
        line[j] = QPointF(x1,y1);
    }
    painter.drawPolyline(line);
}



其实还可以写的再简单点,里面内容主要是绘制了矩形,线条,文字,所以比较多,每个循环都可以删除掉,程序仍然能执行。

这里的重点是绘制形状都沿用了窗体的尺寸,因此可以在拖动窗口时实时改变形状的大小。

原文使用resize函数来实现,其实没有必要,只要实现paintevent就能办到。

书中还有一个iconeditter的例子,就不能实现随窗口大小改变而一起改变的效果,主要是没有引进窗口长宽的概念。

这是程序的显示效果,可以随意改变窗口大小,图像也会跟着改变。

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Intimes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值