Color of buttons not working as expected

1,460 views
Skip to first unread message

Fidel Pérez

unread,
May 28, 2013, 6:09:50 PM5/28/13
to leo-e...@googlegroups.com
Hi, Im creating a big deal of buttons using this script, but it will not produce buttons with other color than "lightblue". I have tried everything (even switching all the lightsteelblue1 within Leopyref and leoguiplugins etc but no success). Any suggestion on what to read to fix this?

from leo.plugins.mod_scripting import scriptingController
sc = scriptingController(c) 
sc.createIconButton( MyNode.h, command = MyCommand, statusLine = MyNode.h, bg="green" )
 
This will create another lightsteelblue button.

The "create-script-button" button is the only one which works and is yellow, searched it through the code but got no good conclusions out of it.

Also got the working "prev" and "next" icon (with a green arrow) from some plugin I dont know which one is it. Im using pyqt.

Thanks! 

Terry Brown

unread,
May 28, 2013, 7:00:55 PM5/28/13
to leo-e...@googlegroups.com
On Tue, 28 May 2013 15:09:50 -0700 (PDT)
Fidel Pérez <fidel...@gmail.com> wrote:

> Hi, Im creating a big deal of buttons using this script, but it will not
> produce buttons with other color than "lightblue". I have tried everything
> (even switching all the lightsteelblue1 within Leopyref and leoguiplugins
> etc but no success). Any suggestion on what to read to fix this?

I meant to mention that when I was looking at it before. The button
color parameter is still required, but does nothing, there's a comment
in the source the the stylesheet should be used instead. More
attributes would need to be set on the button to make that truly
versatile, and even then that might not suit your use case.

You could try setting the QPushButton's color directly, it's
the .button attribute of the action descendant returned by the
scripting controller.

Cheers -Terry

Fidel Pérez

unread,
May 29, 2013, 2:59:33 AM5/29/13
to leo-e...@googlegroups.com
Great! It works!

from leo.plugins.mod_scripting import scriptingController
sc = scriptingController(c) 

TempButtonHold = sc.createIconButton( p.h, command = "", statusLine = p.h, bg="blue" ) 
TempButtonHold.button.setStyleSheet("QWidget {background-color: green }")

Will create a green button :)

Terry Brown

unread,
May 29, 2013, 9:22:57 AM5/29/13
to leo-e...@googlegroups.com
On Tue, 28 May 2013 23:59:33 -0700 (PDT)
Fidel Pérez <fidel...@gmail.com> wrote:

> Great! It works!
>
> from leo.plugins.mod_scripting import scriptingController
> > sc = scriptingController(c)
> >
> > TempButtonHold = sc.createIconButton( p.h, command = "", statusLine = p.h,
> > bg="blue" )
> > TempButtonHold.button.setStyleSheet("QWidget {background-color: green }")

Oh good - just setting the stylesheet on the button itself didn't occur
to me :-) - I was thinking the button would need an attribute set that
allowed it to be targeted vis CSS selection from the top level
stylesheet.

Cheers -Terry

Edward K. Ream

unread,
May 29, 2013, 9:34:29 AM5/29/13
to leo-editor
On Wed, May 29, 2013 at 8:22 AM, Terry Brown <terry_...@yahoo.com> wrote:
On Tue, 28 May 2013 23:59:33 -0700 (PDT)
Fidel Pérez <fidel...@gmail.com> wrote:

> Great! It works!
>
> from leo.plugins.mod_scripting import scriptingController
> > sc = scriptingController(c)
> >
> > TempButtonHold = sc.createIconButton( p.h, command = "", statusLine = p.h,
> > bg="blue" )
> > TempButtonHold.button.setStyleSheet("QWidget {background-color: green }")

Oh good - just setting the stylesheet on the button itself didn't occur
to me :-) - I was thinking the button would need an attribute set that
allowed it to be targeted vis CSS selection from the top level
stylesheet.

Haha.  This means that the bg keyword param to sc.createIconButton should be made functional ;-)  I'll try that now.

Edward

Jacob Peck

unread,
May 29, 2013, 9:40:49 AM5/29/13
to leo-e...@googlegroups.com
--

I probably should have mentioned that setting the stylesheet on individual Qt elements was possible.  Figured that out while I was writing the printing plugin.  Didn't occur to me until just now, though.

