linux 拖动图标有拖影_部件之间图标拖拽(使用很直观,效果很漂亮)

本文介绍了一个Linux环境下实现桌面图标拖放并带有拖影效果的MainWidget类。该类接受拖放操作,支持图标布局调整,同时具备选择、删除和模式切换功能。通过mouseMoveEvent、mousePressEvent等事件处理函数,实现了图标的选择、拖动和释放等交互行为。
摘要由CSDN通过智能技术生成

MainWidget::MainWidget( QWidget *parent /*= NULL*/ ):QWidget(parent),iconMode(SmallIcon_Mode)

{

this->setAcceptDrops(true);

m_pController = new Controller(this);

//init();

this->setMinimumWidth(100);

}

MainWidget::~MainWidget()

{

}

void MainWidget::init()

{

m_pController->init();

for (int i = 0; i getSize(); ++i)

{

IconItemWidget *pItemWidget = new IconItemWidget(m_pController->getItem(i),this);

m_ItemVec.push_back(pItemWidget);

}

}

//获取每个图标应该布局的位置

QRect MainWidget::GetItemRect( int index )

{

if (index  m_ItemVec.size())

{

return QRect();

}

const int spacing = 5;

int width = this->width();

int height = this->height();

int itemWidth = m_ItemVec[index]->width();

int itemHeight = m_ItemVec[index]->height();

int colCount = width / (itemWidth + spacing );

int rowCount = height / (itemHeight + spacing);

int row = index / colCount;

int col = index % colCount;

int xPos = col * (itemWidth + spacing );

int yPos = row * (itemHeight + spacing);

return QRect(xPos,yPos,itemWidth,itemHeight);

}

void MainWidget::resizeEvent( QResizeEvent * event )

