KanvasBuddy - a Minimalist Toolbar

i mean this

I haven’t looked at the fix yet, but moving the button to the top row should be doable. As far as I remember correctly it just needs to be placed in a file in a different location and I think it was the ā€œkanvasbuddy.iniā€, I’ll check after I get back from the hospital.

Michelist

2 Likes

cool thanks

I haven’t fixed anything - only figured out where the error was. I’ll see if I can get the functionality back, but I’m not a coder so can only do the intuitive stuff i.e. extrapolate, copy and paste! :wink:

I’m not sure how to make that change your asking about - but hopefully Michelist can figure it out!

1 Like

Oops 1, with Labi’s joyful question I thought there would be a fix - too bad, but maybe there will be one day (probably not from me, but who knows)?

Oops 2, I should have looked at Labi’s picture first. No I can’t move this button so easily (yet?), at least not off the top of my head.
But it is possible to swap the buttons of the lower and the upper row(s), but for Labi’s wish from his photo you have to ā€œdig deeperā€ - well, maybe I’ll find it anyway.

But now I have to sleep, in 4 hours I will be woken up, two hours after that I will be picked up by the ambulance and after another hour I will lie, under general anesthesia, on the operating table.

Bye, see you soon, I’ll report back here on KA when I can think clearly again. :slight_smile:
Michelist

1 Like

ok, thank you
its not urgent.
Good luck with your operation!!!.
Cheers!!!

1 Like

image image

I made a few minor modifications and now it works :slightly_smiling_face:

I leave the patch: KanvasBuddy - patch

4 Likes

cool thanks!

could you make this???

I’ll ask a friend who knows python for help :grinning_face_with_smiling_eyes:

1 Like

cool thanks!

Hello, I’m testing it (very cool even in regular mode as quick settings docker is much to big to my opinion) but in the new beta Krita 5.0, it crashes.

If you had read this topic completely, :wink: you would know that this plugin works only with the help of a small patch in Krita 5.

To find this patch it was enough to scroll up 5 posts… :joy: :rofl:

With the files included in the patch archive you have to overwrite the two files in the installed KanvasBuddy directory which you can find in the resources’ folder named ā€œpykritaā€. After you applied the patch, you can start Krita, and KanvasBuddy should work as before.

Michelist

1 Like

Thanks a lot. But as KanvasBuddy is on Github, I supposed this kind of patch would have been integrated in the files - or proposed as new pack.
I wrote here a long text about how it is quite difficult for a newbie to manage informations about such plugins but I don’t want to be considered as a troll - and I respect the hard work from the developers. I will try to found a solution to help noobs like me discovering Krita’s plugins.

Oh well Kapyia is the original plugin developer and is not active, so that’s why there are no plugin updates on github.

1 Like

Hi, I am not really knowledgeable regarding scripting but I wanted to ask if it is currently possible to get kanvasbuddy for krita on tablets(mobile). As far as I see scripting isn’t implemented there, right?

1 Like

Sorry if this ends up as a bit of a big post, but I’m stumped trying to add freehand selection to panel section, and deselect to canvas section. Was able to add in reset rotation and preserve alpha, and they work fine, only because of, thankfully, the answers being in this thread.

config.ini

[PANELS]
presetChooser=1
advancedColor=1
# artisticColor=0 Broken; refuses to resize properly
digitalColors=0
specificColors=0
palette=1
layers=1
quickSettings=0
toolOptions=1
animation=0
onionSkins=0
comicsProject=0
svgSymbols=0
arrange=0
lut=0
history=0
freehandSelection=1

[SLIDERS]
brushSize=1
brushOpacity=1
brushFlow=0
canvasRotation=1

[CANVAS]
canvasOnly=1
mirrorCanvas=1
preserveAlpha=1
resetZoom=1
wrapAround=0
instantPreview=0
resetRotation=1
deselect=1

data.json

