Skip to content

Commit

Permalink
Add workaround for loading forms with custom widgets from PyQt4
Browse files Browse the repository at this point in the history
	More information: qt-project.org/forums/viewthread/27098/
  • Loading branch information
NathanW2 committed Apr 25, 2013
1 parent 9e57117 commit e0838b0
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 0 deletions.
2 changes: 2 additions & 0 deletions python/gui/qgisinterface.sip
Expand Up @@ -427,6 +427,8 @@ class QgisInterface : QObject
virtual bool openFeatureForm( QgsVectorLayer *l, QgsFeature &f, bool updateFeatureOnly = false ) = 0;

virtual QDialog* getFeatureForm( QgsVectorLayer *l, QgsFeature &f ) = 0;

virtual void preloadForm(QString uifile) = 0;
/** Return vector layers in edit mode
* @param modified whether to return only layers that have been modified
* @returns list of layers in legend order, or empty list
Expand Down
34 changes: 34 additions & 0 deletions src/app/qgisappinterface.cpp
Expand Up @@ -21,6 +21,9 @@
#include <QMenu>
#include <QDialog>
#include <QAbstractButton>
#include <QSignalMapper>
#include <QTimer>
#include <QUiLoader>

#include "qgisappinterface.h"
#include "qgisappstylesheet.h"
Expand Down Expand Up @@ -541,6 +544,37 @@ bool QgisAppInterface::openFeatureForm( QgsVectorLayer *vlayer, QgsFeature &f, b
}
}

void QgisAppInterface::preloadForm( QString uifile )
{
QSignalMapper* signalMapper = new QSignalMapper ( this );
mTimer = new QTimer(this);

connect( mTimer ,SIGNAL( timeout() ), signalMapper,SLOT( map() ) );
connect( signalMapper, SIGNAL( mapped(QString) ), mTimer, SLOT( stop() ) );
connect( signalMapper, SIGNAL( mapped(QString) ), this, SLOT( cacheloadForm( QString ) ) );

signalMapper->setMapping( mTimer, uifile );

mTimer->start(0);
}

void QgisAppInterface::cacheloadForm( QString uifile )
{
QUiLoader loader;

QFile file( uifile );

if ( file.open( QFile::ReadOnly ) )
{
QUiLoader loader;

QFileInfo fi( uifile );
loader.setWorkingDirectory( fi.dir() );
QWidget *myWidget = loader.load( &file );
file.close();
}
}

QDialog* QgisAppInterface::getFeatureForm( QgsVectorLayer *l, QgsFeature &f )
{
QgsDistanceArea myDa;
Expand Down
19 changes: 19 additions & 0 deletions src/app/qgisappinterface.h
Expand Up @@ -382,6 +382,19 @@ class QgisAppInterface : public QgisInterface

virtual QDialog* getFeatureForm( QgsVectorLayer *l, QgsFeature &f );

/** This method is only needed when using a UI form with a custom widget plugin and calling
* openFeatureForm or getFeatureForm from Python (PyQt4) and you havn't used the info tool first.
* Python will crash bringing QGIS wtih it
* if the custom form is not loaded from a C++ method call.
*
* This method uses a QTimer to call QUiLoader in order to load the form via C++
* you only need to call this once after that you can call openFeatureForm/getFeatureForm
* like normal
*
* More information here: http://qt-project.org/forums/viewthread/27098/
*/
virtual void preloadForm(QString uifile);

/** Return vector layers in edit mode
* @param modified whether to return only layers that have been modified
* @returns list of layers in legend order, or empty list
Expand All @@ -395,6 +408,10 @@ class QgisAppInterface : public QgisInterface
signals:
void currentThemeChanged( QString );

private slots:

void cacheloadForm( QString uifile );

private:

/// QgisInterface aren't copied
Expand All @@ -406,6 +423,8 @@ class QgisAppInterface : public QgisInterface
//! Pointer to the QgisApp object
QgisApp *qgis;

QTimer *mTimer;

//! Pointer to the LegendInterface object
QgsAppLegendInterface legendIface;
};
Expand Down
2 changes: 2 additions & 0 deletions src/gui/qgisinterface.h
Expand Up @@ -477,6 +477,8 @@ class GUI_EXPORT QgisInterface : public QObject

virtual QDialog* getFeatureForm( QgsVectorLayer *l, QgsFeature &f ) = 0;

virtual void preloadForm( QString uifile ) = 0;

/** Return vector layers in edit mode
* @param modified whether to return only layers that have been modified
* @returns list of layers in legend order, or empty list
Expand Down

0 comments on commit e0838b0

Please sign in to comment.