https://blog.csdn.net/elf001/article/details/8978528windows
一、知识点:函数
/* Item则是具体要显示的东西。最基本的Qt类就是QGraphicsItem,通常若是要显示自定义的形状一般的
* 作法是继承自QGraphicsItem,而后去实现它的两个纯虚函数boundingRect和paint
* virtual QRectF boundingRect () const = 0
* virtual void paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ) = 0
* boundingRect就是返回该Item的包围盒,用于Graphics内部的碰撞检测以及选取等计算。paint则是用于Item的重绘。
*/this
二、实现一个item类:spa
2.一、Sation.h.net
#ifndef SATION_H #define SATION_H #include <QGraphicsItem> /*新实现一个sation类,这个类能够在scene中用,也能够在mainwindow中用*/ class Sation : public QGraphicsItem { public: Sation(qreal, qreal); void paint(QPainter*, // // paint虚函数:绘制图标 const QStyleOptionGraphicsItem*, QWidget* ); QRectF boundingRect() const{ // boundingRect虚函数:定义每一个图标对应的外部边框 return QRectF(-6.5, -13, 13, 18);//返回一个矩形:比咱们要画的图标稍大 } }; #endif // SATION_H
2.二、sation.cpp3d
#include "sation.h" #include <QPainter> Sation::Sation(qreal x, qreal y):QGraphicsItem() { setPos(x, y); } //构造函数里咱们根据x和y传递的参数设置坐标。在paint函数绘制咱们的电台图标。 void Sation::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { //绘制电台图标,必须小于边框矩形 painter->setRenderHint( QPainter::Antialiasing ); painter->setPen( QPen( Qt::black, 2 ) ); painter->drawRect( -4, -3, 8, 7 ); painter->drawLine( 0, -4, 0, -11 ); painter->drawLine( -5, -11, 0, -6 ); painter->drawLine( +5, -11, 0, -6 ); }
三、在场景类中:code
3.一、scene.hblog
#ifndef SCENE_H #define SCENE_H class QGraphicsSceneMouseEvent; #include <QGraphicsScene> #include "sation.h" class Scene : public QGraphicsScene { Q_OBJECT public: Scene( ); // constructor signals: void message( QString ); // 文本消息信号 protected: void mousePressEvent( QGraphicsSceneMouseEvent* ); // 接收鼠标按下事件 }; #endif // SCENE_H
3.二、scene.cpp继承
#include "scene.h" #include <QGraphicsSceneMouseEvent> Scene::Scene( ) : QGraphicsScene() { addLine( 0, 0, 0, 1, QPen(Qt::transparent, 1) ); /*在构造函数里咱们须要在(0,0)处添加一个不可见的项做为场景的初始锚。 * 如里没有这样作,Qt默认会把用户添加第一个电台做为左上角定位的锚, * 后面添加的电台位置并非用户所想的。*/ } void Scene::mousePressEvent( QGraphicsSceneMouseEvent* event ) { // 判断用户是否按下鼠标左键 if ( event->button() != Qt::LeftButton ) return; // 发送信息信号 qreal x = event->scenePos().x(); qreal y = event->scenePos().y(); addItem(new Sation(x, y)); // 在用户点击场景的位置新建一个电台 emit message( QString("Clicked at %1,%2").arg(x).arg(y) ); }
这里是在scene中的鼠标点击位置的x,y用来构造一个sation,也就是将此时左键鼠标点击的x,y做为一个传参初始化一个item,做为sation的的做图坐标原点,画矩形和线事件
三、mainwindow中:设置view管理scene
3.一、mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "scene.h" class Scene; class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); ~MainWindow(); private: Scene* m_scene; public slots: //添加槽方法的定义 void showMessage( QString ); // 在状态栏上显示消息 }; #endif // MAINWINDOW_H
3.二、mainwindows.cpp中
#include "mainwindow.h" #include <QMenuBar> #include <QStatusBar> #include <QGraphicsView> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { menuBar()->addMenu( "&File" ); menuBar()->addMenu( "&Edit" ); menuBar()->addMenu( "&View" ); menuBar()->addMenu( "&Simulate" ); menuBar()->addMenu( "&Help" ); statusBar()->showMessage("QSimulate has started"); // 建立场景和显示场景的中央视图部件 m_scene = new Scene(); //View是视图,负责显示;Scene是文档,负责存储数据。因此从这个角度出发,咱们能够这样认为,一个Scene能够关联到多个View,就比如一份数据能够有多个视图去查看它同样。 QGraphicsView* view = new QGraphicsView( m_scene ); //QGraphicsScene是一个视图,它不可以单独存在,必须关联到至少一个QGraphicsView view->setAlignment( Qt::AlignLeft | Qt::AlignTop ); view->setFrameStyle( 0 ); setCentralWidget( view ); //将信号与槽关联:m_scene发射message信号时,MainWindow接收信号,执行showMessage槽函数 connect( m_scene, SIGNAL(message(QString)), this, SLOT(showMessage(QString)) ); } MainWindow::~MainWindow() { } void MainWindow::showMessage( QString msg ) { statusBar()->showMessage( msg ); // 在主窗口状态栏上显示消息 }