Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qframe.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include "qframe.h"
6#include "qbitmap.h"
7#include "qdrawutil.h"
8#include "qevent.h"
9#include "qpainter.h"
10#include "qstyle.h"
11#include "qstyleoption.h"
12#include "qstylepainter.h"
13#include "qapplication.h"
14
15#include "qframe_p.h"
16
18
19QFramePrivate::QFramePrivate()
20 : frect(0, 0, 0, 0),
21 frameStyle(QFrame::NoFrame | QFrame::Plain),
22 lineWidth(1),
23 midLineWidth(0),
24 frameWidth(0),
25 leftFrameWidth(0), rightFrameWidth(0),
26 topFrameWidth(0), bottomFrameWidth(0)
27{
28}
29
33
34inline void QFramePrivate::init()
35{
36 Q_Q(QFrame);
37 setLayoutItemMargins(QStyle::SE_FrameLayoutItem);
38
39 // The frameRect property is implemented in terms of the widget's
40 // contentsRect, which conflicts with the implicit inclusion of
41 // the safe area margins in the contentsRect.
42 q->setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, false);
43}
44
45/*!
46 \class QFrame
47 \brief The QFrame class is the base class of widgets that can have a frame.
48
49 \ingroup abstractwidgets
50 \inmodule QtWidgets
51
52 QMenu uses this to "raise" the menu above the surrounding
53 screen. QProgressBar has a "sunken" look. QLabel has a flat look.
54 The frames of widgets like these can be changed.
55
56 \snippet code/src_gui_widgets_qframe.cpp 0
57
58 The QFrame class can also be used directly for creating simple
59 placeholder frames without any contents.
60
61 The frame style is specified by a \l{QFrame::Shape}{frame shape} and
62 a \l{QFrame::Shadow}{shadow style} that is used to visually separate
63 the frame from surrounding widgets. These properties can be set
64 together using the setFrameStyle() function and read with frameStyle().
65
66 The frame shapes are \l NoFrame, \l Box, \l Panel, \l StyledPanel,
67 HLine and \l VLine; the shadow styles are \l Plain, \l Raised and
68 \l Sunken.
69
70 A frame widget has three attributes that describe the thickness of the
71 border: \l lineWidth, \l midLineWidth, and \l frameWidth.
72
73 \list
74 \li The line width is the width of the frame border. It can be modified
75 to customize the frame's appearance.
76
77 \li The mid-line width specifies the width of an extra line in the
78 middle of the frame, which uses a third color to obtain a special
79 3D effect. Notice that a mid-line is only drawn for \l Box, \l
80 HLine and \l VLine frames that are raised or sunken.
81
82 \li The frame width is determined by the frame style, and the frameWidth()
83 function is used to obtain the value defined for the style used.
84 \endlist
85
86 The margin between the frame and the contents of the frame can be
87 customized with the QWidget::setContentsMargins() function.
88
89 \target picture
90 This table shows some of the combinations of styles and line widths:
91
92 \image frames.png Table of frame styles
93*/
94
95
96/*!
97 \enum QFrame::Shape
98
99 This enum type defines the shapes of frame available.
100
101 \value NoFrame QFrame draws nothing
102 \value Box QFrame draws a box around its contents
103 \value Panel QFrame draws a panel to make the contents appear
104 raised or sunken
105 \value StyledPanel draws a rectangular panel with a look that
106 depends on the current GUI style. It can be raised or sunken.
107 \value HLine QFrame draws a horizontal line that frames nothing
108 (useful as separator)
109 \value VLine QFrame draws a vertical line that frames nothing
110 (useful as separator)
111 \value WinPanel draws a rectangular panel that can be raised or
112 sunken like those in Windows 2000. Specifying this shape sets
113 the line width to 2 pixels. WinPanel is provided for compatibility.
114 For GUI style independence we recommend using StyledPanel instead.
115
116 When it does not call QStyle, Shape interacts with QFrame::Shadow,
117 the lineWidth() and the midLineWidth() to create the total result.
118 See the picture of the frames in the main class documentation.
119
120 \sa QFrame::Shadow, QFrame::style(), QStyle::drawPrimitive()
121*/
122
123
124/*!
125 \enum QFrame::Shadow
126
127 This enum type defines the types of shadow that are used to give
128 a 3D effect to frames.
129
130 \value Plain the frame and contents appear level with the
131 surroundings; draws using the palette QPalette::WindowText color
132 (without any 3D effect)
133
134 \value Raised the frame and contents appear raised; draws a 3D
135 raised line using the light and dark colors of the current color
136 group
137 \value Sunken the frame and contents appear sunken; draws a 3D
138 sunken line using the light and dark colors of the current color
139 group
140
141 Shadow interacts with QFrame::Shape, the lineWidth() and the
142 midLineWidth(). See the picture of the frames in the main class
143 documentation.
144
145 \sa QFrame::Shape, lineWidth(), midLineWidth()
146*/
147
148/*!
149 \enum QFrame::StyleMask
150
151 This enum defines two constants that can be used to extract the
152 two components of frameStyle():
153
154 \value Shadow_Mask The \l Shadow part of frameStyle()
155 \value Shape_Mask The \l Shape part of frameStyle()
156
157 Normally, you don't need to use these, since frameShadow() and
158 frameShape() already extract the \l Shadow and the \l Shape parts
159 of frameStyle().
160
161 \sa frameStyle(), setFrameStyle()
162*/
163
164/*!
165 Constructs a frame widget with frame style \l NoFrame and a
166 1-pixel frame width.
167
168 The \a parent and \a f arguments are passed to the QWidget
169 constructor.
170*/
171
172QFrame::QFrame(QWidget* parent, Qt::WindowFlags f)
173 : QWidget(*new QFramePrivate, parent, f)
174{
175 Q_D(QFrame);
176 d->init();
177}
178
179/*! \internal */
180QFrame::QFrame(QFramePrivate &dd, QWidget* parent, Qt::WindowFlags f)
181 : QWidget(dd, parent, f)
182{
183 Q_D(QFrame);
184 d->init();
185}
186
187/*!
188 \since 5.5
189
190 Initializes \a option with the values from this QFrame. This method is
191 useful for subclasses when they need a QStyleOptionFrame but don't want to
192 fill in all the information themselves.
193
194 \sa QStyleOption::initFrom()
195*/
196void QFrame::initStyleOption(QStyleOptionFrame *option) const
197{
198 if (!option)
199 return;
200
201 Q_D(const QFrame);
202 option->initFrom(this);
203
204 int frameShape = d->frameStyle & QFrame::Shape_Mask;
205 int frameShadow = d->frameStyle & QFrame::Shadow_Mask;
206 option->frameShape = Shape(int(option->frameShape) | frameShape);
207 option->rect = frameRect();
208 switch (frameShape) {
209 case QFrame::Box:
210 case QFrame::HLine:
211 case QFrame::VLine:
212 case QFrame::StyledPanel:
213 case QFrame::Panel:
214 option->lineWidth = d->lineWidth;
215 option->midLineWidth = d->midLineWidth;
216 break;
217 default:
218 // most frame styles do not handle customized line and midline widths
219 // (see updateFrameWidth()).
220 option->lineWidth = d->frameWidth;
221 break;
222 }
223
224 if (frameShadow == Sunken)
225 option->state |= QStyle::State_Sunken;
226 else if (frameShadow == Raised)
227 option->state |= QStyle::State_Raised;
228}
229
230
231/*!
232 Destroys the frame.
233 */
234QFrame::~QFrame()
235{
236}
237
238/*!
239 Returns the frame style.
240
241 The default value is QFrame::Plain.
242
243 \sa setFrameStyle(), frameShape(), frameShadow()
244*/
245int QFrame::frameStyle() const
246{
247 Q_D(const QFrame);
248 return d->frameStyle;
249}
250
251/*!
252 \property QFrame::frameShape
253 \brief the frame shape value from the frame style
254
255 \sa frameStyle(), frameShadow()
256*/
257
258QFrame::Shape QFrame::frameShape() const
259{
260 Q_D(const QFrame);
261 return (Shape) (d->frameStyle & Shape_Mask);
262}
263
264void QFrame::setFrameShape(QFrame::Shape s)
265{
266 Q_D(QFrame);
267 setFrameStyle((d->frameStyle & Shadow_Mask) | s);
268}
269
270
271/*!
272 \property QFrame::frameShadow
273 \brief the frame shadow value from the frame style
274
275 \sa frameStyle(), frameShape()
276*/
277QFrame::Shadow QFrame::frameShadow() const
278{
279 Q_D(const QFrame);
280 return (Shadow) (d->frameStyle & Shadow_Mask);
281}
282
283void QFrame::setFrameShadow(QFrame::Shadow s)
284{
285 Q_D(QFrame);
286 setFrameStyle((d->frameStyle & Shape_Mask) | s);
287}
288
289/*!
290 Sets the frame style to \a style.
291
292 The \a style is the bitwise OR between a frame shape and a frame
293 shadow style. See the picture of the frames in the main class
294 documentation.
295
296 The frame shapes are given in \l{QFrame::Shape} and the shadow
297 styles in \l{QFrame::Shadow}.
298
299 If a mid-line width greater than 0 is specified, an additional
300 line is drawn for \l Raised or \l Sunken \l Box, \l HLine, and \l
301 VLine frames. The mid-color of the current color group is used for
302 drawing middle lines.
303
304 \sa frameStyle()
305*/
306
307void QFrame::setFrameStyle(int style)
308{
309 Q_D(QFrame);
310 if (!testAttribute(Qt::WA_WState_OwnSizePolicy)) {
311 QSizePolicy sp;
312
313 switch (style & Shape_Mask) {
314 case HLine:
315 sp = QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, QSizePolicy::Line);
316 break;
317 case VLine:
318 sp = QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum, QSizePolicy::Line);
319 break;
320 default:
321 sp = QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::Frame);
322 }
323 setSizePolicy(sp);
324 setAttribute(Qt::WA_WState_OwnSizePolicy, false);
325 }
326 d->frameStyle = (short)style;
327 update();
328 d->updateFrameWidth();
329}
330
331/*!
332 \property QFrame::lineWidth
333 \brief the line width
334
335 Note that the \e total line width for frames used as separators
336 (\l HLine and \l VLine) is specified by \l frameWidth.
337
338 The default value is 1.
339
340 \sa midLineWidth, frameWidth
341*/
342
343void QFrame::setLineWidth(int w)
344{
345 Q_D(QFrame);
346 if (short(w) == d->lineWidth)
347 return;
348 d->lineWidth = short(w);
349 d->updateFrameWidth();
350}
351
352int QFrame::lineWidth() const
353{
354 Q_D(const QFrame);
355 return d->lineWidth;
356}
357
358/*!
359 \property QFrame::midLineWidth
360 \brief the width of the mid-line
361
362 The default value is 0.
363
364 \sa lineWidth, frameWidth
365*/
366
367void QFrame::setMidLineWidth(int w)
368{
369 Q_D(QFrame);
370 if (short(w) == d->midLineWidth)
371 return;
372 d->midLineWidth = short(w);
373 d->updateFrameWidth();
374}
375
376int QFrame::midLineWidth() const
377{
378 Q_D(const QFrame);
379 return d->midLineWidth;
380}
381
382/*!
383 \internal
384 Updates the frame widths from the style.
385*/
387{
388 Q_Q(const QFrame);
389 QStyleOptionFrame opt;
390 q->initStyleOption(&opt);
391
392 QRect cr = q->style()->subElementRect(QStyle::SE_ShapedFrameContents, &opt, q);
393 leftFrameWidth = cr.left() - opt.rect.left();
394 topFrameWidth = cr.top() - opt.rect.top();
395 rightFrameWidth = opt.rect.right() - cr.right(),
396 bottomFrameWidth = opt.rect.bottom() - cr.bottom();
399}
400
401/*!
402 \internal
403 Updated the frameWidth parameter.
404*/
405
407{
408 Q_Q(QFrame);
409 QRect fr = q->frameRect();
411 q->setFrameRect(fr);
412 setLayoutItemMargins(QStyle::SE_FrameLayoutItem);
413}
414
415/*!
416 \property QFrame::frameWidth
417 \brief the width of the frame that is drawn.
418
419 Note that the frame width depends on the \l{QFrame::setFrameStyle()}{frame style},
420 not only the line width and the mid-line width. For example, the style specified
421 by \l NoFrame always has a frame width of 0, whereas the style \l Panel has a
422 frame width equivalent to the line width.
423
424 \sa lineWidth(), midLineWidth(), frameStyle()
425*/
426int QFrame::frameWidth() const
427{
428 Q_D(const QFrame);
429 return d->frameWidth;
430}
431
432
433/*!
434 \property QFrame::frameRect
435 \brief the frame's rectangle
436
437 The frame's rectangle is the rectangle the frame is drawn in. By
438 default, this is the entire widget. Setting the rectangle \e doesn't
439 cause a widget update. The frame rectangle is automatically adjusted
440 when the widget changes size.
441
442 If you set the rectangle to a null rectangle (for example,
443 QRect(0, 0, 0, 0)), then the resulting frame rectangle is
444 equivalent to the \l{QWidget::rect()}{widget rectangle}.
445*/
446
447QRect QFrame::frameRect() const
448{
449 Q_D(const QFrame);
450 QRect fr = contentsRect();
451 fr.adjust(-d->leftFrameWidth, -d->topFrameWidth, d->rightFrameWidth, d->bottomFrameWidth);
452 return fr;
453}
454
455void QFrame::setFrameRect(const QRect &r)
456{
457 Q_D(QFrame);
458 QRect cr = r.isValid() ? r : rect();
459 cr.adjust(d->leftFrameWidth, d->topFrameWidth, -d->rightFrameWidth, -d->bottomFrameWidth);
460 setContentsMargins(cr.left(), cr.top(), rect().right() - cr.right(), rect().bottom() - cr.bottom());
461}
462
463/*!\reimp
464*/
465QSize QFrame::sizeHint() const
466{
467 Q_D(const QFrame);
468 // Returns a size hint for the frame - for HLine and VLine
469 // shapes, this is stretchable one way and 3 pixels wide the
470 // other. For other shapes, QWidget::sizeHint() is used.
471 switch (d->frameStyle & Shape_Mask) {
472 case HLine:
473 return QSize(-1,3);
474 case VLine:
475 return QSize(3,-1);
476 default:
477 return QWidget::sizeHint();
478 }
479}
480
481/*!\reimp
482*/
483
484void QFrame::paintEvent(QPaintEvent *)
485{
486 QStylePainter p(this);
487 drawFrame(&p);
488}
489
490/*!
491 \internal
492
493 Used by QLabel and QLCDNumber
494 */
495void QFrame::drawFrame(QPainter *p)
496{
497 QStyleOptionFrame opt;
498 initStyleOption(&opt);
499 style()->drawControl(QStyle::CE_ShapedFrame, &opt, p, this);
500}
501
502
503/*!\reimp
504 */
505void QFrame::changeEvent(QEvent *ev)
506{
507 Q_D(QFrame);
508 if (ev->type() == QEvent::StyleChange
509#ifdef Q_OS_MAC
510 || ev->type() == QEvent::MacSizeChange
511#endif
512 )
513 d->updateFrameWidth();
514 QWidget::changeEvent(ev);
515}
516
517/*! \reimp */
518bool QFrame::event(QEvent *e)
519{
520 if (e->type() == QEvent::ParentChange)
521 d_func()->updateFrameWidth();
522 bool result = QWidget::event(e);
523 //this has to be done after the widget has been polished
524 if (e->type() == QEvent::Polish)
525 d_func()->updateFrameWidth();
526 return result;
527}
528
529QT_END_NAMESPACE
530
531#include "moc_qframe.cpp"
short frameWidth
Definition qframe_p.h:39
short topFrameWidth
Definition qframe_p.h:41
void updateStyledFrameWidths()
Definition qframe.cpp:386
short bottomFrameWidth
Definition qframe_p.h:41
void updateFrameWidth()
Definition qframe.cpp:406
void init()
Definition qframe.cpp:34
short rightFrameWidth
Definition qframe_p.h:40
short leftFrameWidth
Definition qframe_p.h:40