您的位置:首页 > 编程语言 > Qt开发

qt实现头像上传功能(写了4个类,朝十晚八的博客,非常好)

2016-08-04 23:57 411 查看
想必大家都使用过qt的自定义头像功能吧,那么图1应该不会陌生,本片文章我就是要模拟一个这样的功能,虽然没有这么强大的效果,但是能够满足一定的需求。

1 void CutShape::mousePressEvent(QMouseEvent * event)
2 {
3     m_startPoint = event->pos();
4     m_MouseDown = event->button() == Qt::LeftButton;
5 }
6
7 void CutShape::mouseMoveEvent(QMouseEvent * event)
8 {
9     QPoint dragPoint = event->pos();
10     if (!parentWidget()->rect().contains(mapToParent(dragPoint)))
11     {
12         return;
13     }
14     int x = event->x();
15     int y = event->y();
16     if (m_MouseDown)
17     {
18         if (m_Left == false && m_Right == false
19             && m_Bottom == false && m_Top == false)
20         {
21             QPoint p = QPoint((pos().x() + dragPoint.x() - m_startPoint.x()), (pos().y() + dragPoint.y() - m_startPoint.y()));
22             QPoint dragEndge = p;
23             dragEndge.setX(dragEndge.x() + rect().width());
24             dragEndge.setY(dragEndge.y() + rect().height());
25             p.setX(p.x() < 0 ? 0 : p.x());
26             p.setX(dragEndge.x() > parentWidget()->width() ? parentWidget()->width() - rect().width() : p.x());
27             p.setY(p.y() < 0 ? 0 : p.y());
28             p.setY(dragEndge.y() > parentWidget()->height() ? parentWidget()->height() - rect().height() : p.y());
29             move(p);
30         }
31         else
32         {
33             bool ignore = false;
34             QRect g = getResizeGem(geometry(), dragPoint, ignore);
35             if (parentWidget()->rect().contains(g))
36                 setGeometry(g);
37             if (ignore == false)
38             {
39                 m_startPoint = QPoint(!m_Right ? m_startPoint.x() : event->x(), !m_Bottom ? m_startPoint.y() : event->y());
40             }
41         }
42     }
43     else
44     {
45         QRect r = rect();
46         m_Left = qAbs(x - r.left()) < 5;
47         m_Right = qAbs(x - r.right()) < 5;
48         m_Bottom = qAbs(y - r.bottom()) < 5;
49         m_Top = qAbs(y - r.top()) < 5;
50         bool lorr = m_Left | m_Right;
51         bool torb = m_Top | m_Bottom;
52         if (lorr && torb)
53         {
54             if ((m_Left && m_Top) || (m_Right && m_Bottom))
55             {
56                 setCursor(Qt::SizeFDiagCursor);
57             }
58             else
59                 setCursor(Qt::SizeBDiagCursor);
60         }
61         else if (lorr)
62             setCursor(Qt::SizeHorCursor);
63         else if (torb)
64             setCursor(Qt::SizeVerCursor);
65         else
66         {
67             setCursor(Qt::SizeAllCursor);
68             m_Bottom = m_Left = m_Right = m_Top = false;
69         }
70     }
71 }
72
73 void CutShape::mouseReleaseEvent(QMouseEvent * event)
74 {
75     m_MouseDown = false;
76 }
77
78 void CutShape::resizeEvent(QResizeEvent *event)
79 {
80     m_EnableRepaint = true;
81     update();
82
83     QWidget::resizeEvent(event);
84 }
85
86 QRect CutShape::getResizeGem(QRect oldgeo, QPoint mousePoint, bool & ignore)
87 {
88     QRect g = oldgeo;
89     bool lorr = m_Left | m_Right;
90     bool torb = m_Top | m_Bottom;
91     int dx = mousePoint.x() - m_startPoint.x();
92     int dy = mousePoint.y() - m_startPoint.y();
93     ignore = false;
94     if (lorr && torb)
95     {
96         int maxLen = qMax(qAbs(dx), qAbs(dy));
97         if (m_Left && m_Top && dx*dy > 0)
98         {
99             g.setLeft(dx > 0 ? g.left() + maxLen : g.left() - maxLen);
100             g.setTop(dy > 0 ? g.top() + maxLen : g.top() - maxLen);
101         }
102         else if (m_Right && m_Top && dx * dy < 0)
103         {
104             g.setRight(dx > 0 ? g.right() + maxLen : g.right() - maxLen);
105             g.setTop(dy > 0 ? g.top() + maxLen : g.top() - maxLen);
106         }
107         else if (m_Right && m_Bottom)
108         {
109             if (dx * dy > 0)
110             {
111                 g.setRight(dx > 0 ? g.right() + maxLen : g.right() - maxLen);
112                 g.setBottom(dy > 0 ? g.bottom() + maxLen : g.bottom() - maxLen);
113             }
114             else if (dx == 0 && dy != 0
115                 /*|| dx != 0 && dy == 0*/)
116             {
117                 ignore = true;
118             }
119         }
120         else if (m_Left && m_Bottom && dx*dy < 0)
121         {
122             g.setLeft(dx > 0 ? g.left() + maxLen : g.left() - maxLen);
123             g.setBottom(dy > 0 ? g.bottom() + maxLen : g.bottom() - maxLen);
124         }
125
126         return g;
127     }
128     else if (lorr)
129     {
130         if (m_Left)
131             g.setLeft(g.left() + dx);
132         if (m_Right)
133             g.setRight(g.right() + dx);
134         int len = g.width() - oldgeo.width();
135         int intHight = (int)len / 2.0;
136
137         g.setTop(g.top() - intHight);
138         g.setBottom(g.bottom() + len - intHight);
139     }
140     else if (torb)
141     {
142         if (m_Bottom)
143             g.setBottom(g.bottom() + dy);
144         if (m_Top)
145             g.setTop(g.top() + dy);
146         int dheigt = g.height() - oldgeo.height();
147         int intWidth = (int)dheigt / 2.0;
148
149         g.setLeft(g.left() - intWidth);
150         g.setRight(g.right() + dheigt - intWidth);
151     }
152     else
153     {
154         ignore = true;
155     }
156     return g;
157 }


