应大家的要求,还是把完整的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. OpenStack项目列表

    这个也是必须要熟悉的哟. ~~~~~~~~~~ OpenStack是一个美国国家航空航天局和Rackspace合作研发的,以Apache许可证授权,并且是一个自由软件和开放源代码项目.OpenStac ...

  2. php邮件发送 phpmailer

    首先要安装phpmailer开源项目. 将class.phpmailer.php转移到php文件夹下, 编写代码: <?php require("class.phpmailer.php ...

  3. redis info 各信息意义

    redis_version:2.4.16 # Redis 的版本redis_git_sha1:00000000redis_git_dirty:0arch_bits:64multiplexing_api ...

  4. 安装java memcached client到本地maven repository

    由于目前java memcached client没有官方的maven repository可供使用,因此使用时需要手动将其安装到本地repository.java memcached client的 ...

  5. easyui表单提交,后台获取不到值

    J2ee开发,使用easyui表单提交,在ie中可以正常将参数传递到后台,但使用firefox,chrome都无法将easyui的combobox值传递到后台,使用alert($('#form').s ...

  6. Java缓存--JCS

    添加外部包: jcs-1.3.jar concurrent-10.3.jar cache.cff # optional region "myCache" specific conf ...

  7. 李洪强iOS开发本人集成环信的经验总结_02_基本配置

     李洪强iOS开发本人集成环信的经验总结_02_基本配置 来到APPdelegate中做一些配置 01 - 导入头文件 02 - 在didFinishLaunchingWithOptions用法总结 ...

  8. char 和 varchar

    固定长度或可变长度的字符数据类型. char [ ( n ) ] 固定长度,非 Unicode 字符数据,长度为 n 个字节.n 的取值范围为 1 至 8,000,存储大小是 n 个字节.char 的 ...

  9. laravel route路由,视图和response和filter

    Laravel充分利用PHP 5.3的特性,使路由变得简单并富于表达性.这使得从构建API到完整的web应用都变得尽可能容易.路由的实现代码在 application/routes.php 文件. 和 ...

  10. 多核CPU怎么理解

    简而言之,双核处理器即是基于单个半导体的一个处理器上拥有两个一样功能的处理器核心.换句话说,将两个物理处理器核心整合入一个核中.企业IT管理者们也一直坚持寻求增进性能而不用提高实际硬件覆盖区的方法.多 ...