QGIS API Documentation  3.0.2-Girona (307d082)
qgslayoutmultiframe.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutmultiframe.cpp
3  -----------------------
4  begin : October 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgslayoutmultiframe.h"
18 #include "qgslayoutframe.h"
19 #include "qgslayout.h"
21 #include "qgslayoutundostack.h"
22 #include <QtCore>
23 
25  : QgsLayoutObject( layout )
26  , mUuid( QUuid::createUuid().toString() )
27 {
28  mLayout->addMultiFrame( this );
29 
30  connect( mLayout->pageCollection(), &QgsLayoutPageCollection::changed, this, &QgsLayoutMultiFrame::handlePageChange );
31 }
32 
34 {
35  deleteFrames();
36 }
37 
39 {
40  Q_UNUSED( frameIndex );
41  return QSizeF( 0, 0 );
42 }
43 
45 {
46  Q_UNUSED( frameIndex );
47  return QSizeF( 0, 0 );
48 }
49 
51 {
52  return yPos;
53 }
54 
55 void QgsLayoutMultiFrame::addFrame( QgsLayoutFrame *frame, bool recalcFrameSizes )
56 {
57  if ( !frame || mFrameItems.contains( frame ) )
58  return;
59 
60  mFrameItems.push_back( frame );
61  frame->mMultiFrame = this;
63  connect( frame, &QgsLayoutFrame::destroyed, this, [this, frame ]
64  {
65  handleFrameRemoval( frame );
66  } );
67  if ( mLayout && !frame->scene() )
68  {
69  mLayout->addLayoutItem( frame );
70  }
71 
72  if ( recalcFrameSizes )
73  {
75  }
76 }
77 
79 {
80  if ( mode != mResizeMode )
81  {
82  mLayout->undoStack()->beginMacro( tr( "Change Resize Mode" ) );
83  mResizeMode = mode;
85  mLayout->undoStack()->endMacro();
86  emit changed();
87  }
88 }
89 
90 QList<QgsLayoutFrame *> QgsLayoutMultiFrame::frames() const
91 {
92  return mFrameItems;
93 }
94 
96 {
97  if ( mFrameItems.empty() )
98  {
99  return;
100  }
101 
102  QSizeF size = totalSize();
103  double totalHeight = size.height();
104 
105  if ( totalHeight < 1 )
106  {
107  return;
108  }
109 
110  if ( mBlockUndoCommands )
111  mLayout->undoStack()->blockCommands( true );
112 
113  double currentY = 0;
114  double currentHeight = 0;
115  QgsLayoutFrame *currentItem = nullptr;
116 
117  for ( int i = 0; i < mFrameItems.size(); ++i )
118  {
119  if ( mResizeMode != RepeatOnEveryPage && currentY >= totalHeight )
120  {
121  if ( mResizeMode == RepeatUntilFinished || mResizeMode == ExtendToNextPage ) //remove unneeded frames in extent mode
122  {
123  bool removingPages = true;
124  for ( int j = mFrameItems.size(); j > i; --j )
125  {
126  int numPagesBefore = mLayout->pageCollection()->pageCount();
127  removeFrame( j - 1, removingPages );
128  //if removing the frame didn't also remove the page, then stop removing pages
129  removingPages = removingPages && ( mLayout->pageCollection()->pageCount() < numPagesBefore );
130  }
131  return;
132  }
133  }
134 
135  currentItem = mFrameItems.value( i );
136  currentHeight = currentItem->rect().height();
138  {
139  currentItem->setContentSection( QRectF( 0, 0, currentItem->rect().width(), currentHeight ) );
140  }
141  else
142  {
143  currentHeight = findNearbyPageBreak( currentY + currentHeight ) - currentY;
144  currentItem->setContentSection( QRectF( 0, currentY, currentItem->rect().width(), currentHeight ) );
145  }
146  currentItem->update();
147  currentY += currentHeight;
148  }
149 
150  //at end of frames but there is still content left. Add other pages if ResizeMode ==
151  if ( currentItem && mResizeMode != UseExistingFrames )
152  {
153  while ( ( mResizeMode == RepeatOnEveryPage ) || currentY < totalHeight )
154  {
155  //find out on which page the lower left point of the last frame is
156  int page = mLayout->pageCollection()->predictPageNumberForPoint( QPointF( 0, currentItem->pos().y() + currentItem->rect().height() ) ) + 1;
157 
159  {
160  if ( page >= mLayout->pageCollection()->pageCount() )
161  {
162  break;
163  }
164  }
165  else
166  {
167  //add new pages if required
168  for ( int p = mLayout->pageCollection()->pageCount() - 1 ; p < page; ++p )
169  {
170  mLayout->pageCollection()->extendByNewPage();
171  }
172  }
173 
174  double currentPageHeight = mLayout->pageCollection()->page( page )->rect().height();
175 
176  double frameHeight = 0;
177  switch ( mResizeMode )
178  {
179  case RepeatUntilFinished:
180  case RepeatOnEveryPage:
181  {
182  frameHeight = currentItem->rect().height();
183  break;
184  }
185  case ExtendToNextPage:
186  {
187  frameHeight = ( currentY + currentPageHeight ) > totalHeight ? totalHeight - currentY : currentPageHeight;
188  break;
189  }
190 
191  case UseExistingFrames:
192  break;
193  }
194 
195  double newFrameY = mLayout->pageCollection()->page( page )->pos().y();
197  {
198  newFrameY += currentItem->pagePos().y();
199  }
200 
201  //create new frame
202  QgsLayoutFrame *newFrame = createNewFrame( currentItem,
203  QPointF( currentItem->pos().x(), newFrameY ),
204  QSizeF( currentItem->rect().width(), frameHeight ) );
205 
207  {
208  newFrame->setContentSection( QRectF( 0, 0, newFrame->rect().width(), newFrame->rect().height() ) );
209  currentY += frameHeight;
210  }
211  else
212  {
213  double contentHeight = findNearbyPageBreak( currentY + newFrame->rect().height() ) - currentY;
214  newFrame->setContentSection( QRectF( 0, currentY, newFrame->rect().width(), contentHeight ) );
215  currentY += contentHeight;
216  }
217 
218  currentItem = newFrame;
219  }
220  }
221 
222  if ( mBlockUndoCommands )
223  mLayout->undoStack()->blockCommands( false );
224 }
225 
227 {
228  if ( mFrameItems.empty() )
229  {
230  //no frames, nothing to do
231  return;
232  }
233 
234  const QList< QgsLayoutFrame * > frames = mFrameItems;
235  for ( QgsLayoutFrame *frame : frames )
236  {
238  }
239 }
240 
242 {
243 
244 }
245 
246 QgsLayoutFrame *QgsLayoutMultiFrame::createNewFrame( QgsLayoutFrame *currentFrame, QPointF pos, QSizeF size )
247 {
248  if ( !currentFrame )
249  {
250  return nullptr;
251  }
252 
253  QgsLayoutFrame *newFrame = new QgsLayoutFrame( mLayout, this );
254  newFrame->attemptSetSceneRect( QRectF( pos.x(), pos.y(), size.width(), size.height() ) );
255 
256  //copy some settings from the parent frame
257  newFrame->setBackgroundColor( currentFrame->backgroundColor() );
258  newFrame->setBackgroundEnabled( currentFrame->hasBackground() );
259  newFrame->setBlendMode( currentFrame->blendMode() );
260  newFrame->setFrameEnabled( currentFrame->frameEnabled() );
261  newFrame->setFrameStrokeColor( currentFrame->frameStrokeColor() );
262  newFrame->setFrameJoinStyle( currentFrame->frameJoinStyle() );
263  newFrame->setFrameStrokeWidth( currentFrame->frameStrokeWidth() );
264  newFrame->setItemOpacity( currentFrame->itemOpacity() );
265  newFrame->setHideBackgroundIfEmpty( currentFrame->hideBackgroundIfEmpty() );
266 
267  addFrame( newFrame, false );
268 
269  return newFrame;
270 }
271 
273 {
274  return tr( "<Multiframe>" );
275 }
276 
277 QgsAbstractLayoutUndoCommand *QgsLayoutMultiFrame::createCommand( const QString &text, int id, QUndoCommand *parent )
278 {
279  return new QgsLayoutMultiFrameUndoCommand( this, text, id, parent );
280 }
281 
282 void QgsLayoutMultiFrame::beginCommand( const QString &commandText, QgsLayoutMultiFrame::UndoCommand command )
283 {
284  if ( !mLayout )
285  return;
286 
287  mLayout->undoStack()->beginCommand( this, commandText, command );
288 }
289 
291 {
292  if ( mLayout )
293  mLayout->undoStack()->endCommand();
294 }
295 
297 {
298  if ( mLayout )
299  mLayout->undoStack()->cancelCommand();
300 }
301 
303 {
304  for ( int i = 0; i < mFrameUuids.count(); ++i )
305  {
306  QgsLayoutFrame *frame = nullptr;
307  const QString uuid = mFrameUuids.at( i );
308  if ( !uuid.isEmpty() )
309  {
310  QgsLayoutItem *item = mLayout->itemByUuid( uuid, true );
311  frame = qobject_cast< QgsLayoutFrame * >( item );
312  }
313  if ( !frame )
314  {
315  const QString templateUuid = mFrameTemplateUuids.at( i );
316  if ( !templateUuid.isEmpty() )
317  {
318  QgsLayoutItem *item = mLayout->itemByTemplateUuid( templateUuid );
319  frame = qobject_cast< QgsLayoutFrame * >( item );
320  }
321  }
322 
323  if ( frame )
324  {
325  addFrame( frame );
326  }
327  }
328 }
329 
331 {
334 }
335 
336 void QgsLayoutMultiFrame::handleFrameRemoval( QgsLayoutFrame *frame )
337 {
338  if ( mBlockUpdates )
339  return;
340 
341  if ( !frame )
342  {
343  return;
344  }
345  int index = mFrameItems.indexOf( frame );
346  if ( index == -1 )
347  {
348  return;
349  }
350 
351  mFrameItems.removeAt( index );
352  if ( !mFrameItems.isEmpty() )
353  {
354  if ( resizeMode() != QgsLayoutMultiFrame::RepeatOnEveryPage && !mIsRecalculatingSize )
355  {
356  //removing a frame forces the multi frame to UseExistingFrames resize mode
357  //otherwise the frame may not actually be removed, leading to confusing ui behavior
359  emit changed();
361  }
362  }
363 }
364 
365 void QgsLayoutMultiFrame::handlePageChange()
366 {
367  if ( mLayout->pageCollection()->pageCount() < 1 )
368  {
369  return;
370  }
371 
373  {
374  return;
375  }
376 
377  //remove items beginning on non-existing pages
378  for ( int i = mFrameItems.size() - 1; i >= 0; --i )
379  {
380  QgsLayoutFrame *frame = mFrameItems.at( i );
381  int page = mLayout->pageCollection()->predictPageNumberForPoint( frame->pos() );
382  if ( page >= mLayout->pageCollection()->pageCount() )
383  {
384  removeFrame( i );
385  }
386  }
387 
388  //page number of the last item
389  QgsLayoutFrame *lastFrame = mFrameItems.last();
390  int lastItemPage = mLayout->pageCollection()->predictPageNumberForPoint( lastFrame->pos() );
391 
392  for ( int i = lastItemPage + 1; i < mLayout->pageCollection()->pageCount(); ++i )
393  {
394  //copy last frame to current page
395  std::unique_ptr< QgsLayoutFrame > newFrame = qgis::make_unique< QgsLayoutFrame >( mLayout, this );
396 
397  newFrame->attemptSetSceneRect( QRectF( lastFrame->pos().x(),
398  mLayout->pageCollection()->page( i )->pos().y() + lastFrame->pagePos().y(),
399  lastFrame->rect().width(), lastFrame->rect().height() ) );
400  lastFrame = newFrame.get();
401  addFrame( newFrame.release(), false );
402  }
403 
405  update();
406 }
407 
408 void QgsLayoutMultiFrame::removeFrame( int i, const bool removeEmptyPages )
409 {
410  if ( i >= mFrameItems.count() )
411  {
412  return;
413  }
414 
415  QgsLayoutFrame *frameItem = mFrameItems.at( i );
416  if ( mLayout )
417  {
418  mIsRecalculatingSize = true;
419  int pageNumber = frameItem->page();
420  //remove item, but don't create undo command
421  mLayout->undoStack()->blockCommands( true );
422  mLayout->removeLayoutItem( frameItem );
423  //if frame was the only item on the page, remove the page
424  if ( removeEmptyPages && mLayout->pageCollection()->pageIsEmpty( pageNumber ) )
425  {
426  mLayout->pageCollection()->deletePage( pageNumber );
427  }
428  mLayout->undoStack()->blockCommands( false );
429  mIsRecalculatingSize = false;
430  }
431  mFrameItems.removeAt( i );
432 }
433 
435 {
436  for ( QgsLayoutFrame *frame : qgis::as_const( mFrameItems ) )
437  {
438  frame->update();
439  }
440 }
441 
443 {
444  mBlockUpdates = true;
445  ResizeMode bkResizeMode = mResizeMode;
447  mLayout->undoStack()->blockCommands( true );
448  for ( QgsLayoutFrame *frame : qgis::as_const( mFrameItems ) )
449  {
450  mLayout->removeLayoutItem( frame );
451  }
452  mLayout->undoStack()->blockCommands( false );
453  mFrameItems.clear();
454  mResizeMode = bkResizeMode;
455  mBlockUpdates = false;
456 }
457 
459 {
460  if ( i < 0 || i >= mFrameItems.size() )
461  {
462  return nullptr;
463  }
464  return mFrameItems.at( i );
465 }
466 
468 {
469  return mFrameItems.indexOf( frame );
470 }
471 
472 bool QgsLayoutMultiFrame::writeXml( QDomElement &parentElement, QDomDocument &doc, const QgsReadWriteContext &context, bool includeFrames ) const
473 {
474  QDomElement element = doc.createElement( QStringLiteral( "LayoutMultiFrame" ) );
475  element.setAttribute( QStringLiteral( "resizeMode" ), mResizeMode );
476  element.setAttribute( QStringLiteral( "uuid" ), mUuid );
477  element.setAttribute( QStringLiteral( "templateUuid" ), mUuid );
478  element.setAttribute( QStringLiteral( "type" ), type() );
479 
480  for ( QgsLayoutFrame *frame : mFrameItems )
481  {
482  if ( !frame )
483  continue;
484 
485  QDomElement childItem = doc.createElement( QStringLiteral( "childFrame" ) );
486  childItem.setAttribute( QStringLiteral( "uuid" ), frame->uuid() );
487  childItem.setAttribute( QStringLiteral( "templateUuid" ), frame->uuid() );
488 
489  if ( includeFrames )
490  {
491  frame->writeXml( childItem, doc, context );
492  }
493 
494  element.appendChild( childItem );
495  }
496 
497  writeObjectPropertiesToElement( element, doc, context );
498  writePropertiesToElement( element, doc, context );
499  parentElement.appendChild( element );
500  return true;
501 }
502 
503 bool QgsLayoutMultiFrame::readXml( const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context, bool includeFrames )
504 {
505  if ( element.nodeName() != QStringLiteral( "LayoutMultiFrame" ) )
506  {
507  return false;
508  }
509 
510  mBlockUndoCommands = true;
511  mLayout->undoStack()->blockCommands( true );
512 
513  readObjectPropertiesFromElement( element, doc, context );
514 
515  mUuid = element.attribute( QStringLiteral( "uuid" ), QUuid::createUuid().toString() );
516  mTemplateUuid = element.attribute( QStringLiteral( "templateUuid" ), QUuid::createUuid().toString() );
517  mResizeMode = static_cast< ResizeMode >( element.attribute( QStringLiteral( "resizeMode" ), QStringLiteral( "0" ) ).toInt() );
518 
519  deleteFrames();
520  mFrameUuids.clear();
521  mFrameTemplateUuids.clear();
522  QDomNodeList elementNodes = element.elementsByTagName( QStringLiteral( "childFrame" ) );
523  for ( int i = 0; i < elementNodes.count(); ++i )
524  {
525  QDomNode elementNode = elementNodes.at( i );
526  if ( !elementNode.isElement() )
527  continue;
528 
529  QDomElement frameElement = elementNode.toElement();
530 
531  QString uuid = frameElement.attribute( QStringLiteral( "uuid" ) );
532  mFrameUuids << uuid;
533  QString templateUuid = frameElement.attribute( QStringLiteral( "templateUuid" ) );
534  mFrameTemplateUuids << templateUuid;
535 
536  if ( includeFrames )
537  {
538  QDomNodeList frameNodes = frameElement.elementsByTagName( QStringLiteral( "LayoutItem" ) );
539  if ( !frameNodes.isEmpty() )
540  {
541  QDomElement frameItemElement = frameNodes.at( 0 ).toElement();
542  std::unique_ptr< QgsLayoutFrame > newFrame = qgis::make_unique< QgsLayoutFrame >( mLayout, this );
543  newFrame->readXml( frameItemElement, doc, context );
544  addFrame( newFrame.release(), false );
545  }
546  }
547  }
548 
549  bool result = readPropertiesFromElement( element, doc, context );
550 
551  mBlockUndoCommands = false;
552  mLayout->undoStack()->blockCommands( false );
553  return result;
554 }
555 
556 bool QgsLayoutMultiFrame::writePropertiesToElement( QDomElement &, QDomDocument &, const QgsReadWriteContext & ) const
557 {
558  return true;
559 }
560 
561 bool QgsLayoutMultiFrame::readPropertiesFromElement( const QDomElement &, const QDomDocument &, const QgsReadWriteContext & )
562 {
563 
564  return true;
565 }
566 
void setBlendMode(const QPainter::CompositionMode mode)
Sets the item&#39;s composition blending mode.
QgsLayoutMultiFrame(QgsLayout *layout)
Construct a new multiframe item, attached to the specified layout.
QString uuid() const
Returns the multiframe identification string.
The class is used as a container of context for various read/write operations on other objects...
virtual QSizeF totalSize() const =0
Returns the total size of the multiframe&#39;s content, in layout units.
void refresh() override
Refreshes the multiframe, causing a recalculation of any property overrides.
virtual QSizeF fixedFrameSize(const int frameIndex=-1) const
Returns the fixed size for a frame, if desired.
Base class for graphical items within a QgsLayout.
bool readObjectPropertiesFromElement(const QDomElement &parentElement, const QDomDocument &document, const QgsReadWriteContext &context)
Sets object properties from a DOM element.
Base class for commands to undo/redo layout and layout object changes.
int frameIndex(QgsLayoutFrame *frame) const
Returns the index of a frame within the multiframe.
virtual bool writePropertiesToElement(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Stores multiframe state within an XML DOM element.
bool readXml(const QDomElement &itemElement, const QDomDocument &document, const QgsReadWriteContext &context, bool includeFrames=false)
Sets the item state from a DOM element.
QgsLayoutFrame * createNewFrame(QgsLayoutFrame *currentFrame, QPointF pos, QSizeF size)
Creates a new frame and adds it to the multi frame and layout.
QList< QgsLayoutFrame * > frames() const
Returns a list of all child frames for this multiframe.
bool frameEnabled() const
Returns true if the item includes a frame.
Don&#39;t automatically create new frames, just use existing frames.
void beginCommand(const QString &commandText, UndoCommand command=UndoNone)
Starts new undo command for this item.
void deleteFrames()
Removes and deletes all child frames.
QList< QgsLayoutFrame * > mFrameItems
void changed()
Emitted when pages are added or removed from the collection.
void setFrameStrokeColor(const QColor &color)
Sets the frame stroke color.
void recalculateFrameRects()
Forces a recalculation of all the associated frame&#39;s scene rectangles.
Creates new full page frames on the following page(s) until the entire multiframe content is visible...
void setContentSection(const QRectF &section)
Sets the visible part of the multiframe&#39;s content which is visible within this frame (relative to the...
QgsLayoutMeasurement frameStrokeWidth() const
Returns the frame&#39;s stroke width.
void refreshItemSize()
Refreshes an item&#39;s size by rechecking it against any possible item fixed or minimum sizes...
void sizePositionChanged()
Emitted when the item&#39;s size or position changes.
bool writeXml(QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context) const
Stores the item state in a DOM element.
QgsAbstractLayoutUndoCommand * createCommand(const QString &text, int id, QUndoCommand *parent=nullptr) override
Creates a new layout undo command with the specified text and parent.
bool hasBackground() const
Returns true if the item has a background.
Repeats the same frame on every page.
void attemptSetSceneRect(const QRectF &rect, bool includesFrame=false)
Attempts to update the item&#39;s position and size to match the passed rect in layout coordinates...
void setResizeMode(ResizeMode mode)
Sets the resize mode for the multiframe, and recalculates frame sizes to match.
QColor backgroundColor() const
Returns the background color for this item.
QPointer< QgsLayout > mLayout
int page() const
Returns the page the item is currently on, with the first page returning 0.
virtual void setFrameStrokeWidth(const QgsLayoutMeasurement &width)
Sets the frame stroke width.
double itemOpacity() const
Returns the item&#39;s opacity.
QPainter::CompositionMode blendMode() const
Returns the item&#39;s composition blending mode.
void setHideBackgroundIfEmpty(const bool hideBackgroundIfEmpty)
Sets whether the background and frame stroke should be hidden if this frame is empty.
virtual void finalizeRestoreFromXml()
Called after all pending items have been restored from XML.
void endCommand()
Completes the current item command and push it onto the layout&#39;s undo stack.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:49
QColor frameStrokeColor() const
Returns the frame&#39;s stroke color.
virtual void recalculateFrameSizes()
Recalculates the portion of the multiframe item which is shown in each of its component frames...
void setBackgroundEnabled(bool drawBackground)
Sets whether this item has a background drawn under it or not.
QgsLayoutFrame * frame(int index) const
Returns the child frame at a specified index from the multiframe.
virtual bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context)
Sets multiframe state from a DOM element.
QPointF pagePos() const
Returns the item&#39;s position (in layout units) relative to the top left corner of its current page...
bool writeObjectPropertiesToElement(QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context) const
Stores object properties within an XML DOM element.
virtual QString displayName() const
Returns the multiframe display name.
void setFrameJoinStyle(const Qt::PenJoinStyle style)
Sets the join style used when drawing the item&#39;s frame.
ResizeMode
Specifies the behavior for creating new frames to fit the multiframe&#39;s content.
virtual double findNearbyPageBreak(double yPos)
Finds the optimal position to break a frame at.
Qt::PenJoinStyle frameJoinStyle() const
Returns the join style used for drawing the item&#39;s frame.
virtual QSizeF minFrameSize(const int frameIndex=-1) const
Returns the minimum size for a frames, if desired.
void update()
Forces a redraw of all child frames.
ResizeMode resizeMode() const
Returns the resize mode for the multiframe.
virtual int type() const =0
Returns unique multiframe type id.
virtual QString uuid() const
Returns the item identification string.
void removeFrame(int index, bool removeEmptyPages=false)
Removes a frame by index from the multiframe.
virtual void setFrameEnabled(bool drawFrame)
Sets whether this item has a frame drawn around it or not.
bool writeXml(QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context, bool includeFrames=false) const
Stores the multiframe state in a DOM element.
A base class for objects which belong to a layout.
bool hideBackgroundIfEmpty() const
Returns whether the background and frame stroke should be hidden if this frame is empty...
virtual void refreshDataDefinedProperty(const QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::AllProperties)
Refreshes a data defined property for the multi frame by reevaluating the property&#39;s value and redraw...
UndoCommand
Multiframe item undo commands, used for collapsing undo commands.
virtual void addFrame(QgsLayoutFrame *frame, bool recalcFrameSizes=true)
Adds a frame to the multiframe.
virtual void refresh()
Refreshes the object, causing a recalculation of any property overrides.
void changed()
Emitted when the object&#39;s properties change.
DataDefinedProperty
Data defined properties for different item types.
Base class for frame items, which form a layout multiframe item.
void setItemOpacity(double opacity)
Sets the item&#39;s opacity.
void cancelCommand()
Cancels the current item command and discards it.
void setBackgroundColor(const QColor &color)
Sets the background color for this item.