(03-24-2025, 04:50 PM)iiey Wrote: Hi nchen,
Thank you for your reply, I will take your example with choice as reference and test it out.
Hello iiey,
You're welcome! Hope that helps.
Were you trying to get Radio options working?
You can theoretically use any GTK 3 widgets with the GimpUI dialog.
I just learned GTK recently because I didn't know how to use GimpUI...
Here is an example I just created with Radio option:
Code:
#!/usr/bin/env python3
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import gi
gi.require_version('Gimp', '3.0')
from gi.repository import Gimp
gi.require_version('GimpUi', '3.0')
from gi.repository import GimpUi
gi.require_version('Gegl', '0.4')
from gi.repository import Gegl
from gi.repository import GObject
from gi.repository import GLib
from gi.repository import Gio
from gi.repository import Gtk
from gi.repository import Gdk
import time
import sys
def N_(message): return message
def _(message): return GLib.dgettext(None, message)
'''
A Python plugin.
Tests GimpProcedureDialog.
Temporarily, just testing widgets for subclasses of GimpResource.
Temporarily, just testing Brush subclass of Resource.
FUTURE: For all the parameter types.
Formerly PF_ constants, now all parameters for which GimpParamSpecs exist.
Not localized, no i18n
'''
def process_args(brush, font, gradient, palette, pattern, choice_val):
'''
Test the args are sane.
'''
assert brush is not None
assert isinstance(brush, Gimp.Brush)
id = brush.get_id()
name = brush.get_name()
assert id is not None
msg = "Brush: {} (ID: {})".format(name, id)
print(msg)
Gimp.message(msg)
assert font is not None
assert isinstance(font, Gimp.Font)
id = font.get_id()
name = font.get_name()
assert id is not None
msg = "Font: {} (ID: {})".format(name, id)
print(msg)
Gimp.message(msg)
assert gradient is not None
assert isinstance(gradient, Gimp.Gradient)
id = gradient.get_id()
name = gradient.get_name()
assert id is not None
msg = "Gradient: {} (ID: {})".format(name, id)
print(msg)
Gimp.message(msg)
assert palette is not None
assert isinstance(palette, Gimp.Palette)
id = palette.get_id()
name = palette.get_name()
assert id is not None
msg = "Palette: {} (ID: {})".format(name, id)
print(msg)
Gimp.message(msg)
assert pattern is not None
assert isinstance(pattern, Gimp.Pattern)
id = pattern.get_id()
name = pattern.get_name()
assert id is not None
msg = "Pattern: {} (ID: {})".format(name, id)
print(msg)
Gimp.message(msg)
assert choice_val is not None
assert isinstance(choice_val, str)
msg = "Choice : {}".format(choice_val)
print(msg)
Gimp.message(msg)
return
class CustomProcedureDialog(GimpUi.ProcedureDialog):
def __init__(self, procedure, config):
super().__init__(procedure=procedure, config=config)
self.set_default_size(600, 100)
# Apply CSS
self.apply_css()
# Get the main content area of the ProcedureDialog
content_area = self.get_content_area()
# Create a scrolled window for the entire dialog
scrolled_window = Gtk.ScrolledWindow()
scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
scrolled_window.set_size_request(400, 300) # Adjust scrolled window size request dims
# Create a container to hold all the UI elements inside the scroll area
content_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
content_box.set_border_width(10)
content_box.get_style_context().add_class("content_box")
# Populate GIMP's default argument UI elements,
# This adds the GIMP argument widgets to the content area
self.fill(None)
# Retrieve all GIMP UI elements that were just added
for child in content_area.get_children():
# Skip the GtkBox and GtkButtonBox elements (ok buttons at the bottom to add them later)
if child.get_name() == "GtkBox" or child.get_name() == "GtkButtonBox":
continue
content_area.remove(child) # Remove them temporarily
content_box.pack_start(child, False, False, 5) # Repack them inside the scrollable box
# Create custom Radio options
export_box = Gtk.Box(spacing=10)
export_box.get_style_context().add_class("export_box")
export_label = Gtk.Label(label="Export As")
export_label.get_style_context().add_class("export_label")
self.png_radio = Gtk.RadioButton.new_with_label(None, "PNG")
self.jpg_radio = Gtk.RadioButton.new_with_label_from_widget(self.png_radio, "JPG")
# Add the radio to the content box
export_box.pack_start(export_label, False, False, 0)
export_box.pack_start(self.png_radio, False, False, 0)
export_box.pack_start(self.jpg_radio, False, False, 0)
content_box.pack_start(export_box, False, False, 0)
# Add the content box to the scrolled window
scrolled_window.add(content_box)
# Add the scrolled window into the GimpUi dialog
content_area.pack_start(scrolled_window, True, True, 0)
self.show_all()
def apply_css(self):
css = """
.content_box {
padding-left: 20px;
padding-right: 20px;
}
"""
style_provider = Gtk.CssProvider()
style_provider.load_from_data(css.encode("utf-8"))
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), style_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
def get_radio_result(self):
"""Store the radio button selection before closing."""
if self.png_radio.get_active():
self.selected_format = "png"
elif self.jpg_radio.get_active():
self.selected_format = "jpg"
def test_dialog(procedure, run_mode, image, drawables, config, data):
'''
Just a standard shell for a plugin.
'''
if run_mode == Gimp.RunMode.INTERACTIVE:
GimpUi.init('python-fu-test-dialog')
Gegl.init(None)
dialog = CustomProcedureDialog(procedure, config)
response = dialog.run()
dialog.get_radio_result()
selected_format = dialog.selected_format
Gimp.message(f"Selected Format: {selected_format}")
dialog.destroy()
brush = config.get_property('brush')
font = config.get_property('font')
gradient = config.get_property('gradient')
palette = config.get_property('palette')
pattern = config.get_property('pattern')
choice_val = config.get_property('format')
Gimp.context_push()
# process_args(brush, font, gradient, palette, pattern, choice_val)
Gimp.displays_flush()
Gimp.context_pop()
return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())
class TestDialogPlugin (Gimp.PlugIn):
# FUTURE all other Gimp classes that have GimpParamSpecs
## GimpPlugIn virtual methods ##
def do_set_i18n(self, procname):
return True, 'gimp30-python', None
def do_query_procedures(self):
return [ 'python-fu-test-dialog' ]
def do_create_procedure(self, name):
procedure = Gimp.ImageProcedure.new(self, name,
Gimp.PDBProcType.PLUGIN,
test_dialog, None)
procedure.set_sensitivity_mask (Gimp.ProcedureSensitivityMask.NO_IMAGE)
procedure.set_documentation ("Test dialog",
"Test dialog",
name)
procedure.set_menu_label("Test dialog...")
procedure.set_attribution("Lloyd Konneker",
"Lloyd Konneker",
"2022")
# Top level menu "Test"
procedure.add_menu_path ("<Image>/Filters/Development/Demos")
procedure.add_brush_argument ("brush", "_Brush", "Brush", True,
Gimp.Brush.get_by_name ("2. Hardness 025"),
False,
GObject.ParamFlags.READWRITE)
procedure.add_font_argument ("font", "_Font", "Font", True,
Gimp.Font.get_by_name ("Serif"),
False,
GObject.ParamFlags.READWRITE)
procedure.add_gradient_argument ("gradient", "_Gradient",
"Gradient", True,
Gimp.Gradient.get_by_name ("Incandescent"),
False,
GObject.ParamFlags.READWRITE)
procedure.add_palette_argument ("palette", "_Palette",
"Palette", True,
Gimp.Palette.get_by_name ("Default"),
False,
GObject.ParamFlags.READWRITE)
procedure.add_pattern_argument ("pattern", "Pa_ttern",
"Pattern", True,
Gimp.Pattern.get_by_name ("Paper"),
False,
GObject.ParamFlags.READWRITE)
export_format_choice = Gimp.Choice.new()
export_format_choice.add("png", 1, "png", "png")
export_format_choice.add("jpg", 2, "jpg", "jpg")
procedure.add_choice_argument("format", "_Format",
"Format", export_format_choice, "png",
GObject.ParamFlags.READWRITE)
return procedure
Gimp.main(TestDialogPlugin.__gtype__, sys.argv)