Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
ImageView UI Designer Code
-
@rb said
Apologies for wasting part of your day with that !
No problem, happy to have helped, sincerely
-
Next question..
If I want to add a custom image in designer for a button not an imageView…
I can’t get the image to load using the same above syntax in custom attributes.Is this something to do with :
.with_rendering_mode(ui.RENDERING_MODE_ORIGINAL)
And if so what would the proper syntax be inside that custom attribute string? So far I just get errors if I add that as an extra string on end of image path.
Also it’s not important that this image is visible in designer just that it works in final use when loaded/used in another view. -
@rb try
import editor import ast import json from objc_util import * import ui @on_main_thread def SetImageInDesigner(): global filenames filenames = {} t = "ui.Image.named('" fil = editor.get_path() #print(fil) with open(fil) as f: dic = json.load(f)[0] nodes = dic['nodes'] for node in nodes: if node['class'] in ['ImageView', 'Button']: attrs = node['attributes']['custom_attributes'] i = attrs.find(t) if i >= 0: j = attrs.find("')", i) img = attrs[i+len(t):j] nam = node['attributes']['name'] filenames[nam] = img win = ObjCClass('UIApplication').sharedApplication().keyWindow() main_view = win.rootViewController().view() def analyze(v,indent): global filenames for sv in v.subviews(): #print(indent,sv._get_objc_classname()) if 'UIImageView' in str(sv._get_objc_classname()): if 'OMUIWidgetViewImageView' in str(sv.superview()._get_objc_classname()): if 'OMUIDesignCanvasView' in str(sv.superview().superview()._get_objc_classname()): w = sv.superview() w.setFrame_(w.superview().frame()) for svw in w.subviews(): if 'UILabel' in str(svw._get_objc_classname()): n = str(svw.text()) break if n in filenames: sv.setImage_(ObjCInstance(ui.Image.named(filenames[n]))) elif 'UIButton' in str(sv._get_objc_classname()): if 'OMUIWidgetViewButton' in str(sv.superview()._get_objc_classname()): if 'OMUIDesignCanvasView' in str(sv.superview().superview()._get_objc_classname()): w = sv.superview() for svw in w.subviews(): if 'UILabel' in str(svw._get_objc_classname()): n = str(svw.text()) break if n in filenames: sv.setImage_forState_(ObjCInstance(ui.Image.named(filenames[n]).with_rendering_mode(ui.RENDERING_MODE_ORIGINAL)),0) analyze(sv,indent+' ') analyze(main_view,'') return if __name__ == '__main__': SetImageInDesigner()
-
@rb You have to know that you can set the image or the background_image of a button.
If you set the background_image, the button title is also visible.The modified tool script sets the image, not the background_image.
If you would prefer to set the background_image or both (not together), tell me, I should need to change the tool script
-
@rb try this version, supporting custom attributes image and background_image but not together
import editor import ast import json from objc_util import * import ui @on_main_thread def SetImageInDesigner(): global filenames filenames = {} t = "ui.Image.named('" fil = editor.get_path() #print(fil) with open(fil) as f: dic = json.load(f)[0] nodes = dic['nodes'] for node in nodes: if node['class'] in ['ImageView', 'Button']: attrs = node['attributes']['custom_attributes'] #print(attrs) i = attrs.find(t) if i >= 0: j = attrs.find("')", i) img = attrs[i+len(t):j] nam = node['attributes']['name'] if node['class'] == 'Button': if "'image'" in attrs: k = 'image' else: k = 'background_image' filenames[nam] = (img,k) else: filenames[nam] = (img,'image') win = ObjCClass('UIApplication').sharedApplication().keyWindow() main_view = win.rootViewController().view() def analyze(v,indent): global filenames for sv in v.subviews(): #print(indent,sv._get_objc_classname()) if 'UIImageView' in str(sv._get_objc_classname()): if 'OMUIWidgetViewImageView' in str(sv.superview()._get_objc_classname()): if 'OMUIDesignCanvasView' in str(sv.superview().superview()._get_objc_classname()): w = sv.superview() w.setFrame_(w.superview().frame()) for svw in w.subviews(): if 'UILabel' in str(svw._get_objc_classname()): n = str(svw.text()) break if n in filenames: sv.setImage_(ObjCInstance(ui.Image.named(filenames[n][0]))) elif 'UIButton' in str(sv._get_objc_classname()): if 'OMUIWidgetViewButton' in str(sv.superview()._get_objc_classname()): if 'OMUIDesignCanvasView' in str(sv.superview().superview()._get_objc_classname()): w = sv.superview() for svw in w.subviews(): if 'UILabel' in str(svw._get_objc_classname()): n = str(svw.text()) break if n in filenames: #print(dir(sv)) if filenames[n][1] == 'image': sv.setImage_forState_(ObjCInstance(ui.Image.named(filenames[n][0]).with_rendering_mode(ui.RENDERING_MODE_ORIGINAL)),0) else: sv.setBackgroundImage_forState_ (ObjCInstance(ui.Image.named(filenames[n][0]).with_rendering_mode(ui.RENDERING_MODE_ORIGINAL)),0) analyze(sv,indent+' ') analyze(main_view,'') return if __name__ == '__main__': SetImageInDesigner()
-
Dude your so generous with your assistance always above and beyond Thankyou ! It’s sunny right now in uk so I’m chillin with my dawg in the garden with a beer - will check this as darkness falls :)
-
-
Found couple of issues.
I had to add the middle line/check:if node['class'] in ['ImageView', 'Button']: if 'custom_attributes' in node['attributes']: attrs = node['attributes']['custom_attributes'] ``` As I have some other buttons without anything in custom_attributes and it was erroring. After changing that I get the images appearing on buttons in designer woop! but unfortunately it still fails when imported as a load_view in my main function with same error ie : Warning: Could not load custom attributes of view "test_btn": 'NoneType' object has no attribute 'with_rendering_mode'
-
Ok it was the path again but it makes no sense to me …
My path was resolved ok in designer using your script but I had to specify a full path to get it working as a load view. I don’t have to do this with the image views they work after I’ve set my file using
os.chdir(os.path.split(__file__)[0])
Anyhow it works so thanks again! -
@rb said
I had to add the middle line/check:
Sorry, shame on me. I'm always in a hurry and I never do enough testing of different cases. You can call me an amateur.
Ok it was the path again but it makes no sense to me …
No idea, don't forget that the code which loads the images is unknown because belonging to Pythonista it-self.