应大家的要求,还是把完整的project文件贴出来,大家省点事:http://www.kuaipan.cn/file/id_48923272389086450.htm

先看看执行效果,我用的群创7寸屏,主机是mini2440,分辨率是800*480,程序写比較粗糙,但对刚開始学习的人还是有一点启示,大家一起进步。

qt中提供了QGphicsView,QGraphicsScene,QGraphicsItem,QGraphicsPixmapItem是QGraphicsItem的子类

分辨创建它们的实例:view,scene,item,然后通过各自的方法scene->addItem(item);view->setScene(scene);就能够达到类似下图的效果,想要进一步定制,则要继承QGraphicsItem或QGraphicsPixmapItem,然后重写paint()、boundingRect()等方法,此外假设还想要获取鼠标事件,重写mousePressEvent等事件就好了,注意,一旦重写了mousePressEvent方法,就以为了qt不会再自己主动处理item的不论什么press事件了,能够在你重写的mousePressEvent方法中最后加入QGraphicsItem::mousePressEvent(event);解决问题,就是说你获取到了鼠标事件,可是依旧让qt处理这个鼠标事件。

程序中的item能够水平拖动,拖动的同一时候图标大小会渐变,中间最大,两边渐小。

图1

图2

图3

以下是源程序文件夹结构:

mainwindow.h与main.cpp是qt自己主动产生的代码,我没有产生窗体ui

myscene.h与某与scene.cpp是定义了类MyScene,继承自QGraphicsScene,我的目的是要获取其鼠标事件

nodeui.h与nodeui.cpp是定义了类NodeUI,继承自QGraphicsPixmapItem,目的相当多。

以下详细的源文件:myscene.h与myscene.cpp相对简单,就实现了一个功能

myscene.h

#ifndef MYSCENE_H
#define MYSCENE_H #include <QGraphicsScene> class MyScene : public QGraphicsScene
{
Q_OBJECT
public:
explicit MyScene(QObject *parent = 0); private:
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); signals:
void isMoving(QPointF &pos); public slots: private:
QPointF beforePos;
QPointF releasePos;
}; #endif // MYSCENE_H

myscene.cpp

#include "myscene.h"
#include <QGraphicsSceneMouseEvent>
#include <QPointF>
#include <QDebug> MyScene::MyScene(QObject *parent) :
QGraphicsScene(parent)
{
}
void MyScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
//QPointF pos = event->scenePos();
QPointF pos(event->scenePos().x()-beforePos.x(),event->scenePos().y()-beforePos.y());
emit isMoving(pos);
//qDebug()<<"x:"<<pos.x()<<"y:"<<pos.y();
}
void MyScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
beforePos = event->scenePos();
}
void MyScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
releasePos = event->scenePos();
}

再看nodeui.h与nodeui.cpp,在原来的QGraphicsPixmapItem基础上又假如了点自己的东西

#ifndef NODEUI_H
#define NODEUI_H #include <QGraphicsPixmapItem>
#include <QGraphicsItem>
#include <QStyleOptionGraphicsItem>
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
#include <QPointF> class NodeUI : public QObject,public QGraphicsPixmapItem
{
Q_OBJECT
public:
NodeUI();
NodeUI(QString &file,QString &text,int imagesize=80); //setup function
void setMyPixmap(QString &file,int size);
void setMyText(QString &text);
QString getMyText();
//virtual function
QRectF boundingRect() const;
QPainterPath shape() const;
signals:
void nodeIsMoving(QPointF &pos);
void nodeIsPressed(); protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
private:
//QString myImage;
QString myText; }; #endif // NODEUI_H

nideui.cpp