-->Jake

Edward K. Ream

unread,
May 29, 2013, 9:51:35 AM5/29/13
to leo-editor
On Wed, May 29, 2013 at 8:34 AM, Edward K. Ream <edre...@gmail.com> wrote:

Haha.  This means that the bg keyword param to sc.createIconButton should be made functional ;-)  I'll try that now.

Done at rev 5796.  All unit tests pass.  Please report any problems immediately.

The heart of the new code is::

    b.button.setStyleSheet("{background-color: %s }" % (bg))

not:

    b.button.setStyleSheet("QWidget {background-color: %s }" % (bg))

This latter code would change to much.

Edward

Fidel Pérez

unread,
May 29, 2013, 10:14:08 AM5/29/13
to leo-e...@googlegroups.com
Heey Im glad that was helpful! 
Great change, that will save me a *few* lines of code =)
Couldn't have found it without your help anyway so thank you guys.

Terry Brown

unread,
May 29, 2013, 10:18:15 AM5/29/13
to leo-e...@googlegroups.com
On Wed, 29 May 2013 08:51:35 -0500
The stylesheet only applies to the widget and its descendants, so the
latter's fine, although you could use QPushButton perhaps. The former
doesn't work, it just produces a lot of

Could not parse stylesheet of widget 0x6f32b20

because it doesn't specify a target for the style.

Using the fixed QWidget / QPushButton version, I'm getting black
backgrounded buttons, suggesting color names which Qt doesn't know are
being used.

Of course hard coded button colors of any type are undesirable, so
first I would recommend the 'bg' parameter have a new default value of
None, and that no styling be applied when it is None.

Then we need either @color @settings for the different button types:

- the singleton run-script button
- the singleton script-button button
- buttons created by @button nodes
- buttons created by clicking the script-button button

or w.setObjectName() be used to tag those four types at creation to
make them viable targets for the top level stylesheet.

I prefer this latter approach, and to go with it re-purposing the bg
parameter (which remember was dead wood until 30 minutes ago) to be the
object name. If some objects get called "light-blue" that won't break
anything.

Cheers -Terry

Edward K. Ream

unread,
May 29, 2013, 10:25:29 AM5/29/13
to leo-editor
On Wed, May 29, 2013 at 9:18 AM, Terry Brown <terry_...@yahoo.com> wrote:
 
> The heart of the new code is::
>
>     b.button.setStyleSheet("{background-color: %s }" % (bg))
>
> not:
>
>     b.button.setStyleSheet("QWidget {background-color: %s }" % (bg))
>
> This latter code would change to much.

The stylesheet only applies to the widget and its descendants, so the
latter's fine, although you could use QPushButton perhaps.
 
Using the fixed QWidget / QPushButton version, I'm getting black

backgrounded buttons, suggesting color names which Qt doesn't know are
being used.

That happened to me too, which is why I removed the QWidget selector.

Of course hard coded button colors of any type are undesirable, so
first I would recommend the 'bg' parameter have a new default value of
None, and that no styling be applied when it is None.

The code on the trunk does that.

Then we need either @color @settings for the different button types:

 - the singleton run-script button
 - the singleton script-button button
 - buttons created by @button nodes
 - buttons created by clicking the script-button button

or w.setObjectName() be used to tag those four types at creation to
make them viable targets for the top level stylesheet.

Actually, afaik, the present code works as before, except that the bg param now works.  If you need more, then fire away.

Edward

Terry Brown

unread,
May 29, 2013, 11:23:10 AM5/29/13
to leo-e...@googlegroups.com
On Wed, 29 May 2013 09:25:29 -0500
"Edward K. Ream" <edre...@gmail.com> wrote:

> Actually, afaik, the present code works as before, except that the bg param
> now works. If you need more, then fire away.

What you see depends on lot on what theme you're using, so now I'm
testing under the default theme, and...

The only difference I see between 5796 and earlier versions is that it
says "Could not parse stylesheet of widget 0x434b460"
when you click script-button.

It doesn't work any more or less than it did before. Note, and this had me confused for some time, the default stylesheet makes buttons lightsteelblue1, it's not
the bg parameter, which is actually MistyRose1 for buttons created by clicking the script-button button.

