It is currently Mon Jul 22, 2024 10:45 am


All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: Can someone help me with this GTK stuff?
PostPosted: Mon Apr 18, 2011 5:54 am  (#1) 
Offline
Script Coder

Joined: Apr 10, 2011
Posts: 532
Ok, so I've been trying to make a plugin that uses a GTK interface, using this http://www.gimphelp.org/scripts/script_ ... sharpen.py as a template.

I'm trying to create a dummy/test plugin that does nothing except creates a new layer. However, I just can't get it to work! It shows up in the filters menu but does nothing, doesn't display the dialog... I'm frustrated and I can't find what is wrong with it.

Can anyone help me find out what I'm doing wrong here?

Here's my source code:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#

import gimp, gimpplugin, math
from gimpenums import *
pdb = gimp.pdb
import gtk, gimpui, gimpcolor
from gimpshelf import shelf

class reuse_init(object):
   previewLayer = None

   def get_layer_pos(self, layer):
      i = 0
      while i < len(self.img.layers):
         if layer == self.img.layers[i]:
            return i
      else:
         i += 1
      return -1


   def layer_exists(self, layer):
      return layer != None and layer in self.img.layers

   def removePreviews(self):
      if self.layer_exists(self.previewLayer):
         self.img.remove_layer(self.previewLayer)
         self.previewLayer = None
      gimp.displays_flush()

   def make_label(self, text):
      label = gtk.Label(text)
      label.set_use_underline(True)
      label.set_alignment(1.0, 0.5)
      label.show()
      return label

   def make_slider_and_spinner(self, init, min, max, step, page, digits):
      controls = {'adj':gtk.Adjustment(init, min, max, step, page), 'slider':gtk.HScale(), 'spinner':gtk.SpinButton()}
      controls['slider'].set_adjustment(controls['adj'])
      controls['slider'].set_draw_value(False)
      controls['spinner'].set_adjustment(controls['adj'])
      controls['spinner'].set_digits(digits)
      controls['slider'].show()
      controls['spinner'].show()
      return controls

   def show_error_msg(self, msg):
      origMsgHandler = pdb.gimp_message_get_handler()
      pdb.gimp_message_set_handler(ERROR_CONSOLE)
      pdb.gimp_message(msg)
      pdb.gimp_message_set_handler(origMsgHandler)

   def stringToColor(self, string):
      colorlist = string[5:-1].split(", ")
      return gimpcolor.RGB(float(colorlist[0]), float(colorlist[1]), float(colorlist[2]), float(colorlist[3]))


class testplugin(reuse_init):
   def __init__(self, runmode, img, drawable, param1, param2):
      self.img = img
      self.drawable = drawable
      self.shelfkey = 'test-plugin'
      self.showDialog()

   def showDialog(self):
      self.dialog = gimpui.Dialog("Bheeeeps BAA!", "thedialog")

      self.table = gtk.Table(20, 4, True)
      self.table.set_homogeneous(False)
      self.table.set_row_spacings(8)
      self.table.set_col_spacings(8)
      self.table.show()

#param1
      self.label1 = self.make_label("Baa:")
      self.table.attach(self.label1, 0, 1, 1, 2)

      self.spinner1 = self.make_slider_and_spinner(10.0, 1.0, 20.0, 1.0, 10.0, 1)
      self.spinner1['adj'].set_value(10.0)
      self.table.attach(self.spinner1['slider'], 1, 2, 1, 2)
      self.table.attach(self.spinner1['spinner'], 2, 3, 1, 2)

#param2
                self.label2 = self.make_label("Boo:")
                self.table.attach(self.label2, 0, 1, 2, 3)

                self.spinner2 = self.make_slider_and_spinner(10.0, 0.0, 20.0, 0.1, 1.0, 1)
                self.spinner2['adj'].set_value(10.0)
                self.table.attach(self.spinner2['slider'],1,2,3,4)
                self.table.attach(self.spinner2['spinner'],2,3,3,4)

#      self.flatten_check = gtk.CheckButton("Flatten layer when complete")
#      self.flatten_check.show()
#      self.table.attach(self.flatten_check, 3, 4, 1, 2)

      self.dialog.vbox.hbox1 = gtk.HBox(False, 7)
      self.dialog.vbox.hbox1.show()
      self.dialog.vbox.pack_start(self.dialog.vbox.hbox1, True, True, 7)
      self.dialog.vbox.hbox1.pack_start(self.table, True, True, 7)

      reset_button = gtk.Button("_Reset")
      reset_button.connect("clicked", self.resetbutton)
      reset_button.show()

      self.preview_button = gtk.Button("Preview")
      self.preview_button.connect("clicked", self.preview)
      self.preview_button.set_size_request(100, -1)
      self.preview_button.show()

      if gtk.alternative_dialog_button_order():
         ok_button = self.dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
         cancel_button = self.dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
         self.dialog.action_area.add(reset_button)
         self.dialog.action_area.add(self.preview_button)
      else:
         self.dialog.action_area.add(self.preview_button)
         self.dialog.action_area.add(reset_button)
         cancel_button = self.dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
         ok_button = self.dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
      ok_button.connect("clicked", self.okbutton)

      self.dialog.show()
      self.dialog.run()
      self.removePreviews()


   def okbutton(self, widget):
      # remove old preview layer if it exists
      if self.layer_exists(self.previewLayer):
         self.img.remove_layer(self.previewLayer)
         self.previewLayer = None

      # get values of the settings
                param1 = self.spinner1['adj'].get_value()
                param2 = self.spinner2['adj'].get_value()
               
#      if self.flatten_check.get_active():
#         flatten = 1
#      else:
#         flatten = 0

      # then build new layer with current settings to actually impliment...
      # the True value at the end means it is a Final layer sent to "makeLayer"
      # hence it will flatten image if this is chosen (previews will not)
      fxlayer = self.makeLayer(self.img, self.drawable, param1, param2)


   def resetbutton(self, widget):
      self.spinner1['adj'].set_value(10.0)
      


   def preview(self, widget):
      ptxt = self.preview_button.get_label()

      if self.layer_exists(self.previewLayer):
         self.img.remove_layer(self.previewLayer)
         gimp.displays_flush()

      else:
                        param1 = self.spinner1['adj'].get_value()
                        param2 = self.spinner2['adj'].get_value()
         self.previewLayer = self.makeLayer(self.img, self.drawable, param1, param2)


      if ptxt == "Preview":
         ptxt = "Undo Preview"
      else:
         ptxt = "Preview"
      self.preview_button.set_label(ptxt)


   def makeLayer(self, img, drawable, param1, param2):
      pdb.gimp_image_undo_group_start(img)


      tmpLayer1 = pdb.gimp_layer_copy(drawable, True)


      pdb.gimp_image_add_layer(img, tmpLayer1, -1)


      gimp.displays_flush()
      pdb.gimp_image_undo_group_end(img)
      return tmpLayer1


class pyTestplugin(gimpplugin.plugin):
   def start(self):
      gimp.main(self.init, self.quit, self.query, self._run)

   def init(self):
      pass

   def quit(self):
      pass

   def query(self):
      authorname = "dd"
      copyrightname = "dd"
      menu_location = "<Image>/Filters/Testplugin..."
      date = "2011"
      plug_description = "A test plugin"
      plug_help = "A test plugin"
      plug_params = [
         (PDB_INT32, "run_mode", "Run mode"),
         (PDB_IMAGE, "image", "Input image"),
         (PDB_DRAWABLE, "drawable", "Input drawable"),
         ####### 3 params above needed by all scripts using gimpplugin.plugin ######################
         (PDB_FLOAT, "param1", "First parameter"),
         (PDB_FLOAT, "param2", "Second parameter")]

      gimp.install_procedure("py_testplugin",
         plug_description,
         plug_help,
         authorname,
         copyrightname,
         date,
         menu_location,
         "RGB*, GRAY*",
         PLUGIN,
         plug_params,
         [])

   def py_testplugin(self, runmode, img, drawable, param1, param2):
      testplugin(runmode, img, drawable, param1, param2)

if __name__ == '__main__':
   pyTestplugin().start()



Share on Facebook Share on Twitter Share on Orkut Share on Digg Share on MySpace Share on Delicious Share on Technorati
Top
 Post subject: Re: Can someone help me with this GTK stuff?
PostPosted: Mon Apr 18, 2011 7:33 am  (#2) 
Offline
Script Coder
User avatar

Joined: Jun 22, 2010
Posts: 1171
Location: Here and there
I couldn't even get this to register until I fixed your inconsistent indentation.

For example:
#param1
      self.label1 = self.make_label("Baa:")
      self.table.attach(self.label1, 0, 1, 1, 2)

      self.spinner1 = self.make_slider_and_spinner(10.0, 1.0, 20.0, 1.0, 10.0, 1)
      self.spinner1['adj'].set_value(10.0)
      self.table.attach(self.spinner1['slider'], 1, 2, 1, 2)
      self.table.attach(self.spinner1['spinner'], 2, 3, 1, 2)

#param2
                self.label2 = self.make_label("Boo:")
                self.table.attach(self.label2, 0, 1, 2, 3)

                self.spinner2 = self.make_slider_and_spinner(10.0, 0.0, 20.0, 0.1, 1.0, 1)
                self.spinner2['adj'].set_value(10.0)
                self.table.attach(self.spinner2['slider'],1,2,3,4)
                self.table.attach(self.spinner2['spinner'],2,3,3,4)

All the code for param2 should have the same indentation as that for param1

def okbutton(self, widget): has the same problem as does def preview(self, widget): although here it's not clear if you want the next lines as part of the preceding else or not.

Kevin

Update:
I've also found it necessary to add a default value for your parameters:
   def py_testplugin(self, runmode, img, drawable, param1=None, param2=None):
      testplugin(runmode, img, drawable, param1, param2)


What I tend to do with the Python scripts is to add the following. Make sure you have an import gtk
def debugMessage(Message):
    dialog = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, Message)
    dialog.run()
    dialog.hide()


Then I drop in debugMessage("I got here") into the code and if I get the "I got here" message I know the error hasn't occurred before that point. ;)


Top
 Post subject: Re: Can someone help me with this GTK stuff?
PostPosted: Mon Apr 18, 2011 8:30 am  (#3) 
Offline
Script Coder

Joined: Apr 10, 2011
Posts: 532
The indent thing was just due to the different tab length... the indents are in the right place in idle.

Anyway, yeah, I retraced my steps and I found out about the default values, and it works now... but thanks. The debug tip is a good one too, I'm going to use that, so thanks for that too!

I have a new problem though: I'm trying to create a layer mode selection drop-down box. I ripped the code from the layerfx plugin, what I have looks like this:

## blend mode box definition

        def make_blend_mode_box(self):
            return gimpui.IntComboBox((
              "Normal",        NORMAL_MODE,
              "Dissolve",      DISSOLVE_MODE,
              "Multiply",      MULTIPLY_MODE,
              "Divide",        DIVIDE_MODE,
              "Screen",        SCREEN_MODE,
              "Overlay",       OVERLAY_MODE,
              "Dodge",         DODGE_MODE,
              "Burn",          BURN_MODE,
              "Hard Light",    HARDLIGHT_MODE,
              "Soft Light",    SOFTLIGHT_MODE,
              "Grain Extract", GRAIN_EXTRACT_MODE,
              "Grain Merge",   GRAIN_MERGE_MODE,
              "Difference",    DIFFERENCE_MODE,
              "Addition",      ADDITION_MODE,
              "Subtract",      SUBTRACT_MODE,
              "Darken Only",   DARKEN_ONLY_MODE,
              "Lighten Only",  LIGHTEN_ONLY_MODE,
              "Hue",           HUE_MODE,
              "Saturation",    SATURATION_MODE,
              "Color",         COLOR_MODE,
              "Value",         VALUE_MODE
            ))

## this is in the showdialog method:

      self.lmode_label = self.make_label("_Layer mode:")
      self.table.attach(self.lmode_label, 0, 1, 1, 2)

                self.lmode_box = self.make_blend_mode_box()
                self.lmode_box.set_active(NORMAL_MODE)
                self.lmode_label.set_mnemonic_widget(self.lmode_box)
                self.table.attach(self.lmode_box, 1, 6, 1, 3)


If the indents are screwed again, ignore that, they're ok in my end... anyway, the plugin dialog shows up ok, the "Layer mode" label shows up, but the drop-down box doesn't show...


Top
 Post subject: Re: Can someone help me with this GTK stuff?
PostPosted: Mon Apr 18, 2011 8:58 am  (#4) 
Offline
Script Coder
User avatar

Joined: Jun 22, 2010
Posts: 1171
Location: Here and there
Well we're deep into things I've never seen before, but comparing it to what you've copied from and from experience with Tcl/Tk and py.gtk - aren't you missing self.mode_box.show()?

Can I recommend not using TABs they're too inconsistent across editors.

Kevin


Top
 Post subject: Re: Can someone help me with this GTK stuff?
PostPosted: Mon Apr 18, 2011 9:50 am  (#5) 
Offline
Script Coder

Joined: Apr 10, 2011
Posts: 532
Yes, thank you again! That was it!

:tyspin


Top
 Post subject: Re: Can someone help me with this GTK stuff?
PostPosted: Mon Apr 18, 2011 11:29 am  (#6) 
Offline
Script Coder

Joined: Apr 10, 2011
Posts: 532
Ok, I got the interface to work, but now I can't get the actual plugin to work... interface shows up ok, but the plugin doesn't do anything. And again I have absolutely no idea what could be wrong...


Top
 Post subject: Re: Can someone help me with this GTK stuff?
PostPosted: Mon Apr 18, 2011 1:14 pm  (#7) 
Offline
Script Coder

Joined: Apr 10, 2011
Posts: 532
Ha, now I got it... thanks to the debugmessage thing. Thanks again paynekj!


Top
 Post subject: Re: Can someone help me with this GTK stuff?
PostPosted: Mon Apr 18, 2011 1:33 pm  (#8) 
Offline
Script Coder

Joined: Apr 10, 2011
Posts: 532
Ok, I've got the preview working... now all I have to do is figure out how to use parasites to save/restore the plugin settings and we're all set.

ps. sorry for multiple posts... :oops:


Top
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 5 hours [ DST ]


   Similar Topics   Replies 
No new posts The Right Stuff.

5



* Login  



Powered by phpBB3 © phpBB Group