QT Implementation Avatar upload function (wrote 4 classes, ten-to-eight blog, very good)

Source: Internet
Author: User
Tags custom graphics

Presumably everyone has used Qt's custom avatar function, then figure 1 should not be unfamiliar, this piece of article I just want to simulate a such function, although not so powerful effect, but can meet a certain demand.

Figure 1 QQ Upload image


First of all, before explaining the function, I first give a piece, QT implementation of similar QQ avatar selection box, this article is also to explain the Avatar upload function, and my own code is optimized from this demo, not only the code has been reconstructed, but also to deal with the rapid drag, the border disappears. Use events and double buffering to minimize the chance of repainting. Next I will step by step to explain how to achieve the image of the custom interception function.
I. Summary
Preferred, I gave 4 classes, and gave their explanations
1. Picturepreviewpanel: Icon display box, control base class
2, Backgroundwidget: Shadow window, is Picturepreviewpanel subclass
3, Cutshape: Interactive graphics base class, realize the drag and zoom reduction function
4, Cutround: Round clipping, the parent class is Cutshape, implements Paintinit interface redrawing of the parent class
5, Cutrectangle: Rectangle clipping, the parent class is Cutshape, implements Paintinit interface redrawing of the parent class
Second, details
After understanding the above 5 classes, I will explain the next class header file and the important implementation interface, where the custom graphics class can also be expanded
The header file code is as follows, there are some comments, the code should not be difficult to understand, the development process only need to declare the Picturepreviewpanel class, and the call period LoadPicture interface can load the picture, and the picture cut

  1 #include <QWidget> 2 3 class Qlabel; 4 5 enum ShapeType 6 {7 rect,//rectangle 8 round,//Round 9}; 10 11//Clip EOG class implements the basic interactive function and draws a partial pattern, the main group is drawn in the subclass implementation, by implementing the Paintinit interface of the Cutshape:public qwidget (public:15 C Utshape (qwidget * parent = nullptr); ~cutshape (); Public:19 Qpainterpath cutregion (); Protected:22//qwidget mousepressevent (qmouseevent *) q_decl_override; virtual void mousemoveevent (qmouseevent *) q_decl_override; virtual void mousereleaseevent (qmouseevent *) q_decl_override; -Virtual void resizeevent (qresizeevent *) q_decl_override; virtual void PaintEvent (qpaintevent *) q_decl_override; virtual BOOL Paintinit (qpaintevent *, qpaintdevice *) = 0; Virtual Qpainterpath region () {return Qpainterpath ();}; Protected:33 ShapeType M_type; m_mousedown bool = false; m_ismoving bool = false; m_isfirst bool = true; PNS int bordER = 5; private:40 qrect Getresizegem (qrect oldgeo, Qpoint mousepoint, BOOL & ignore); private:43 bool M_enablerepaint = true; m_left bool = false; m_right bool = false; m_bottom bool = false; m_top bool = false; Qpoint M_startpoint; Qpoint M_old_pos; Qlabel * M_label; Wuyi Qpixmap M_bufferpix; 52}; Cutrectangle:public Cutshape, public:57 cutrectangle (qwidget * parent = nullptr), ~cutre Ctangle (); protected:61//cutshape, virtual bool Paintinit (qpaintevent *, Qpaintdevice *) q_decl_override; Q_decl_override Virtual Qpainterpath region (); 64}; Cutround:public cutshape public:69 Cutround (qwidget * parent = nullptr); ~cutround (); 7 1 protected:73//cutshape, virtual bool Paintinit (qpaintevent *, Qpaintdevice *) q_decl_override; Qpainterpath Virtual region () Q_decl_override; PRIVATE:78}; 79 class Backgroundwidget:public Qwidget Bayi {public:83 Backgroundwidget (qwidget * parent = nullptr, Shapetyp E type = Round); ~backgroundwidget (); public:87 void pictureloadfinished (); protected:90 virtual void PaintEvent (qpaintevent *) q_decl_override; private:93 ShapeType M_type; 94 Cutshape * M_cutshape = nullptr; 95};  Picturepreviewpanel:public class Qwidget 98 {q_object100 101 public:102 picturepreviewpanel (QWidget * parent = nullptr); 103 ~picturepreviewpanel () 104 public:106 void LoadPicture (const QString & filepath);// Load Picture 107 108 protected:109 virtual BOOL EventFilter (Qobject *, qevent *) q_decl_override;110 111 private:112 void I Nitializeui (); 113 void Loadpicture_p (); private:116 QString m_picturepath;117 Qlabel * m_picturecontain ER = nullptr;118 backgroundwidget * m_bgwidget = nullptr;119};

