淘先锋技术网

首页 1 2 3 4 5 6 7

首先看程序运行后的效果:

可以改变shapeColorBackground,点击Save As将图片保存成SVG格式文件到任意位置。

该例子包括了两个主要的类:WindowDisplayWidget

Window类包含了一个Qt Designer UI,用它来开发了主界面的UI,布局,信号槽以及绑定关系。

UI文件里头displayWidget是来自QWidget的提升:DisplayWidget

 

DisplayWidget实现所有的painting工作。它提供了两种形状:HouseCar;三种背景:SkyTreesRoad;为形状提供QColor,它将由Window类对象的updateColor槽提供QColorDialog来选择颜色。

 UI的信号槽:

 

//! [DisplayWidget class definition]
class DisplayWidget : public QWidget
{
    Q_OBJECT

public:
    enum Shape { House = 0, Car = 1 };
    enum Background { Sky = 0, Trees = 1, Road = 2 };

    DisplayWidget(QWidget *parent = 0);
    QColor color() const;
    void paint(QPainter &painter);

public slots:
    void setBackground(Background background);
    void setColor(const QColor &color);
    void setShape(Shape shape);

protected:
    void paintEvent(QPaintEvent *event);

private:
    Background background;
    QColor shapeColor;
    Shape shape;
    QHash<Shape,QPainterPath> shapeMap;
    QPainterPath moon;
    QPainterPath tree;
};
//! [DisplayWidget class definition]


DisplayWidget::DisplayWidget(QWidget *parent)
    : QWidget(parent)
{
    QPainterPath car;
    QPainterPath house;

    // 将shap.dat文件QPainterPath对象赋值
    QFile file(":resources/shapes.dat");
    file.open(QFile::ReadOnly);
    QDataStream stream(&file);
    stream >> car >> house >> tree >> moon;
    file.close();

    shapeMap[Car] = car;
    shapeMap[House] = house;

    background = Sky;  // 初始化对象
    shapeColor = Qt::darkYellow;
    shape = House;
}

//! [paint event]
void DisplayWidget::paintEvent(QPaintEvent * /* event */)
{
    QPainter painter;  // 将DisplayWidget绘制出来
    painter.begin(this);
    painter.setRenderHint(QPainter::Antialiasing);
    paint(painter);
    painter.end();
}
//! [paint event]

//! [paint function]
void DisplayWidget::paint(QPainter &painter)
{
//![paint picture]
    // 将Widget的图片画出
    painter.setClipRect(QRect(0, 0, 200, 200));
    painter.setPen(Qt::NoPen);

    switch (background) {  // 背景
    case Sky:
    default:
        painter.fillRect(QRect(0, 0, 200, 200), Qt::darkBlue);
        painter.translate(145, 10);
        painter.setBrush(Qt::white);
        painter.drawPath(moon);
        painter.translate(-145, -10);
        break;
    case Trees:
    {
        painter.fillRect(QRect(0, 0, 200, 200), Qt::darkGreen);
        painter.setBrush(Qt::green);
        painter.setPen(Qt::black);
        for (int y = -55, row = 0; y < 200; y += 50, ++row) {
            int xs;
            if (row == 2 || row == 3)
                xs = 150;
            else
                xs = 50;
            for (int x = 0; x < 200; x += xs) {
                painter.save();
                painter.translate(x, y);
                painter.drawPath(tree);
                painter.restore();
            }
        }
        break;
    }
    case Road:
        painter.fillRect(QRect(0, 0, 200, 200), Qt::gray);
        painter.setPen(QPen(Qt::white, 4, Qt::DashLine));
        painter.drawLine(QLine(0, 35, 200, 35));
        painter.drawLine(QLine(0, 165, 200, 165));
        break;
    }

    painter.setBrush(shapeColor); // 绘制shape
    painter.setPen(Qt::black);
    painter.translate(100, 100);
    painter.drawPath(shapeMap[shape]);
//![paint picture]
}
//! [paint function]

// 一下都是为Widget类提供的接口
QColor DisplayWidget::color() const
{
    return shapeColor;
}

void DisplayWidget::setBackground(Background background)
{
    this->background = background;
    update();  // 更新DisplayWidget
}

void DisplayWidget::setColor(const QColor &color)
{
    this->shapeColor = color;
    update();
}

void DisplayWidget::setShape(Shape shape)
{
    this->shape = shape;
    update();
}

 

Window类的定义和实现:

 

class Window : public QWidget, private Ui::Window
{
    Q_OBJECT

public:
    Window(QWidget *parent = 0);

public slots:
    void saveSvg();
    void updateBackground(int background);
    void updateColor();
    void updateShape(int shape);

private:
    QString path;   // SAVE AS路径
};


Window::Window(QWidget *parent)
    : QWidget(parent)
{
    setupUi(this);

#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5)
    this->layout()->setSizeConstraint(QLayout::SetDefaultConstraint);
#endif
}

void Window::updateBackground(int background)
{
    displayWidget->setBackground(DisplayWidget::Background(background));
}

void Window::updateColor()
{
    QColor color = QColorDialog::getColor(displayWidget->color());
    if (color.isValid())
        displayWidget->setColor(color);
}

void Window::updateShape(int shape)
{
    displayWidget->setShape(DisplayWidget::Shape(shape));
}

//! [save SVG]
void Window::saveSvg()  // 保存为svg文件
{
    QString newPath = QFileDialog::getSaveFileName(this, tr("Save SVG"),
        path, tr("SVG files (*.svg)"));  // 弹出Save as Dialog

    if (newPath.isEmpty())
        return;

    path = newPath;     // 路径

//![configure SVG generator]
    QSvgGenerator generator;   // qt svg的painting device对象
    generator.setFileName(path);
    generator.setSize(QSize(200, 200));
    generator.setViewBox(QRect(0, 0, 200, 200));
    generator.setTitle(tr("SVG Generator Example Drawing"));
    generator.setDescription(tr("An SVG drawing created by the SVG Generator "
                                "Example provided with Qt."));
//![configure SVG generator]
//![begin painting]
    QPainter painter;
    painter.begin(&generator);
//![begin painting]
    displayWidget->paint(painter);
//![end painting]
    painter.end();
//![end painting]
}
//! [save SVG]