So why did I say it was disabled? Because of the if 0: in
.../leo/core/LeoPyRef.leo#Code-->Qt gui-->@file ../plugins/qtGui.py-->Frame and component classes...-->class leoQtFrame-->class qtIconBarClass-->add (qtIconBarClass)

So I don't think the new code is doing anything except producing the
"Can't parse" messages.

I'll have a look at the .setObjectName() / .setProperty() options in a
bit.

Cheers -Terry

Edward K. Ream

unread,
May 30, 2013, 9:58:08 AM5/30/13
to leo-e...@googlegroups.com
On Wednesday, May 29, 2013 10:23:10 AM UTC-5, Terry wrote:


So I don't think the new code is doing anything except producing the
"Can't parse" messages.

Somehow I was confused yesterday.  I am seeing the behavior you describe.

I am going to work on this a bit now.  For starters, I am wondering how LightSteelBlue1 ever got correctly translated into a color that Qt can handle...

Edward

Terry Brown

unread,
May 30, 2013, 10:05:27 AM5/30/13
to leo-e...@googlegroups.com
On Thu, 30 May 2013 06:58:08 -0700 (PDT)
"Edward K. Ream" <edre...@gmail.com> wrote:

> On Wednesday, May 29, 2013 10:23:10 AM UTC-5, Terry wrote:
>
>
> > So I don't think the new code is doing anything except producing the
> > "Can't parse" messages.
> >
>
> Somehow I was confused yesterday. I am seeing the behavior you describe.
>
> I am going to work on this a bit now. For starters, I am wondering how

No, don't do that - I have a bunch of new code ready to push.

> LightSteelBlue1 ever got correctly translated into a color that Qt can
> handle...

It's not, the only thing that's coloring buttons currently is
this in leoSettings.leo

/* Default colors for icons in the icon area. */
QPushButton {
background-color: #CAE1FF; /* lightSteelBlue1 */
/* border: none; /* Needed to make background-color "stick" */
}
/*
You may set colors for individual buttons by name.
To get a list of button names, enable tracing for
the qtIconBarClass.add method in qtGui.py.
*/
/* Colors for the "script-button" button. */
QPushButton#script-button-button {
background-color: #ffffcc;
/* border: none; /* Needed to make background-color "stick" */
}

createIconButton or whatever it's called does
b.button.setObjectName(b.button.text()+'-button') on the buttons it
makes, hence the targetting above - I've expanded this and will push
now.

Cheers -Terry


> Edward
>

Edward K. Ream

unread,
May 30, 2013, 10:06:29 AM5/30/13
to leo-e...@googlegroups.com

Doh.  The answer is::


QPushButton#script-button-button {
    background-color: #ffffcc;
    /* border: none; /* Needed to make background-color "stick" */
}

But yikes, it's not clear where the yellow background for the script-button button itself is coming from.  This is a complete mess at present.

Some mini tasks:

1. Either eliminate unused color args to various methods, or find a way to use human-readable color names.

2. Retain the stylesheet entry above, while allowing scripts to specify colors.

3. Check color names before setting stylesheets so they don't ever generate exceptions.

Edward

Edward K. Ream

unread,
May 30, 2013, 10:24:34 AM5/30/13
to leo-e...@googlegroups.com
On Thursday, May 30, 2013 9:06:29 AM UTC-5, Edward K. Ream wrote:

Some mini tasks:

1. Either eliminate unused color args to various methods, or find a way to use human-readable color names.