#include "nodeui.h"
#include <QPixmap>
#include <iostream>
#include <QDebug> NodeUI::NodeUI()
{
}
/*note: imagesize = 80 is in the nodeui.h*/
NodeUI::NodeUI(QString &file,QString &text,int imagesize)
{ setMyText(text);
setMyPixmap(file,imagesize);
} void NodeUI::setMyText(QString &text)
{
myText = text;
} void NodeUI::setMyPixmap(QString &file,int size)
{
//myImage = file;
QPixmap pixmap;
pixmap.load(file);
pixmap= pixmap.scaled(size,size,Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
setPixmap(pixmap);
}
QRectF NodeUI::boundingRect() const
{
QRect rect = this->pixmap().rect();
//return QRectF(rect);
return QRectF(0,0,rect.width(),rect.width()+15);
} void NodeUI::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
QPixmap pixmap = this->pixmap();
QRect rect = pixmap.rect(); painter->drawPixmap(rect,pixmap); //print name,calculate the text's heigh & width for center layout
QPen pen(Qt::black);
painter->setPen(pen);
painter->setRenderHint(QPainter::Antialiasing);
QFont font("Verdana",8, QFont::Normal);
painter->setFont(font);
painter->drawText(QRectF(0,rect.height(),rect.width(),15),Qt::AlignCenter,myText); if (option->state & QStyle::State_Sunken)
{
QRectF rect1 = boundingRect();
//QPen pen(Qt::darkGreen);
painter->setPen(QPen(Qt::darkGreen));
}else
{ }
}
QPainterPath NodeUI::shape() const
{
QRectF rect = boundingRect(); QPainterPath path;
path.addRoundRect(rect, 5,5);
return path;
} void NodeUI::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
emit nodeIsPressed();
qDebug()<<"pressed";
QGraphicsItem::mousePressEvent(event);
}
void NodeUI::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
update(boundingRect());
QGraphicsItem::mouseReleaseEvent(event);
}
QString NodeUI::getMyText()
{
return myText;
}

