You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We do a lot of custom plugins and forms with roam. The user wants foto loading in our plugins/forms, and we want to use the exceptionally well made ImageWidget available for automatically generated featureforms. Unfortunately, it is not available in the api. It would be nice if it was. Especially since all the internal roam code will change with Roam 3.
I have made a wrapper for the roam ImageWidget that I have been able to use in my plugin, which I am attaching. I hope it will be helpful. If you do not want to incorporate the idea, maybe it has a place in the documentation. I took the code from the Roam 2.7.2 hotfix branch. I pulled the code that featureform.py uses to handle the image widget into a class.
The wrapper assumes that the widget is being added to a QStackedWidget, where the first page of the widget is taken (by the form or plugin layout). The parent widget is the widget containing the QStackedWidget, which is adding the image widget to itself.
The wrapper's implementation looks like this:
from ev_roam_image_widget_wrapper import ImageWidgetWrapper
image_filename = "my_default_image.jpg" # the original/default/saved filename
image_folder = "c:\my_path_to\the\image\directory" # might be roam's, or our own
parent = self # i am the form widget, and I will add the image widget to myself
def setup_image_widget(self):
# create image widget and add it to my form
self.image_wrapper = ImageWidgetWrapper(self.canvas,
self.stackedWidget,
image_filename,
image_folder,
parent)
self.image_widget = self.image_wrapper.qwidget()
row, column = (9, 3)
self.form_widget.layout().addWidget(self.image_widget, row, column) # add the image widget
to the right place in my form
def update_image_value(self):
# get the current filename. if the loaded image has changed, it will
# be saved to the disk at this point
filename = self.image_wrapper.get_saved_image_value()
bk_util.set_value("foto", filename) # save the filename in our way
The wrapper looks like this:
# wraps the roam image widget and its interactions with a stacked widget
# so that the widget can be used in the context of custom forms and plugins
import os
import inspect
import functools
from PyQt4.QtCore import pyqtSignal, QVariant
from PyQt4.QtGui import QPixmap
from roam.api import RoamEvents
from roam.api import utils as qgisutils
import roam
from roam.editorwidgets.imagewidget import ImageWidget
from roam.editorwidgets.uifiles.imagewidget import QMapImageWidget
FeatureSaveException = qgisutils.FeatureSaveException
class ImageWidgetWrapper(object):
form_closed = pyqtSignal(int)
def __init__(self, canvas, stack_widget, image_filename, image_folder, parent_widget=None):
"""
:param canvas: the roam canvas object
:param stack_widget: the QStackedWidget that the large widgets will be appended to
:param image_filename:
:param image_folder:
:param parent_widget:
"""
self.canvas = canvas
self.stackedWidget = stack_widget
self.widgetstack = []
self.image_folder = image_folder
self.image_filename = image_filename
self.image_path = os.path.join(self.image_folder, self.image_filename)
self.image_widget = QMapImageWidget(parent=parent_widget)
self.image_wrapper = None
layer = None
label = None
# The field is just used for information, not for saving data, so we just send in a dummy
field = FakeField("foto")
self.image_object = ImageWidget(self.image_widget, layer, label, field)
self.image_object.initWidget(self.image_widget)
self.image_object.largewidgetrequest.connect(self.add_widget)
pic = QPixmap(self.image_path)
self.image_widget.loadImage(pic, fromfile=True)
def qwidget(self):
# this returns the initialised QMapImageWidget object that can be added into a form
return self.image_widget
def add_widget(self, widgettype, lastvalue, callback, config, initconfig=None, cancel_callback=None):
# from dataentrywidget, which recieves the featureform show_widget signal that
# is emitted on reciept of largewidgetrequest from the editorwidget
if not initconfig:
initconfig = {}
if inspect.isclass(widgettype):
widget = widgettype.createwidget(config=initconfig)
largewidgetwrapper = widgettype.for_widget(widget, None, None, None, None, map=self.canvas)
else:
# If the user passes in a instance we can just use that and trust they have set it up right.
largewidgetwrapper = widgettype
widget = largewidgetwrapper.widget
largewidgetwrapper.finished.connect(callback)
largewidgetwrapper.initWidget(widget)
largewidgetwrapper.config = config
if isinstance(lastvalue, QPixmap):
lastvalue = QPixmap(lastvalue)
largewidgetwrapper.setvalue(lastvalue)
largewidgetwrapper.largewidgetrequest.connect(RoamEvents.show_widget.emit)
largewidgetwrapper.finished.connect(functools.partial(self.cleanup, largewidgetwrapper))
largewidgetwrapper.cancel.connect(functools.partial(self.cleanup, largewidgetwrapper))
if cancel_callback:
largewidgetwrapper.cancel.connect(cancel_callback)
try:
largewidgetwrapper.before_load()
position = self.stackedWidget.addWidget(widget)
self.stackedWidget.setCurrentIndex(position)
self.widgetstack.append(largewidgetwrapper)
largewidgetwrapper.after_load()
except roam.editorwidgets.core.exceptions.RejectedException as rejected:
RoamEvents.raisemessage("Program Error", rejected.message)
self.cleanup(largewidgetwrapper)
def cleanup(self, wrapper, *args):
# Pop the widget off the current widget stack and kill it.
try:
index = self.widgetstack.index(wrapper)
del self.widgetstack[index]
except ValueError:
pass
index = self.stackedWidget.indexOf(wrapper.widget)
if index == -1:
return
self.clearwidget(index)
wrapper.deleteLater()
wrapper.setParent(None)
def clearwidget(self, position=0):
widget = self.stackedWidget.widget(position)
self.stackedWidget.removeWidget(widget)
if widget:
widget.deleteLater()
widget.setParent(None)
self.stackedWidget.setCurrentIndex(0)
def get_saved_image_value(self):
widget = self.image_object
if widget.modified:
self.image_filename = widget.get_filename()
saved = widget.save(self.image_folder, self.image_filename)
if not saved:
raise FeatureSaveException("Image Error",
"Could not save image to {}".format(self.image_folder))
return self.image_filename
class FakeField(object):
def __init__(self, name):
self.field_name = name
def name(self):
return self.field_name
def type(self):
return QVariant.String
The text was updated successfully, but these errors were encountered:
We do a lot of custom plugins and forms with roam. The user wants foto loading in our plugins/forms, and we want to use the exceptionally well made ImageWidget available for automatically generated featureforms. Unfortunately, it is not available in the api. It would be nice if it was. Especially since all the internal roam code will change with Roam 3.
I have made a wrapper for the roam ImageWidget that I have been able to use in my plugin, which I am attaching. I hope it will be helpful. If you do not want to incorporate the idea, maybe it has a place in the documentation. I took the code from the Roam 2.7.2 hotfix branch. I pulled the code that featureform.py uses to handle the image widget into a class.
The wrapper assumes that the widget is being added to a QStackedWidget, where the first page of the widget is taken (by the form or plugin layout). The parent widget is the widget containing the QStackedWidget, which is adding the image widget to itself.
The wrapper's implementation looks like this:
The wrapper looks like this:
The text was updated successfully, but these errors were encountered: