qt之二维图像绘制之:选择,删除,移动Item
时间: 2018-09-04来源:OSCHINA
前景提要
「深度学习福利」大神带你进阶工程师,立即查看>>>
1、添加Item类
sation.h #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
sation.cpp #include "sation.h" #include <QPainter> Sation::Sation(qreal x, qreal y):QGraphicsItem() { setPos(x, y); setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIgnoresTransformations ); } //构造函数里我们根据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 ); }
2、在scene类中处理item类
scene.h #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* ); // 接收鼠标按下事件 void contextMenuEvent( QGraphicsSceneContextMenuEvent* ); // 接收上下文菜单事件 }; #endif // SCENE_H
scene.cpp #include "scene.h" #include <QGraphicsSceneMouseEvent> #include <QGraphicsSceneContextMenuEvent> #include <QMenu> #include <QAction> Scene::Scene( ) : QGraphicsScene() { addLine( 0, 0, 0, 1, QPen(Qt::transparent, 1) ); } void Scene::mousePressEvent( QGraphicsSceneMouseEvent* event ) { // 设置本地变量和检查被选中的电台是否存在 qreal x = event->scenePos().x(); qreal y = event->scenePos().y(); QTransform transform; Sation *station = dynamic_cast<Sation *>(this->itemAt(QPointF(x, y), transform)); //pointf返回一个基类,现在让他指向派生类 // 如果电台没有被选中并且鼠标左键被按下, 创建一个新电台 if ( station == 0 && event->button() == Qt::LeftButton ) { addItem( new Sation( x, y ) ); emit message( QString("Station add at %1,%2").arg(x).arg(y) ); } // 调用基类的mousePressEvent处理其它鼠标按下事件 QGraphicsScene::mousePressEvent( event ); } /* * 添加新方法contextMenuEvent的代码。当用户在场景里按下鼠标右键,这个方法将被调用。我们只想用户指向一个电台时才会显示一个上下文菜单。 * 然后我们创建一个只有删除电台选项的菜单。 * 如果用户选择这个选项,电台将会从场景中删除,并且从内存中删除,和发送一条消息。 */ void Scene::contextMenuEvent( QGraphicsSceneContextMenuEvent* event ) { // 我们只想当用户选择一个电台时才显示菜单 qreal x = event->scenePos().x(); qreal y = event->scenePos().y(); QTransform transform; Sation *station = dynamic_cast<Sation *>(this->itemAt(QPointF(x, y), transform)); //pointf返回一个基类,现在让他指向派生类 if(0 == station) return; // 显示上下文和相应的动作 QMenu menu; QAction* deleteAction = menu.addAction("Delete Station"); if ( menu.exec( event->screenPos() ) == deleteAction ) { removeItem( station ); delete station; emit message( QString("Station deleted at %1,%2").arg(x).arg(y) ); } }
3、将scene放入view
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
mainwindow.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 ); // 在主窗口状态栏上显示消息 }
4、main.cpp #include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }

科技资讯:

科技学院:

科技百科:

科技书籍:

网站大全:

软件大全:

热门排行