{

//改变大小了要重新布局

for (int i = 0; i 

{

QRect rect = GetItemRect(i);

if (i == m_ItemVec.size() - 1)

{

this->setMinimumHeight(rect.y() + 20);

emit heightChangeSignal(this->height());

}

m_ItemVec[i]->setGeometry(rect);

}

QWidget::resizeEvent(event);

}

void MainWidget::paintEvent( QPaintEvent * event )

{

if (m_mousePos.x() == 0 && m_mousePos.y() == 0)

{

return;

}

//画红色选框

QRect rect(m_mousePressPos,m_mousePos);

QPainter painter(this);

painter.setPen(Qt::red);

painter.drawRect(rect);

update();

QWidget::paintEvent(event);

}

void MainWidget::mousePressEvent( QMouseEvent * event )

{

m_mousePressPos = event->pos();

//点击空白处则情况选中,

//如果m_selectItemVec大小为1,则也要清空下面再另外选中

//右键单击也要清空m_selectItemVec

if (!HitTest(event) || (m_selectItemVec.size() == 1) ||Qt::RightButton == event->button())

{

for (int i = 0; i 

{

m_selectItemVec[i]->unSelectedItem();

}

m_selectItemVec.clear();

}

for (int i = 0; i 

{

QRect rect = GetItemRect(i);

if (rect.contains(event->pos()) && (!isInVector(m_ItemVec[i])))  //图标尚未被选中则添加到m_selectItemVec

{

m_selectItemVec.push_back(m_ItemVec[i]);

m_ItemVec[i]->SelectItem();

}

}

QWidget *pWidget = QApplication::focusWidget();   //如果正在编辑名称,点击别的地方可以结束编辑

if (pWidget)

{

pWidget->clearFocus();

}

//右键菜单

if (Qt::RightButton == event->button())

{

QMenu *pMenu = new QMenu(this);

QAction *pBigModeAct = new QAction(tr("大图标"),pMenu);

QAction *pSmallModeAct = new QAction(tr("小图标"),pMenu);

QAction *pDeleteAct = new QAction(tr("删除"),pMenu);

if (m_selectItemVec.size() > 0)   //有选中的则弹出删除菜单

{

pMenu->addAction(pDeleteAct);

connect(pDeleteAct,SIGNAL(triggered()),this,SLOT(deleteItemSlot()));

}

else

{

//点击空白处则可切换图标模式

pMenu->addAction(pBigModeAct);

pMenu->addAction(pSmallModeAct);

connect(pBigModeAct,SIGNAL(triggered()),this,SLOT(bigModeSlot()));

connect(pSmallModeAct,SIGNAL(triggered()),this,SLOT(smallModeSlot()));

}

pMenu->exec(event->globalPos());

delete pMenu;

}

QWidget::mousePressEvent(event);

}

//大图标模式

void MainWidget::bigModeSlot()

{

m_pController->changeIconMode(BigIcon_Mode);

reLayoutIconSlot();

this->update();

}

//小图标模式

void MainWidget::smallModeSlot()

{

m_pController->changeIconMode(SmallIcon_Mode);

reLayoutIconSlot();

this->update();

}

void MainWidget::reLayoutIconSlot()

{

clear();    //先清除

for (int i = 0; i getSize(); ++i)

{

//重新生成图标

IconItemWidget *pItemWidget = new IconItemWidget(m_pController->getItem(i),this);

m_ItemVec.push_back(pItemWidget);

}

for (int i = 0; i 

{

QRect rect = GetItemRect(i);

m_ItemVec[i]->setGeometry(rect);

m_ItemVec[i]->show();             //重新生成,布局图标必须show才能显示

}

this->repaint();

}

void MainWidget::clear()

{

qDeleteAll(m_ItemVec);

m_ItemVec.clear();

}

void MainWidget::mouseMoveEvent( QMouseEvent * event )

{

if (event->buttons() & Qt::LeftButton && (m_selectItemVec.size() > 0))

{

if (( m_mousePressPos - event->pos()).manhattanLength() > QApplication::startDragDistance())

{

performDrag();

}

}

else

{

m_mousePos = event->pos();

}

QWidget::mouseMoveEvent(event);

}

void MainWidget::mouseReleaseEvent( QMouseEvent *event )

{

if (m_mousePos.x() == 0 && m_mousePos.y() == 0)

{

return;

}

else

{

//release鼠标再进行选择

SelectItem();

}

m_mousePos = QPoint();

QWidget::mouseReleaseEvent(event);

}

void MainWidget::dragEnterEvent( QDragEnterEvent * event )

{

const ItemMimeData *pMimeData = (const ItemMimeData*)event->mimeData();

const QList* plist = pMimeData->DragItemData();

if (plist)

{

event->accept();

}

}

void MainWidget::dragLeaveEvent( QDragLeaveEvent * event )

{

}

void MainWidget::dragMoveEvent( QDragMoveEvent * event )

{

event->accept();

}

void MainWidget::performDrag()

{

QDrag  *pDrag = new QDrag(this);

ItemMimeData *pData = new ItemMimeData;

QList *plist = new QList;

for (int i = 0; i 

{

plist->append(m_selectItemVec[i]->getData());

}

pData->SetDragDatas("ItemMimeData",plist);

pDrag->setMimeData(pData);

QPixmap pixmap = QPixmap::fromImage(m_selectItemVec[0]->getData()->image).scaled(50,50,Qt::KeepAspectRatio);

pDrag->setPixmap(pixmap);

pDrag->exec(Qt::CopyAction);

//delete m_selectItemVec[0];

}

void MainWidget::dropEvent( QDropEvent *event )

{

const ItemMimeData *pMimeData = (const ItemMimeData*)event->mimeData();

const QList* plist = pMimeData->DragItemData();

if (plist)

{

for (int i = 0; i size(); ++i)

{

m_pController->addItem(plist->at(i));

}

reLayoutIconSlot();

event->accept();

}

}

void MainWidget::deleteItemSlot()

{

//删除再重新布局

for (int i = 0; i 

{

m_pController->deleteItem(m_selectItemVec[i]->getData());

}

reLayoutIconSlot();

}

//框选多个图标

void MainWidget::SelectItem()

{

QRect rect(m_mousePressPos,m_mousePos);

for (int i = 0; i 

{

QPoint centerPos = GetItemRect(i).center();

if (rect.contains(centerPos))

{

m_ItemVec[i]->SelectItem();

m_selectItemVec.push_back(m_ItemVec[i]);

}

}

}

//有点击图标则返回true,否则返回false

bool MainWidget::HitTest( QMouseEvent * event )

{

for (int i = 0; i 

{

QRect rect = GetItemRect(i);

if (rect.contains(event->pos()))

{

return true;

}

}

return false;

}

//检查图标是否已经被选中

bool MainWidget::isInVector(IconItemWidget* pItem )

{

for (int i = 0; i 

{

if (m_selectItemVec[i] == pItem)

{

return true;

}

}

return false;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值