【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
绘图是qt很基础的一个功能。通常,我们进行qt绘图的时候,一般会先创建一个qt view,这个相当于视图。接着创建一个场景scene,场景和视图是一对多的关系,比如相同的场景可以正着看、反着看、旋转着看等等,这样就会有多个view。有了场景之后呢,我们就可以在上面添加物体了,这个物体就是各种各样形状的内容。今天,我们借着键盘绘图的需求,看下qt下面view-scene-item是怎么一个情况。
1、首先创建一个widget工程
widget工程是我们开发的一个基础,虽然里面的代码基本不用,但是需要这样的一个基本框架。
2、接着创建绘制的物体
绘制的物体一般都要继承QGraphicsPolygonItem,后期这个类就会被添加到scene当中。因为本次的需求是响应各种按键功能,所以还要重写一下keyPressEvent函数。
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsPolygonItem>
#include <QKeyEvent>class TriangleItem : public QGraphicsPolygonItem
{
public:TriangleItem(QGraphicsItem* parent = nullptr) : QGraphicsPolygonItem(parent){QPolygonF triangle;triangle << QPointF(0, -50) << QPointF(25, 25) << QPointF(-25, 25);setPolygon(triangle);}~TriangleItem(){}void keyPressEvent(QKeyEvent* event) override{QPointF currentPosition = pos();switch (event->key()){case Qt::Key_Up:currentPosition.setY(currentPosition.y() - 10);break;case Qt::Key_Down:currentPosition.setY(currentPosition.y() + 10);break;case Qt::Key_Left:currentPosition.setX(currentPosition.x() - 10);break;case Qt::Key_Right:currentPosition.setX(currentPosition.x() + 10);break;default:break;}setPos(currentPosition);}
};
3、重写QGraphicsView类
当view中接收到按键消息之后,第一个处理的,一般是view里面的keyPressEvent函数。我们目前的处理方法就是,首先在view里面识别到按键事件,然后判断当前按键是不是TriangleItem,如果是,就继续调用对应类的keyPressEvent函数。
class GraphicsView : public QGraphicsView
{
public:GraphicsView(QGraphicsScene* scene, QWidget* parent = nullptr) : QGraphicsView(scene, parent) {}~GraphicsView(){}protected:void keyPressEvent(QKeyEvent* event) override{QGraphicsScene* graphicsScene = scene();if (graphicsScene){QList<QGraphicsItem*> items = graphicsScene->items();for (QGraphicsItem* item : items){if (TriangleItem* triangle = dynamic_cast<TriangleItem*>(item)){triangle->keyPressEvent(event);return;}}}QGraphicsView::keyPressEvent(event);}
};
4、构建基本的view-scene-item流程
qt下面的构建方法还是比较清晰的,首先是创建一个scene变量,用scene变量创建一个view变量。简单设置好大小之后,创建一个triangle的item,保存在scene场景中。最后view简单设置了属性之后,直接show出来。基本逻辑就是这样。
另外需要注意的是,这里的view,就可以看成一种普通的控件。它和标准的ListView、TreeView、TableView等等,都是一样的。本身也可以集成到main window下面。
int main(int argc, char *argv[])
{QApplication app(argc, argv);QGraphicsScene scene;GraphicsView view(&scene);view.resize(600, 450);TriangleItem *triangle = new TriangleItem();scene.addItem(triangle);view.setRenderHint(QPainter::Antialiasing);view.setRenderHint(QPainter::SmoothPixmapTransform);view.show();return app.exec();
}
5、测试和验证
代码编写好了之后,简易编译测试下。这里面包括显示是否正确,按键是否有反应,以及对应函数设置断点后是否真的会断注之类的。