最后是scene与item的文件mainwindow.cpp,继承了QMainWindow,作用就是画一个应用程序框架

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H #include <QtGui/QMainWindow>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QPointF>
#include "nodeui.h"
#include "myscene.h"
#include <QMap> class MainWindow : public QMainWindow
{
Q_OBJECT public:
MainWindow(QWidget *parent = 0);
~MainWindow(); NodeUI *selectedNodeUI();
bool isNodeUiClicked();
void nodeUiSizeAdjust();
//var protected: private: void GetScreenInfo();
QGraphicsView *view;
//QGraphicsScene *scene;
MyScene *scene;
//instead of (NodeUI *nodeui;)&(QPointF nodeUiPos;)
//眼下弃用,因为QMap的顺序无法人为设定,依照内部key自己主动升序
//QMap<NodeUI*,QPointF>nodeUiMaps;
//NodeUI *currentNodeUI;
//nodeui pressed or released
volatile bool mPressed; QList<NodeUI*> nodeUiLists;
QList<QPointF> nodeUiPosLists;
QList<QPixmap> nodeUiPixmapLists;
/*
struct {
QList<NodeUI*> nodelists;
QList<QPointF> poslists;
}ss;
*/
//弃用
NodeUI *nodeui;
QPointF nodeUiPos; //sceen size info;
qint16 sceenSizeX;
qint16 sceenSizeY;
private slots:
void isMoving(QPointF &pos);
void isPressed();
void isReleased();
void selectionChanged(); signals:
void nodeUiClicked(NodeUI* node);
}; #endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include <QDesktopWidget>
#include <QApplication>
#include <QPixmap>
#include <QGraphicsItem>
#include <QMouseEvent>
#include <QWidget>
#include <QGraphicsPixmapItem>
#include <QMessageBox>
#include <QDebug> const qreal MY_NODEUI_POS_Y = 200;
const qreal MY_NODEUI_DIS = 110;
const qreal MY_NODEUI_STA = 90;
const int MYNODEUI_SIZE = 100;
const int MYNODEUI_SIZE_M = 20;
const int SCREEN_SIZE = 800;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
//初始化
mPressed = false;
//get windows size
GetScreenInfo(); view = new QGraphicsView;
scene = new MyScene();
scene->setSceneRect(0,0,800,480); //new
QString file;
QString text;
QPointF pos;
NodeUI* node; //HOME:1
file = QString(":/images/home.png");
text = QString("Home");
pos = QPointF(MY_NODEUI_STA,MY_NODEUI_POS_Y); node = new NodeUI(file,text,MYNODEUI_SIZE);
node->setPos(pos);
nodeUiLists.append(node);
nodeUiPosLists.append(pos);
nodeUiPixmapLists.append(node->pixmap());
/*
here cannot delete node!!!!!!!!!!!!!!!
delete node;
*/ //VIDIO:2
file = QString(":/images/securitycamera.png");
text = QString("Vidio");
pos = QPointF(MY_NODEUI_STA+MY_NODEUI_DIS*1,MY_NODEUI_POS_Y); node = new NodeUI(file,text,MYNODEUI_SIZE);
node->setPos(pos);
nodeUiLists.append(node);
nodeUiPosLists.append(pos);
nodeUiPixmapLists.append(node->pixmap()); //APPLICATION:3
file = QString(":/images/application.png");
text = QString("Application");
pos = QPointF(MY_NODEUI_STA+MY_NODEUI_DIS*2,MY_NODEUI_POS_Y); node = new NodeUI(file,text,MYNODEUI_SIZE);
node->setPos(pos);
nodeUiLists.append(node);
nodeUiPosLists.append(pos);
nodeUiPixmapLists.append(node->pixmap()); //NETWORK:4
file = QString(":/images/network-2.png");
text = QString("Network");
pos = QPointF(MY_NODEUI_STA+MY_NODEUI_DIS*3,MY_NODEUI_POS_Y); node = new NodeUI(file,text,MYNODEUI_SIZE);
node->setPos(pos);
nodeUiLists.append(node);
nodeUiPosLists.append(pos);
nodeUiPixmapLists.append(node->pixmap()); //COMPUTER:5
file = QString(":/images/smartphone.png");
text = QString("Phone");
pos = QPointF(MY_NODEUI_STA+MY_NODEUI_DIS*4,MY_NODEUI_POS_Y); node = new NodeUI(file,text,MYNODEUI_SIZE);
node->setPos(pos);
nodeUiLists.append(node);
nodeUiPosLists.append(pos);
nodeUiPixmapLists.append(node->pixmap()); //CUSTOMIZE:5
file = QString(":/images/customize.png");
text = QString("Setting");
pos = QPointF(MY_NODEUI_STA+MY_NODEUI_DIS*5,MY_NODEUI_POS_Y); node = new NodeUI(file,text,MYNODEUI_SIZE);
node->setPos(pos);
nodeUiLists.append(node);
nodeUiPosLists.append(pos);
nodeUiPixmapLists.append(node->pixmap()); //又一次计算UiSize
nodeUiSizeAdjust(); int i = 0;
foreach(NodeUI* node_temp,nodeUiLists)
{ node_temp->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); qDebug()<<"name:"<<node_temp->getMyText()<<nodeUiPosLists.at(i); scene->addItem(node_temp); i++;
} //用于button的单机 view->setScene(scene);
//set drag mode
//view->setDragMode(QGraphicsView::RubberBandDrag);
view->setRenderHints(QPainter::Antialiasing);
//no menu
view->setContextMenuPolicy(Qt::NoContextMenu); view->setBackgroundBrush(QImage(":/images/shuibo2.jpg"));
//view->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
//view->setCacheMode(QGraphicsView::CacheBackground);
setCentralWidget(view);
setWindowTitle(tr("Main Window"));
}
//槽,当scene鼠标拖拽是运行
//控制UI图标的水平
void MainWindow::isMoving(QPointF &pos)
{
int i=0;
if(mPressed){
foreach(NodeUI* node,nodeUiLists)
{
node->setPos(nodeUiPosLists.at(i).x()+pos.x(),MY_NODEUI_POS_Y);
i++;
}
nodeUiSizeAdjust();
}
}
//槽,当nodeui鼠标按下时运行,调用selectedNodeUI函数,更新currentNodeUI变量
//除此之外,selectionChanged()也是一个槽,由scene调用
void MainWindow::isPressed()
{
selectionChanged();
mPressed = true;
}
//槽,当nodeui鼠标释放时运行
//应当设置标志位,让UI图片停止对鼠标拖动事件的响应
void MainWindow::isReleased()
{
mPressed = false;
if(isNodeUiClicked())
qDebug()<<"clicked";
qDebug()<<"release";
} //槽,当scene的selectedItem变化时,发送同名信号到此槽
void MainWindow::selectionChanged()
{
int i=0,j=0;
QList<QGraphicsItem *> items = scene->selectedItems();
if (items.count() == 1) {
//当前所选择的UI图标的坐标
QPointF pos = items.first()->pos();
NodeUI* node_temp = dynamic_cast<NodeUI *>(items.first());
qDebug()<<"items.x:"<<pos.x()<<"items.y:"<<pos.y(); foreach(NodeUI* node,nodeUiLists)
{
if(node == node_temp)
break;
i++;
}
j=i;
i=0;
foreach(QPointF ppos,nodeUiPosLists)
{
nodeUiPosLists[i].setX((i-j)*MY_NODEUI_DIS+pos.x());
nodeUiPosLists[i].setY(MY_NODEUI_POS_Y);
i++;
} } else {
return;
}
}
//推断是否Nodeui接收的是否是单击信号。
//推断根据是当前单击的nodeui对象的pos与存储在nodeUiPosListsd的位置比較,相等则为单击
bool MainWindow::isNodeUiClicked()
{
int i=-1;
QList<QGraphicsItem *> items = scene->selectedItems();
if (items.count() == 1) {
QPointF pos = items.first()->pos();
NodeUI* node_temp = dynamic_cast<NodeUI *>(items.first());
if(pos ==nodeUiPosLists.at(i)){
//emit nodeUiClicked(node_temp);
QMessageBox::information(this,"New Window","will open : "+node_temp->getMyText());
return true;
}
}
return false;
}
void MainWindow::nodeUiSizeAdjust()
{
quint16 i=0;
foreach(NodeUI* node,nodeUiLists)
{
//qDebug()<<"i= "<<i;
QPointF pos=node->pos(); pos.setX(node->pos().x()+MYNODEUI_SIZE/2);
//pos.setX(node->pos().x()+node->pixmap().width());
if(pos.x()>=0 && pos.x()<=SCREEN_SIZE/2)
{
//(MYNODEUI_SIZE-MYNODEUI_SIZE_M)/(SCREEN_SIZE/2)==(size-20)/pos.x()
quint16 size=pos.x()/5+20;
QPixmap pixmap = nodeUiPixmapLists.at(i);
//QPixmap pixmap = nodeUiLists.at(i)->pixmap();
pixmap = pixmap.scaled(size,size,Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
nodeUiLists[i]->setPixmap(pixmap);
} //if(pos.x()>SCREEN_SIZE/2 && pos.x()<=SCREEN_SIZE)
if(pos.x()>SCREEN_SIZE/2 && pos.x()<=SCREEN_SIZE+10)
{
//(MYNODEUI_SIZE-MYNODEUI_SIZE_M)/(SCREEN_SIZE/2)==(size-20)/pos.x()
quint16 size=(SCREEN_SIZE-pos.x())/5+20;
QPixmap pixmap = nodeUiPixmapLists.at(i);
//QPixmap pixmap = nodeUiLists.at(i)->pixmap();
pixmap = pixmap.scaled(size,size,Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
nodeUiLists[i]->setPixmap(pixmap);
}
i++;
}
}
MainWindow::~MainWindow()
{
}
//获取设备分辨率的呢个信息
void MainWindow::GetScreenInfo()
{
QDesktopWidget* desktopWidget = QApplication::desktop();
//获取可用桌面大小
//QRect deskRect = desktopWidget->availableGeometry();
//获取设备屏幕大小
QRect screenRect = desktopWidget->screenGeometry(); sceenSizeX = screenRect.width();
sceenSizeY = screenRect.height(); //获取系统设置的屏幕个数(屏幕拷贝方式该值为1)
//g_nScreenCount = desktopWidget->screenCount();
}

最后是main.cpp

实例化MainWindow

#include <QtGui/QApplication>
#include "mainwindow.h" int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w; w.setWindowOpacity(1);
w.setWindowFlags(Qt::FramelessWindowHint);
w.setAttribute(Qt::WA_TranslucentBackground);
w.show();
//w.showFullScreen(); return a.exec();
}

大概都写了注解了,事实上看看一个名称也该大概了解其作用,写这程序时遇到的问题都记录在了前一篇qt学习笔记(四)中,记录一下,以备不时之需

qt学习笔记(五) QGraphicsPixmapItem与QGraphicsScene的编程实例 图标拖动渐变效果的更多相关文章

  1. (转)Qt Model/View 学习笔记 (五)——View 类

    Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...

  2. C#可扩展编程之MEF学习笔记(五):MEF高级进阶

    好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...

  3. java之jvm学习笔记五(实践写自己的类装载器)

    java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...

  4. Learning ROS for Robotics Programming Second Edition学习笔记(五) indigo computer vision

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  5. Typescript 学习笔记五:类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  6. ES6学习笔记<五> Module的操作——import、export、as

    import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...

  7. muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor

    目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ...

  8. python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍

    python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍 IDLE默认不能显示行号,使用ALT+G 跳到对应行号,在右下角有显示光标所在行.列.pycharm免费社区版.Su ...

  9. Go语言学习笔记五: 条件语句

    Go语言学习笔记五: 条件语句 if语句 if 布尔表达式 { /* 在布尔表达式为 true 时执行 */ } 竟然没有括号,和python很像.但是有大括号,与python又不一样. 例子: pa ...

随机推荐

  1. 类型<T> where T:class的用法

    public void Delete<T>(List<T> EntityList) where T : class, new() 就是说T必须是一个类(class)类型,不能是 ...

  2. JNI 多线程

    一.概述 JNI编程和Linux上的C/C++编程还是挺相似的,每次java调用JNI中的函数时都会传入有关JVM的一些参数(如JNIEnv,jobject),每次JNI回调java中的方法时都要通过 ...

  3. 给自己加油,一定要学会MFC!

    我自己对于没有学会MFC始终耿耿于怀,都什么时代了啊,但是我仍然坚持会去学MFC,因为MFC虽然落后与复杂,但是在Windows平台上仍然是无所不能的(其实Windows平台仍然是唯一可以赚钱的平台, ...

  4. RxJava开发精要3-向响应式世界问好

    原文出自<RxJava Essentials> 原文作者 : Ivan Morgillo 译文出自 : 开发技术前线 www.devtf.cn 转载声明: 本译文已授权开发者头条享有独家转 ...

  5. Android UI性能优化详解

    设计师,开发人员,需求研究和测试都会影响到一个app最后的UI展示,所有人都很乐于去建议app应该怎么去展示UI.UI也是app和用户打交道的部分,直接对用户形成品牌意识,需要仔细的设计.无论你的ap ...

  6. 【图片处理】cocos2dx png图片压缩处理

    一.介绍 美术用photoshop出图有时候会包含一些无用的信息,这时候image magick可以把这些信息裁掉. 二.使用方法 1.下载并安装Image Magick 2.将脚本里的目录名改成Im ...

  7. matlab numpy equivalents

    THIS IS AN EVOLVING WIKI DOCUMENT. If you find an error, or can fill in an empty box, please fix it! ...

  8. hdu4374One hundred layer (DP+单调队列)

    http://acm.hdu.edu.cn/showproblem.php?pid=4374 去年多校的题 今年才做 不知道这一年都干嘛去了.. DP的思路很好想 dp[i][j] = max(dp[ ...

  9. cmd find命令

    find 作用:从文件中收索字符串 格式:find 参数 "字符串" 路径\文件名 参数: /V 显示所有未包含指定字符串的行. /C 仅显示包含字符串的行数. /N 显示行号. ...

  10. [转] POJ 题目分类

    转载来自http://www.cnblogs.com/kuangbin/archive/2011/07/29/2120667.html 初期:一.基本算法:     (1)枚举. (poj1753,p ...