{
    "panels": {
        "presetChooser": {
            "id": "PresetDocker",
            "icon": "paintop_settings_01",
            "size": [260, 335]
        },
        "advancedColor": {
            "id": "ColorSelectorNg",
            "icon": "krita_tool_color_sampler",
            "size": [290, 290]
        },
        "artisticColor": {
            "id": "ArtisticColorSelector",
            "icon": "wheel-sectors",
            "size": []
        },
        "digitalColors": {
            "id": "DigitalMixer",
            "icon": "krita_tool_gradient",
            "size": []
        },
        "specificColors": {
            "id": "SpecificColorSelector",
            "icon": "krita_tool_color_sampler",
            "size": [290, 100]
        },
        "palette": {
            "id": "PaletteDocker",
            "icon": "palette-library",
            "size": []
        },
        "layers": {
            "id": "KisLayerBox",
            "icon": "duplicatelayer",
            "size": []
        },
        "toolOptions": {
            "id": "sharedtooldocker",
            "icon": "light_paintop_settings_02",
            "size": [306, 391]
        },
        "quickSettings": {
            "id": "quick_settings_docker",
            "icon": "gridbrush",
            "size": [260, 325]
        },
        "animation": {
            "id": "AnimationDocker",
            "icon": "light_addblankframe",
            "size": []
        },
        "onionSkins": {
            "id": "OnionSkinsDocker",
            "icon": "light_onion_skin_options",
            "size": [100, 100]
        },
        "arrange": {
            "id": "ArrangeDocker",
            "icon": "24_light_align-horizontal-center",
            "size": [100, 100]
        },
        "svgSymbols": {
            "id": "SvgSymbolCollectionDocker",
            "icon": "22_light_shape-choose",
            "size": []
        },
        "comicsProject": {
            "id": "comics_project_manager_docker",
            "icon": "select-all",
            "size": []
        },
        "lut": {
            "id": "LutDocker",
            "icon": "color-to-alpha",
            "size": []
        },
        "history": {
            "id": "History",
            "icon": "fileLayer",
            "size": []
        },
        "freehandSelection": {
            "id": "freehand_selection_tool",
            "icon": "tool-outline-selection", 
            "size": []   
    },
    "canvasOptions": {
        "canvasOnly": { 
            "id": "view_show_canvas_only",
            "icon": "document-new"
        },
        "mirrorCanvas": { 
            "id": "mirror_canvas",
            "icon": "mirror-view"
        },
        "preserveAlpha": {
            "id": "preserve_alpha",
            "icon": "transparency-locked"
        },   
        "resetZoom": {
            "id": "zoom_to_100pct",
            "icon": "zoom-original"
        },
        "wrapAround": {
            "id": "wrap_around_mode",
            "icon": "view-grid"
        },
        "instantPreview": {
            "id": "level_of_detail_mode",
            "icon": "visible"
        },
        "resetRotation":  {
            "id": "reset_canvas_rotation",
            "icon": "rotation-reset"    
        },
        "Deselect": {
            "id": "deselect",
            "icon": "Deselect" 
        }
            
  }
} 

Looked at example script on github, and also at script school, but can’t fix it.

Not sure if the following is right re HSV either, which hope to add …
},
ā€œHSV Adjustmentā€: {
ā€œidā€: ā€œkrita_filter_hsvadjustmentā€,
ā€œiconā€: ā€œHSV Adjustmentā€

Haven’t added error message, as this post is really large, plus have removed all but the deselect attempt at this point, so the only error message would be regarding that, which I can add if wanted below, if nothing obvious is spotted in the code have added.

1 Like

Unfortunately my very first experience with the plugin results in an error message.
Also following manual instructions of pasting archive content in PyKrita folder didn’t seem to work, only showed once I ran script from Krita menu tool …

Running latest Krita appimage 5.0.2
Operating System: Kubuntu 20.04
KDE Plasma Version: 5.18.5
KDE Frameworks Version: 5.68.0
Qt Version: 5.12.8
Kernel Version: 5.11.0-46-generic
OS Type: 64-bit
Processors: 8 Ɨ IntelĀ® Coreā„¢ i7-2630QM CPU @ 2.00GHz
Memory: 7,7 GiB of RAM

AttributeError
Python 3.8.1: /usr/bin/python3
Sat Jan 15 17:05:18 2022

A problem occurred in a Python script.  Here is the sequence of
function calls leading up to the error, in the order they occurred.

 /home/rob/.local/share/krita/pykrita/kanvasbuddy/kanvasbuddy.py in launchInterface(self=<kanvasbuddy.kanvasbuddy.KanvasBuddy object>)
   54             # importlib.reload(uikanvasbuddy) # FOR TESTING ONLY
   55             self.isActive = True
   56             ui = uikanvasbuddy.UIKanvasBuddy(self)
   57             ui.launch()
   58 
ui undefined
global uikanvasbuddy = <module 'kanvasbuddy.uikanvasbuddy' from '/home/...hare/krita/pykrita/kanvasbuddy/uikanvasbuddy.py'>
uikanvasbuddy.UIKanvasBuddy = <class 'kanvasbuddy.uikanvasbuddy.UIKanvasBuddy'>
self = <kanvasbuddy.kanvasbuddy.KanvasBuddy object>

 /home/rob/.local/share/krita/pykrita/kanvasbuddy/uikanvasbuddy.py in __init__(self=<kanvasbuddy.uikanvasbuddy.UIKanvasBuddy object>, kbuddy=<kanvasbuddy.kanvasbuddy.KanvasBuddy object>)
   61         # SET UP PANELS
   62         self.panelStack = pnlstk.KBPanelStack(self)
   63         self.initPanels(config['PANELS'], jsonData['panels'])
   64         self.layout().addWidget(self.panelStack)
   65 
self = <kanvasbuddy.uikanvasbuddy.UIKanvasBuddy object>
self.initPanels = <bound method UIKanvasBuddy.initPanels of <kanvasbuddy.uikanvasbuddy.UIKanvasBuddy object>>
config = <configparser.ConfigParser object>
jsonData = {'canvasOptions': {'canvasOnly': {'icon': 'light_document-new', 'id': 'view_show_canvas_only'}, 'instantPreview': {'icon': 'light_visible', 'id': 'level_of_detail_mode'}, 'mirrorCanvas': {'icon': 'light_mirror-view', 'id': 'mirror_canvas'}, 'resetZoom': {'icon': 'light_zoom-original', 'id': 'zoom_to_100pct'}, 'wrapAround': {'icon': 'light_view-grid', 'id': 'wrap_around_mode'}}, 'panels': {'advancedColor': {'icon': 'light_krita_tool_color_picker', 'id': 'ColorSelectorNg', 'size': [290, 290]}, 'animation': {'icon': 'light_addblankframe', 'id': 'AnimationDocker', 'size': []}, 'arrange': {'icon': '24_light_align-horizontal-center', 'id': 'ArrangeDocker', 'size': [100, 100]}, 'artisticColor': {'icon': 'light_wheel-sectors', 'id': 'ArtisticColorSelector', 'size': []}, 'comicsProject': {'icon': 'light_select-all', 'id': 'comics_project_manager_docker', 'size': []}, 'digitalColors': {'icon': 'light_krita_tool_gradient', 'id': 'DigitalMixer', 'size': []}, 'history': {'icon': 'light_fileLayer', 'id': 'History', 'size': []}, 'layers': {'icon': 'light_duplicatelayer', 'id': 'KisLayerBox', 'size': []}, 'lut': {'icon': 'light_color-to-alpha', 'id': 'LutDocker', 'size': []}, 'onionSkins': {'icon': 'light_onion_skin_options', 'id': 'OnionSkinsDocker', 'size': [100, 100]}, ...}}

 /home/rob/.local/share/krita/pykrita/kanvasbuddy/uikanvasbuddy.py in initPanels(self=<kanvasbuddy.uikanvasbuddy.UIKanvasBuddy object>, config=<Section: PANELS>, data={'advancedColor': {'icon': 'light_krita_tool_color_picker', 'id': 'ColorSelectorNg', 'size': [290, 290]}, 'animation': {'icon': 'light_addblankframe', 'id': 'AnimationDocker', 'size': []}, 'arrange': {'icon': '24_light_align-horizontal-center', 'id': 'ArrangeDocker', 'size': [100, 100]}, 'artisticColor': {'icon': 'light_wheel-sectors', 'id': 'ArtisticColorSelector', 'size': []}, 'comicsProject': {'icon': 'light_select-all', 'id': 'comics_project_manager_docker', 'size': []}, 'digitalColors': {'icon': 'light_krita_tool_gradient', 'id': 'DigitalMixer', 'size': []}, 'history': {'icon': 'light_fileLayer', 'id': 'History', 'size': []}, 'layers': {'icon': 'light_duplicatelayer', 'id': 'KisLayerBox', 'size': []}, 'lut': {'icon': 'light_color-to-alpha', 'id': 'LutDocker', 'size': []}, 'onionSkins': {'icon': 'light_onion_skin_options', 'id': 'OnionSkinsDocker', 'size': [100, 100]}, ...})
   81         for entry in config:
   82             if config.getboolean(entry):
   83                 self.panelStack.loadPanel(data[entry])
   84 
   85 
self = <kanvasbuddy.uikanvasbuddy.UIKanvasBuddy object>
self.panelStack = <kanvasbuddy.kbpanelstack.KBPanelStack object>
self.panelStack.loadPanel = <bound method KBPanelStack.loadPanel of <kanvasbuddy.kbpanelstack.KBPanelStack object>>
data = {'advancedColor': {'icon': 'light_krita_tool_color_picker', 'id': 'ColorSelectorNg', 'size': [290, 290]}, 'animation': {'icon': 'light_addblankframe', 'id': 'AnimationDocker', 'size': []}, 'arrange': {'icon': '24_light_align-horizontal-center', 'id': 'ArrangeDocker', 'size': [100, 100]}, 'artisticColor': {'icon': 'light_wheel-sectors', 'id': 'ArtisticColorSelector', 'size': []}, 'comicsProject': {'icon': 'light_select-all', 'id': 'comics_project_manager_docker', 'size': []}, 'digitalColors': {'icon': 'light_krita_tool_gradient', 'id': 'DigitalMixer', 'size': []}, 'history': {'icon': 'light_fileLayer', 'id': 'History', 'size': []}, 'layers': {'icon': 'light_duplicatelayer', 'id': 'KisLayerBox', 'size': []}, 'lut': {'icon': 'light_color-to-alpha', 'id': 'LutDocker', 'size': []}, 'onionSkins': {'icon': 'light_onion_skin_options', 'id': 'OnionSkinsDocker', 'size': [100, 100]}, ...}
entry = 'presetChooser'

 /home/rob/.local/share/krita/pykrita/kanvasbuddy/kbpanelstack.py in loadPanel(self=<kanvasbuddy.kbpanelstack.KBPanelStack object>, data={'icon': 'light_paintop_settings_01', 'id': 'PresetDocker', 'size': [260, 335]})
   56         ID = data['id']
   57         if ID == 'PresetDocker': # This is ugly, but necessary until the Krita API opens a proper 'presetChanged' signal
   58             pc = KBPresetChooser()
   59             pc.presetSelected.connect(self.brushPresetChanged)
   60             pc.presetClicked.connect(self.brushPresetChanged)
pc undefined
global KBPresetChooser = <class 'kanvasbuddy.kbpresetchooser.KBPresetChooser'>

 /home/rob/.local/share/krita/pykrita/kanvasbuddy/kbpresetchooser.py in __init__(self=<kanvasbuddy.kbpresetchooser.KBPresetChooser object>, parent=None)
   23         super(KBPresetChooser, self).__init__(parent)
   24         # Hide buttons deemed excessive for this plugin
   25         self.layout().itemAt(0).widget().layout().itemAt(4).itemAtPosition(0,0).widget().hide()
   26         self.layout().itemAt(0).widget().layout().itemAt(4).itemAtPosition(0,1).widget().hide()
   27 
self = <kanvasbuddy.kbpresetchooser.KBPresetChooser object>
self.layout = <built-in method layout of KBPresetChooser object>
).itemAt undefined
AttributeError: 'QWidgetItem' object has no attribute 'itemAtPosition'
    __cause__ = None
    __class__ = <class 'AttributeError'>
    __context__ = None
    __delattr__ = <method-wrapper '__delattr__' of AttributeError object>
    __dict__ = {}
    __dir__ = <built-in method __dir__ of AttributeError object>
    __doc__ = 'Attribute not found.'
    __eq__ = <method-wrapper '__eq__' of AttributeError object>
    __format__ = <built-in method __format__ of AttributeError object>
    __ge__ = <method-wrapper '__ge__' of AttributeError object>
    __getattribute__ = <method-wrapper '__getattribute__' of AttributeError object>
    __gt__ = <method-wrapper '__gt__' of AttributeError object>
    __hash__ = <method-wrapper '__hash__' of AttributeError object>
    __init__ = <method-wrapper '__init__' of AttributeError object>
    __init_subclass__ = <built-in method __init_subclass__ of type object>
    __le__ = <method-wrapper '__le__' of AttributeError object>
    __lt__ = <method-wrapper '__lt__' of AttributeError object>
    __ne__ = <method-wrapper '__ne__' of AttributeError object>
    __new__ = <built-in method __new__ of type object>
    __reduce__ = <built-in method __reduce__ of AttributeError object>
    __reduce_ex__ = <built-in method __reduce_ex__ of AttributeError object>
    __repr__ = <method-wrapper '__repr__' of AttributeError object>
    __setattr__ = <method-wrapper '__setattr__' of AttributeError object>
    __setstate__ = <built-in method __setstate__ of AttributeError object>
    __sizeof__ = <built-in method __sizeof__ of AttributeError object>
    __str__ = <method-wrapper '__str__' of AttributeError object>
    __subclasshook__ = <built-in method __subclasshook__ of type object>
    __suppress_context__ = False
    __traceback__ = <traceback object>
    args = ("'QWidgetItem' object has no attribute 'itemAtPosition'",)
    with_traceback = <built-in method with_traceback of AttributeError object>

The above is a description of an error in a Python program.  Here is
the original traceback:

Traceback (most recent call last):
  File "/home/rob/.local/share/krita/pykrita/kanvasbuddy/kanvasbuddy.py", line 56, in launchInterface
    ui = uikanvasbuddy.UIKanvasBuddy(self)
  File "/home/rob/.local/share/krita/pykrita/kanvasbuddy/uikanvasbuddy.py", line 63, in __init__
    self.initPanels(config['PANELS'], jsonData['panels'])
  File "/home/rob/.local/share/krita/pykrita/kanvasbuddy/uikanvasbuddy.py", line 83, in initPanels
    self.panelStack.loadPanel(data[entry])
  File "/home/rob/.local/share/krita/pykrita/kanvasbuddy/kbpanelstack.py", line 58, in loadPanel
    pc = KBPresetChooser()
  File "/home/rob/.local/share/krita/pykrita/kanvasbuddy/kbpresetchooser.py", line 25, in __init__
    self.layout().itemAt(0).widget().layout().itemAt(4).itemAtPosition(0,0).widget().hide()
AttributeError: 'QWidgetItem' object has no attribute 'itemAtPosition'



Did you apply the patch mentioned a few posts up?

Michelist

1 Like