The above header file, if you feel trouble can also not be specific to look at the interface, as long as the title 1 below the 5 of the function of the class can be. Next I say the interactive graphic class, Background color class and display picture class (that is, the control base class) These three direct relationships, specifically as follows:

1, Cutshape clip EOG class to achieve the basic interactive function, and draw a part of the pattern, the main drawing in the sub-class implementation, through the implementation of the Paintinit interface, the interface in the clipping map Street base class re-drawing, the code is as follows:

 1 void Cutshape::p aintevent (Qpaintevent * Event) 2 {3 Qpainter paint; 4 if (M_enablerepaint && paintinit (event, &m_bufferpix))         5 {6 m_enablerepaint = false; 7 qdebug () << "Event->type ()" << event->type (); 8 M_bufferpix = Qpixmap (Size ()); 9 M_bufferpix.fill (qt::transparent), Paint.begin (&m_bufferpix), Qpen pen0;13 PE N0.setcolor (Qcolor, 158, 254, Wu)); Pen0.setwidth (2); Paint.setpen (pen0); paint.drawrect (Border, border, width ()-Border * 2, Width ()-border * 2); Qpen pen;19 qvector<qreal> dashes ; Qreal space = 3;21 dashes << 5 << space << 5 << space;22 PEN.SETDASHPA Ttern (dashes); Pen.setcolor (qt::white); Paint.setpen (pen), + int x_pos = (int) width ()/3.0 ; Y_pos int = (int) height ()/3.0;28 paint.drawline (X_pos, border, X_pos, Height ()-2 * border); Paint.drawline (2 * x_pos, Border, 2 * x_pos, Height ()-2 * border); 30 Paint.drawline (Border, Y_pos, Width ()-2 * border, Y_pos); Paint.drawline (Border, 2 * y_pos, Width ()-2 * bord     Er, 2 * y_pos); Paint.end ();}34 Paint.begin (this); Paint.drawpixmap (Rect (), M_bufferpix); 36 Paint.end (); 37}

