【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱: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、测试和验证
代码编写好了之后,简易编译测试下。这里面包括显示是否正确,按键是否有反应,以及对应函数设置断点后是否真的会断注之类的。