At last I remember.  leo_color_database in leoColor.py is a dict whose keys are color names and whose values are Qt color values (strings, starting with '#'.

The mod_scripting plugin should use this dict, and perhaps qtIconBarClass.add should too.

Edward

Terry Brown

unread,
May 30, 2013, 10:30:27 AM5/30/13
to leo-e...@googlegroups.com
On Thu, 30 May 2013 07:24:34 -0700 (PDT)
"Edward K. Ream" <edre...@gmail.com> wrote:

> On Thursday, May 30, 2013 9:06:29 AM UTC-5, Edward K. Ream wrote:
>
> Some mini tasks:
> >
> > 1. Either eliminate unused color args to various methods, or find a way to
> > use human-readable color names.
> >
>
> At last I remember. leo_color_database in leoColor.py is a dict whose keys
> are color names and whose values are Qt color values (strings, starting
> with '#'.

I you think it's necessary, that dict could be injected into the new
stylesheet macro expansion system. Currently I think the stylesheet
uses 2-3 named colors, so it's no big deal to define them directly in
the stylesheet, in a comment which is processed by the new stylesheet
macro expansion system.

Cheers -Terry

Edward K. Ream

unread,
May 30, 2013, 11:32:01 AM5/30/13
to leo-editor
On Thu, May 30, 2013 at 9:05 AM, Terry Brown <terry_...@yahoo.com> wrote:

> I have a bunch of new code ready to push.

We are getting closer, but I have a few concerns.

1. you've removed the bg argument from sc.createIconButton.

I'm not sure whether this is going to create problems for other plugins.  You've change the 'bg' keyword to 'kind' in all the official keywords, but there is no guarantee that other plugins won't break.

2. How is the 'kind' param used?

3. The following comment in leoSettings.leo could be improved:


/*
    You may set colors for individual buttons by name.
    To get a list of button names, enable tracing for
    the qtIconBarClass.add method in qtGui.py.
*/

In fact, the selector is the "canonicalized" button name.  qtIconBarClass.add sets the objectName of the button to this name.  Scripts can get this name as follows::

    action = sc.createIconButton(fullName,command="",statusLine=fullName)
    name = action.button.objectName()

Edward

Edward K. Ream

unread,
May 30, 2013, 11:55:14 AM5/30/13
to leo-editor
On Thu, May 30, 2013 at 9:30 AM, Terry Brown <terry_...@yahoo.com> wrote:

> At last I remember.  leo_color_database in leoColor.py is a dict whose keys
> are color names and whose values are Qt color values (strings, starting
> with '#'.

I you think it's necessary, that dict could be injected into the new
stylesheet macro expansion system.  Currently I think the stylesheet
uses 2-3 named colors, so it's no big deal to define them directly in
the stylesheet, in a comment which is processed by the new stylesheet
macro expansion system.

We definitely should support expanded colors somehow. 

Rev 5800 does the following:

1. Restores the bg keyword arg to sc.createIconButton, in its original place, that is, before the "kind" keyword arg.

This is compatible with your code, because it always uses kind=kind.  This change ensures that no scripts or plugins can be broken by recent changes to createIconButton.

2. Adds the following code to createIconButton::

        if not bg.startswith('#'):
            d = leoColor.leo_color_database
            bg2 = d.get(bg.lower())
            if not bg2:
                print('bad color? %s' % bg)
            bg = bg2
        if bg:
            try:
                b.button.setStyleSheet("QPushButton{background-color: %s}" % (bg))
            except Exception:
                # g.es_exception()
                pass # Might not be a valid color.

As a result, the following Leo script now works::

    from leo.plugins.mod_scripting import scriptingController
    sc = scriptingController(c)
    sc.createIconButton(p.h,command="",statusLine=p.h,bg='MistyRose1')

I hope we are not working at cross purposes here.  I like the general idea of using stylesheets to specify defaults, but I think stylesheets aren't dynamic enough for scripting.  I plan no further changes to mod_scripting.  Please feel free to make further changes as you will.

Edward

Terry Brown

unread,
May 30, 2013, 11:58:50 AM5/30/13
to leo-e...@googlegroups.com
On Thu, 30 May 2013 10:32:01 -0500
"Edward K. Ream" <edre...@gmail.com> wrote:

> On Thu, May 30, 2013 at 9:05 AM, Terry Brown <terry_...@yahoo.com>wrote:
>
> > I have a bunch of new code ready to push.
>
> We are getting closer, but I have a few concerns.
>
> 1. you've removed the bg argument from sc.createIconButton.
>
> I'm not sure whether this is going to create problems for other plugins.
> You've change the 'bg' keyword to 'kind' in all the official keywords, but
> there is no guarantee that other plugins won't break.

All existing calls to createIconButton, codebase wide, are updated, so
I'm not sure what would break.

> 2. How is the 'kind' param used?

It is used to set the arbitrary 'button_kind' property on buttons, so
they can be styled by kind rather than just their individual names.

> 3. The following comment in leoSettings.leo could be improved:

These are no longer present in trunk.

Cheers -Terry

Terry Brown

unread,
May 30, 2013, 12:17:59 PM5/30/13
to leo-e...@googlegroups.com
On Thu, 30 May 2013 10:55:14 -0500
"Edward K. Ream" <edre...@gmail.com> wrote:

> On Thu, May 30, 2013 at 9:30 AM, Terry Brown <terry_...@yahoo.com>wrote:
>
> > At last I remember. leo_color_database in leoColor.py is a dict whose
> > keys
> > > are color names and whose values are Qt color values (strings, starting
> > > with '#'.
> >
> > I you think it's necessary, that dict could be injected into the new
> > stylesheet macro expansion system. Currently I think the stylesheet
> > uses 2-3 named colors, so it's no big deal to define them directly in
> > the stylesheet, in a comment which is processed by the new stylesheet
> > macro expansion system.
> >
>
> We definitely should support expanded colors somehow.
>
> Rev 5800 does the following:
>
> 1. Restores the bg keyword arg to sc.createIconButton, in its original
> place, that is, before the "kind" keyword arg.
>
> This is compatible with your code, because it always uses kind=kind. This
> change ensures that no scripts or plugins can be broken by recent changes
> to createIconButton.

I don't think anything in the shared code base would have been broken,
but I guess this protects local scripts.

> 2. Adds the following code to createIconButton::
>
> if not bg.startswith('#'):
> d = leoColor.leo_color_database
> bg2 = d.get(bg.lower())
> if not bg2:
> print('bad color? %s' % bg)
> bg = bg2
> if bg:
> try:
> b.button.setStyleSheet("QPushButton{background-color: %s}"
> % (bg))
> except Exception:
> # g.es_exception()
> pass # Might not be a valid color.
>
> As a result, the following Leo script now works::
>
> from leo.plugins.mod_scripting import scriptingController
> sc = scriptingController(c)
> sc.createIconButton(p.h,command="",statusLine=p.h,bg='MistyRose1')
>
> I hope we are not working at cross purposes here. I like the general idea
> of using stylesheets to specify defaults, but I think stylesheets aren't
> dynamic enough for scripting. I plan no further changes to mod_scripting.
> Please feel free to make further changes as you will.

I think this is all ok as long as it all works together. I didn't
think it was worth restoring the bg parameter because I think it's not
dynamic enough for scripting ;-) It only sets the background color,
which is very limited, compared to

b = sc.createIconButton(p.h,command="",statusLine=p.h)
b.button.setStylesheet("""QPushButton {
background: #123;
foreground: #fda;
border: solid red 3px;
}
QPushButton:hover {
border-color: green;
}
""")

etc. etc.

Also with dark and light themes in existence it's not really safe to
specify only the background color - setting only one of foreground /
background is considered bad styling style.

But if nothing's broken right now, let's leave it that way.

Cheers -Terry

Edward K. Ream

unread,
May 30, 2013, 12:23:55 PM5/30/13
to leo-e...@googlegroups.com
On Thursday, May 30, 2013 10:58:50 AM UTC-5, Terry wrote:

> All existing calls to createIconButton, codebase wide, are updated, so I'm not sure what would break.

Our codebase is not the only consideration.  It's possible that Leo users have written private plugins or scripts that call createIconButton.

In general, all developers should ensure that no changes to the API can break existing code, including code of which we have no knowledge.

Edward

Edward K. Ream

unread,
May 30, 2013, 12:28:50 PM5/30/13
to leo-e...@googlegroups.com
On Thursday, May 30, 2013 11:17:59 AM UTC-5, Terry wrote:

 
> I hope we are not working at cross purposes here.  I like the general idea
> of using stylesheets to specify defaults, but I think stylesheets aren't
> dynamic enough for scripting.  I plan no further changes to mod_scripting.
> Please feel free to make further changes as you will.

I think this is all ok as long as it all works together.  I didn't
think it was worth restoring the bg parameter because I think it's not
dynamic enough for scripting ;-)  It only sets the background color,

Hmm.  I haven't noticed problems, but your point is well taken.  Perhaps a new "fg" argument would be good too ;-)

There is an interesting question underlying all this:  are stylesheets sufficient?  Perhaps they are, in which case the "bg" argument might really be deprecated.

Edward
Reply all
Reply to author
Forward
0 new messages