The top is the main drawing process, about the interactive function of the cut graph, I give the specific big aunt, do not carefully explain the function, the code is a bit long, as follows:

  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 (); Parentwidget ()->rect (). Contains (Maptoparent (Dragpoint))) one {x return; X (); int y = event->y (); if (M_mousedown) + {if (M_left = = False && M_right = = False && M_bo Ttom = = False && M_top = = False) {Qpoint p = qpoint (pos (). x () + dragpoint.x ()-M_star Tpoint.x ()), (POS (). Y () + dragpoint.y ()-M_startpoint.y ())); Qpoint Dragendge = p; Dragendge.setx (dragendge.x () + rect (). width ()); Dragendge.sety (Dragendge.y () + rect (). height ()); P.setx (p.x () < 0? 0:p.x ()); P.setx (dragendge.x () > PArentwidget ()->width ()? Parentwidget ()->width ()-rect (). Width (): p.x ()); P.sety (p.y () < 0 0:p.y ()); P.sety (Dragendge.y () > Parentwidget ()->height ()? Parentwidget ()->height ()-rect (). Height (): p.y ()); Move (p); + Else (ignore = false; Qrect g = Getresizegem (GeoMet Ry (), dragpoint, ignore); if (Parentwidget ()->rect (). Contains (g)) setgeometry (g); PNS if (ignore = = false) M_startpoint = Qpoint (!m_right? M_startpoint.x () : Event->x (),!m_bottom? M_startpoint.y (): Event->y ()); () () () () () (), Qrect r = rect (); m_left = Qabs (x-r.le FT ()) < 5; M_right = Qabs (X-r.right ()) < 5; M_bottom = Qabs (Y-r.bottom ()) < 5; M_top = Qabs (Y-r.top ()) < 5;        50 BOOL Lorr = M_left | M_right; wuyi bool Torb = M_top | M_bottom; if (Lorr && torb) (M_left && m_top) (M_right && M_bottom))                 SetCursor (qt::sizefdiagcursor); 59 SetCursor (Qt::sizebdiagcursor); (Lorr) SetCursor (qt::sizehorcursor); (Torb) SetCursor (qt::sizevercursor); SetCursor Else (qt::sizeallcursor); m_bottom = M_left = M_right = m_t op = false; The cutshape::mousereleaseevent} (Qmouseevent * event), and the M_mousedown = false; 7     6} cutshape::resizeevent void (Qresizeevent *event), {m_enablerepaint = true; Bayi update (); 82 83 Qwidget::resizeevent (event); Qrect Cutshape::getresizegem (Qrect oldgeo, Qpoint mousepoint, BOOL &Amp  Ignore) (qrect g = oldgeo; Lorr = M_left | m_right; n-bool Torb = M_top | m_bottom; DX = mousepoint.x ()-m_startpoint.x (); The mousepoint.y int dy = n ()-M_startpoint.y (); Ignore = false; 94 if (Lorr && torb)-QMax (Qabs (DX), qabs (DY)) (M_left &&am P M_top && dx*dy > 0) 98 {g.setleft (dx > 0? g.left () + maxlen:g.left ()-maxlen); 10 0 g.settop (dy > 0? g.top () + maxlen:g.top ()-maxlen); 101}102 Else if (m_right &&am P M_top && dx * DY < 0) 103 {104 G.setright (dx > 0? g.right () + maxlen:g.right ()-Maxle n); g.settop (dy > 0? g.top () + maxlen:g.top ()-maxlen); 106}107 Else if (m_right &am  p;& M_bottom) 108 {109 if (dx * dy > 0) {111 g.setright (dx > 0 ? G.right () + maxleN:g.right ()-MaxLen); G.setbottom (dy > 0? g.bottom () + maxlen:g.bottom ()-maxlen); 113             }114 else if (dx = = 0 && dy! = 0115/*| | 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 re         Turn g;127}128 else if (Lorr) 129 {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 I Nthight = (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), G.setright (G.right () + dheigt-intwidth); 151}152 E lse153 {154 ignore = true;155}156 return g;157}

2, Backgroundwidget Background window, the window as the parent window of the clipping window, but there is no layout, the purpose is to allow the shear window to move freely, and remain on the background color window, when the backlight window is redrawn, only in addition to the cut window. This enables the clipping window to be transparent, but the rest is translucent and the code is as follows:

1 void Backgroundwidget::p aintevent (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);     qpainter paint (this);     Paint.setopacity (0.5);     Paint.fillpath (DrawPath, Qbrush (Qt::black)); 15}

3, Picturepreviewpanel image upload Control base class, when the picture is loaded, you need to reset the background color window size, so as to overwrite the image above, the code is as follows:

1 bool Picturepreviewpanel::eventfilter (Qobject * watched, qevent * Event) 2 {3     if (watched = = M_picturecontainer) 4< c1/>{5         if (event->type () = = qevent::resize) 6         {7             loadpicture_p (); 8             if (m_bgwidget) 9             {Ten                 M_bgwidget->resize (M_picturecontainer->size ());             }12         }13     }14     return Qwidget:: EventFilter (watched, event); 15}

The reason why you need to reload the picture is that the picture is loaded by dragging and distorting the loading code as follows:

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 ();     }11}

Well, with the above code, the basic interactive function of the image upload space is finished, click Save to capture the image, you can use the Cutregion method of the clipping EOG class to get the path of the clip, and save it to the specified image format. Effect 2 shows

Figure 2 Effect display

Instance code download: http://download.csdn.net/detail/qq_30392343/9581238

Http://www.cnblogs.com/swarmbees/p/5688885.html

QT Implementation Avatar upload function (wrote 4 classes, ten-to-eight blog, very good)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.