mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-17 00:04:02 -04:00
Fix action column widget rendering artifacts
This creates an action column widget when the widget is rendered for the first time. The original approach was to create an image and render the buffered image onto the cell until the first mouse action triggered the creation of the real widget. This led to several rendering problems and triggered some strange ownership issues with crashes under certain situations. Followup a05b2ad9
This commit is contained in:
parent
6d1e554206
commit
3fcabc96fe
@ -40,8 +40,14 @@ class QgsAttributeTableDelegate : QItemDelegate
|
||||
|
||||
void setFeatureSelectionModel( QgsFeatureSelectionModel* featureSelectionModel );
|
||||
|
||||
signals:
|
||||
/**
|
||||
* Set an image that represents an action widget
|
||||
* Is emitted when an action column item is painted.
|
||||
* The consumer of this signal can initialize the index widget.
|
||||
*
|
||||
* @note This signal is emitted repeatedly whenever the item is being painted.
|
||||
* It is the consumers responsibility to check if initialization has already
|
||||
* happened before.
|
||||
*/
|
||||
void setActionWidgetImage( const QImage& image );
|
||||
void actionColumnItemPainted( const QModelIndex& index ) const;
|
||||
};
|
||||
|
@ -118,20 +118,13 @@ void QgsAttributeTableDelegate::setFeatureSelectionModel( QgsFeatureSelectionMod
|
||||
mFeatureSelectionModel = featureSelectionModel;
|
||||
}
|
||||
|
||||
void QgsAttributeTableDelegate::setActionWidgetImage( const QImage& image )
|
||||
{
|
||||
mActionWidgetImage = image;
|
||||
}
|
||||
|
||||
|
||||
void QgsAttributeTableDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
QgsAttributeTableFilterModel::ColumnType columnType = static_cast<QgsAttributeTableFilterModel::ColumnType>( index.model()->data( index, QgsAttributeTableFilterModel::TypeRole ).toInt() );
|
||||
|
||||
if ( columnType == QgsAttributeTableFilterModel::ColumnTypeActionButton )
|
||||
{
|
||||
QRect r = option.rect.adjusted( -1, 0, 0, 0 );
|
||||
painter->drawImage( r.x(), r.y(), mActionWidgetImage );
|
||||
emit actionColumnItemPainted( index );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -77,15 +77,20 @@ class GUI_EXPORT QgsAttributeTableDelegate : public QItemDelegate
|
||||
|
||||
void setFeatureSelectionModel( QgsFeatureSelectionModel* featureSelectionModel );
|
||||
|
||||
signals:
|
||||
/**
|
||||
* Set an image that represents an action widget
|
||||
* Is emitted when an action column item is painted.
|
||||
* The consumer of this signal can initialize the index widget.
|
||||
*
|
||||
* @note This signal is emitted repeatedly whenever the item is being painted.
|
||||
* It is the consumers responsibility to check if initialization has already
|
||||
* happened before.
|
||||
*/
|
||||
void setActionWidgetImage( const QImage& image );
|
||||
void actionColumnItemPainted( const QModelIndex& index ) const;
|
||||
|
||||
private:
|
||||
QgsVectorLayer* mLayer;
|
||||
QgsFeatureSelectionModel* mFeatureSelectionModel;
|
||||
QImage mActionWidgetImage;
|
||||
};
|
||||
|
||||
#endif //QGSATTRIBUTETABLEDELEGATE_H
|
||||
|
@ -35,15 +35,12 @@
|
||||
|
||||
QgsAttributeTableView::QgsAttributeTableView( QWidget *parent )
|
||||
: QTableView( parent )
|
||||
, mMasterModel( nullptr )
|
||||
, mFilterModel( nullptr )
|
||||
, mFeatureSelectionModel( nullptr )
|
||||
, mFeatureSelectionManager( nullptr )
|
||||
, mModel( nullptr )
|
||||
, mActionPopup( nullptr )
|
||||
, mRowSectionAnchor( 0 )
|
||||
, mCtrlDragSelectionFlag( QItemSelectionModel::Select )
|
||||
, mActionWidget( nullptr )
|
||||
{
|
||||
QSettings settings;
|
||||
restoreGeometry( settings.value( "/BetterAttributeTable/geometry" ).toByteArray() );
|
||||
@ -52,8 +49,6 @@ QgsAttributeTableView::QgsAttributeTableView( QWidget *parent )
|
||||
horizontalHeader()->setHighlightSections( false );
|
||||
|
||||
// We need mouse move events to create the action button on hover
|
||||
setMouseTracking( true );
|
||||
|
||||
mTableDelegate = new QgsAttributeTableDelegate( this );
|
||||
setItemDelegate( mTableDelegate );
|
||||
|
||||
@ -121,6 +116,7 @@ void QgsAttributeTableView::setModel( QgsAttributeTableFilterModel* filterModel
|
||||
if ( mFilterModel )
|
||||
{
|
||||
connect( mFilterModel, SIGNAL( destroyed() ), this, SLOT( modelDeleted() ) );
|
||||
connect( mTableDelegate, SIGNAL( actionColumnItemPainted( QModelIndex ) ), this, SLOT( onActionColumnItemPainted( QModelIndex ) ) );
|
||||
}
|
||||
|
||||
delete mFeatureSelectionModel;
|
||||
@ -138,10 +134,6 @@ void QgsAttributeTableView::setModel( QgsAttributeTableFilterModel* filterModel
|
||||
mTableDelegate->setFeatureSelectionModel( mFeatureSelectionModel );
|
||||
connect( mFeatureSelectionModel, SIGNAL( requestRepaint( QModelIndexList ) ), this, SLOT( repaintRequested( QModelIndexList ) ) );
|
||||
connect( mFeatureSelectionModel, SIGNAL( requestRepaint() ), this, SLOT( repaintRequested() ) );
|
||||
|
||||
mActionWidget.reset( createActionWidget( 0 ) );
|
||||
mActionWidget->setVisible( false );
|
||||
updateActionImage( mActionWidget.data() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,15 +230,6 @@ void QgsAttributeTableView::mouseReleaseEvent( QMouseEvent *event )
|
||||
|
||||
void QgsAttributeTableView::mouseMoveEvent( QMouseEvent *event )
|
||||
{
|
||||
QModelIndex index = indexAt( event->pos() );
|
||||
if ( index.data( QgsAttributeTableFilterModel::TypeRole ) == QgsAttributeTableFilterModel::ColumnTypeActionButton )
|
||||
{
|
||||
Q_ASSERT( index.isValid() );
|
||||
|
||||
if ( !indexWidget( index ) )
|
||||
setIndexWidget( index, createActionWidget( mFilterModel->data( index, QgsAttributeTableModel::FeatureIdRole ).toLongLong() ) );
|
||||
}
|
||||
|
||||
setSelectionMode( QAbstractItemView::NoSelection );
|
||||
QTableView::mouseMoveEvent( event );
|
||||
setSelectionMode( QAbstractItemView::ExtendedSelection );
|
||||
@ -396,18 +379,13 @@ void QgsAttributeTableView::actionTriggered()
|
||||
void QgsAttributeTableView::columnSizeChanged( int index, int oldWidth, int newWidth )
|
||||
{
|
||||
Q_UNUSED( oldWidth )
|
||||
if ( mFilterModel->actionColumnIndex() == index )
|
||||
{
|
||||
mActionWidget->resize( newWidth, mActionWidget->height() );
|
||||
updateActionImage( mActionWidget.data() );
|
||||
}
|
||||
emit columnResized( index, newWidth );
|
||||
}
|
||||
|
||||
void QgsAttributeTableView::updateActionImage( QWidget* widget )
|
||||
void QgsAttributeTableView::onActionColumnItemPainted( const QModelIndex& index )
|
||||
{
|
||||
QImage image( widget->size(), QImage::Format_ARGB32_Premultiplied );
|
||||
QPainter painter( &image );
|
||||
widget->render( &painter );
|
||||
mTableDelegate->setActionWidgetImage( image );
|
||||
if ( !indexWidget( index ) )
|
||||
{
|
||||
setIndexWidget( index, createActionWidget( mFilterModel->data( index, QgsAttributeTableModel::FeatureIdRole ).toLongLong() ) );
|
||||
}
|
||||
}
|
||||
|
@ -155,22 +155,20 @@ class GUI_EXPORT QgsAttributeTableView : public QTableView
|
||||
void showHorizontalSortIndicator();
|
||||
void actionTriggered();
|
||||
void columnSizeChanged( int index, int oldWidth, int newWidth );
|
||||
void onActionColumnItemPainted( const QModelIndex& index );
|
||||
|
||||
private:
|
||||
void updateActionImage( QWidget* widget );
|
||||
QWidget* createActionWidget( QgsFeatureId fid );
|
||||
|
||||
void selectRow( int row, bool anchor );
|
||||
QgsAttributeTableModel* mMasterModel;
|
||||
QgsAttributeTableFilterModel* mFilterModel;
|
||||
QgsFeatureSelectionModel* mFeatureSelectionModel;
|
||||
QgsIFeatureSelectionManager* mFeatureSelectionManager;
|
||||
QgsAttributeTableDelegate* mTableDelegate;
|
||||
QAbstractItemModel* mModel; // Most likely the filter model
|
||||
QMenu *mActionPopup;
|
||||
int mRowSectionAnchor;
|
||||
QItemSelectionModel::SelectionFlag mCtrlDragSelectionFlag;
|
||||
QScopedPointer<QWidget> mActionWidget;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user