2、BackgroundWidget背景色窗口,该窗口作为剪切窗口的父类窗口,但是没有布局,目的就是可以让剪切窗口自由的移动,并保持在背景色窗口之上,当背景色窗口重新绘制的时候,只绘制除剪切窗口以外的部分。这样就实现了剪切窗口是透明的但是其余部分都是半透明的,代码如下:

1 void BackgroundWidget::paintEvent(QPaintEvent *)
2 {
3     QPainterPath painterPath;
4     QPainterPath p;
5     p.addRect(x(), y(), rect().width(), rect().height());
6     if (m_CutShape)
7     {
8         painterPath.addPath(m_CutShape->CutRegion().translated(m_CutShape->pos()));
9     }
10     QPainterPath drawPath = p.subtracted(painterPath);
11
12     QPainter paint(this);
13     paint.setOpacity(0.5);
14     paint.fillPath(drawPath, QBrush(Qt::black));
15 }


3、PicturePreviewPanel图片上传控件基类,当图片加载后,需要重置背景色窗口的大小,以便覆盖到图片之上,代码如下:

1 bool PicturePreviewPanel::eventFilter(QObject * watched, QEvent * event)
2 {
3     if (watched == m_PictureContainer)
4     {
5         if (event->type() == QEvent::Resize)
6         {
7             LoadPicture_p();
8             if (m_BgWidget)
9             {
10                 m_BgWidget->resize(m_PictureContainer->size());
11             }
12         }
13     }
14     return QWidget::eventFilter(watched, event);
15 }


之所以需要重新加载图片是,放置图片因为拖拉而失真,图片的加载的加载代码如下:

1 void PicturePreviewPanel::LoadPicture_p()
2 {
3     QPixmap picture;
4     picture.load(m_PicturePath);
5     if (!picture.isNull())
6     {
7         picture = picture.scaled(m_PictureContainer->width(), m_PictureContainer->height());
8         m_PictureContainer->setPixmap(picture);
9         m_BgWidget->PictureLoadFinished();
10     }
11 }


好了,有了上边的代码之后,这个图片上传空间的基本交互功能就完成了,点击保存截取图片,可以使用剪贴图基类的CutRegion方法获取剪贴的路径,并保存成指定图片格式。效果如图2所示



图2 效果展示

实例代码下载:http://download.csdn.net/detail/qq_30392343/9581238
http://www.cnblogs.com/swarmbees/p/5688885.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: