首先看程序运行后的效果:
可以改变shape,Color,Background,点击Save As将图片保存成SVG格式文件到任意位置。
该例子包括了两个主要的类:Window和DisplayWidget
Window类包含了一个Qt Designer UI,用它来开发了主界面的UI,布局,信号槽以及绑定关系。
UI文件里头displayWidget是来自QWidget的提升:DisplayWidget
DisplayWidget实现所有的painting工作。它提供了两种形状:House,Car;三种背景:Sky,Trees,Road;为形状提供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]