The overall idea I have is to eventually add a button to my stickyNote nodes when I create them that when clicked would run a script that would give me a pop up window allowing me to change the value. Second idea was I had was for it just take the value within the default created and have it be empty rather than having the default values that appear on creation of "type note here".
I have tried to just set the value to ("") in my mind nothing would be in there, but the node still creates with the "type note here"
def setColor(R,G,B):
return int("%02x%02x%02x%02x" % (R,G,B,1),16)
def StickyNoteOverride():
nuke.thisNode()["tile_color"].setValue(setColor(R=(255*.298),G=(255*.298),B=(255*.298)))
nuke.thisNode()["note_font_size"].setValue(60)
nuke.thisNode()["note_font_color"].setValue(setColor(R=(255),G=(255*.624),B=(255*.0)))
nuke.thisNode()["note_font"].setValue("Deja Vu Sans Bold")
nuke.thisNode()["label"].setValue("")
####nuke.thisNode()['label'].setText("")
####nuke.thisNode()['label'].setText("1")
nuke.addOnUserCreate(StickyNoteOverride, nodeClass = "StickyNote")
My expected code so far does everything I want it too except for changing default on usercreate value to either nothing in the field, or to the value of 1 which I was using through the .setText to just get it to print anything in the field or change the field. .setText change was tried on an already created stickyNote to change the value. When running .setText("1), the value comes back with .getValue usage as having a value of 1 in the field. But the actual node did not change at all. And I am getting stuck in just changing this value of the label before I progress forward further with learning how to have it create a user defined button.
It just works for both variants - for string value "Lorem Ipsum Dolor..." and for empty string "":
def stickyNoteOverridden():
colour = int('%02x%02x%02x%02x' % (0,128,64,1),16) # Greenish
nuke.thisNode()["tile_color"].setValue(colour)
nuke.thisNode()["note_font_size"].setValue(60)
nuke.thisNode()["note_font_color"].setValue(100)
nuke.thisNode()["note_font"].setValue("Deja Vu Sans Bold")
# nuke.thisNode()["label"].setValue("Lorem Ipsum Dolor...")
# nuke.thisNode()["label"].setValue("")
nuke.addOnUserCreate(stickyNoteOverridden, nodeClass = "StickyNote")
nuke.createNode("StickyNote")
A key moment here is to use .createNode() command:
nuke.createNode("StickyNote")
Tested it in NukeX 11v3.5 NC on macOS Mojave 10.14.6.
Related
My problem is I can't find the command to change the background color of DataViewListCtrl for selected text/row/item in DataViewListCtrl object.
I looked into the documentation but there's no apparent reference.
https://docs.wxpython.org/wx.dataview.DataViewCtrl.html#wx-dataview-dataviewctrl
I'm using the sample_one.py script from this reference:
https://wiki.wxpython.org/How%20to%20add%20a%20menu%20bar%20in%20the%20title%20bar%20%28Phoenix%29
The DataViewListCtrl has this example code:
self.dvlc = dv.DataViewListCtrl(
self,
style=dv.DV_MULTIPLE
| dv.DV_ROW_LINES
| dv.DV_HORIZ_RULES
| dv.DV_VERT_RULES,
)
self.dvlc.SetBackgroundColour("#ffffff")
self.dvlc.SetForegroundColour("black")
What I'm looking to do is similar to Tkinter example below (change the selected text background color to blue):
style.configure(
"Treeview", background="#FFFFDD", foreground="black", fieldbackground="#FFFFDD"
)
style.map("Treeview", background=[("selected", "#F0FFFF")])
I haven't been able to try a workaround yet as I'm not sure how to get the needed command/value, but on my end the selected DataViewListCtrl items have a #242424 color (I checked with an eyedropper from a screenshot).
I found the 2 parameters IsSelected and IsRowSelected in the doc:
https://docs.wxpython.org/wx.dataview.DataViewListCtrl.html#wx.dataview.DataViewListCtrl.IsRowSelected
https://docs.wxpython.org/wx.dataview.DataViewCtrl.html#wx.dataview.DataViewCtrl.IsSelected
and tested as
self.dvlc = dv.DataViewListCtrl(
self,
style=dv.DV_MULTIPLE
| dv.DV_ROW_LINES
| dv.DV_HORIZ_RULES
| dv.DV_VERT_RULES,
)
# Give it some columns.
self.dvlc.AppendTextColumn("Id", width=40)
self.dvlc.AppendTextColumn("Artist", width=170)
self.dvlc.AppendTextColumn("Title", width=260)
self.dvlc.AppendTextColumn("Genre", width=80)
# Load the data. Each item (row) is added as a sequence
# of values whose order matches the columns.
for itemvalues in musicdata:
self.dvlc.AppendItem(itemvalues)
# — 1st test with same result as 2nd below
# if self.dvlc.IsSelected == True:
# self.dvlc.SetBackgroundColour("#0066ff")
# else:
# self.dvlc.SetBackgroundColour("#F0FFFF")
if self.dvlc.IsRowSelected == True:
self.dvlc.SetBackgroundColour("#0066ff")
else:
self.dvlc.SetBackgroundColour("#F0FFFF")
self.dvlc.SetForegroundColour("black")
I tried also without the == True explicit as
# — 1st test with same result as 2nd below
# if self.dvlc.IsSelected:
# self.dvlc.SetBackgroundColour("#0066ff")
# else:
# self.dvlc.SetBackgroundColour("#F0FFFF")
if self.dvlc.IsRowSelected:
self.dvlc.SetBackgroundColour("#0066ff")
else:
self.dvlc.SetBackgroundColour("#F0FFFF")
and the unexpected blue background displays by default (when not selected).
Is there some documented "selected" parameter or otherwise known working method to be able to capture the selected background color and change it in WxPython?
You will have to use a custom renderer if you want to change the way the selected items background is rendered -- and you will have to overwrite the entire background entirely, as the default one will still be drawn, you will just be able to paint over it.
Alternatively, you can define a custom wxRendererNative-derived object and override its DrawItemSelectionRect() method and then set it as the renderer to use globally. This should be simpler, but it will change selection drawing in all controls using this function.
I wanna build GUI and there is a button which Combobox adds every time the button is pressed. but i cant find out how to figure or code this concept
And, is there any other Widget? or is there other way to build my concept??
please some one help me..
the main concept without using tkinter is Like this shown . i want this concept to be made in Tkinter.
[THIS IS WHAT I TRIED BUT WHENEVER I PRESS THE BUTTON, ALL COMBOBOX ADDED WORKS TOGETHER (which means when i change the list name, all combobox also changes..)]
def Plus_EXT():
button_plus = Button(window3,justify = CENTER,command = Add_EXT, text= "+")
button_plus.grid(row=0,column=0)
def Add_EXT():
global Num
window3.update()
Num += 1
CEList1 = [x for x in os.listdir(cur_dir) if ('CE' in x.upper()) and ('.rpt' in x)]
RPT_EXT_file=ttk.Combobox(window3, values=CEList1,textvariable= EXT_String)
RPT_EXT_file.grid(row=8+Num,column=1)
RPT_EXT_file.set("FILE")
[MAIN CONCEPT WITHOUT USING TKINTER]
CE_Num= int(input("How Many EXTRA Chordae?: "))
User_File = input("Type the New File Name: ")
for Num_Of_EXT in range(CE_Num):
RPT_EXT_file = input("Type the RPT of EXTRA CHORDAE: ") + ".rpt"
EXTRA(User_File,RPT_EXT_file,Num_Of_EXT)
EXTRA_PLT(User_File,Num_Of_EXT)
the output i want is { everytime i press the button a new Combobox is added in the frame with the lists which works separately.}
The issue is that all your Combobox widgets are linked with same textvariable called EXT_String.So when you change the value of one Combobox widget, it updates same value in all of them.
I would suggest to keep a list of such variables and index that list using NUM in your loop to assign the textvariable.
UPDATE:
Just an example based on limited code shared in Add_EXT method:
global var_list
var_list.append(IntVar()) #Or StringVar(), whatever you are using
RPT_EXT_file=ttk.Combobox(window3, values=CEList1,textvariable=var_list[-1])
I wrote the below code to bind event and do operations on individual listbox items.
import tkinter as tk
root = tk.Tk()
custom_list = tk.Listbox(root)
custom_list.grid(row=0, column=0, sticky="news")
def onselect_listitem(event):
w = event.widget
index = int(w.curselection()[0])
value = w.get(index)
print(index, value, " color : ",custom_list.itemcget(index,'background'))
custom_list.itemconfig(index, fg='gray', selectforeground="gray")
custom_list.bind('<Double-Button-1>', onselect_listitem)
for k in range(20):
custom_list.insert(k, " --------- " + str(k))
root.mainloop()
I am having trouble using itemcget to get the background properties while itemconfig works properly. Everything else is working. Can someone tell me if there is something wrong? I am trying to obtain the current item background color via index of the item in the listbox. The part with custom_list.itemcget doesn't print anything.
Thanks
From the New Mexico tech Tkinter reference:
.itemcget(index, option)
Retrieves one of the option values for a specific line in the listbox. For option values, see itemconfig below. If the given option has not been set for the given line, the returned value will be an empty string.
So since you haven't set the background option, itemcget returns an empty string. You can see this working by changing the print to custom_list.itemcget(index,'fg'). The first time you doubleclick you get an empty sting because you haven't set it, the second time it prints gray.
I am using a standard tkinter entry to input a directory path. When the user presses enter - if the physical length of the string exceeds that of the entry, I want the program to modify the displayed text to ...[end of directory]. I have the logistics of this figured out but as of yet I have no accurate way to test whether the entry box is full, or how full
Things I have tried:
Using 'PIL.ImageFont.truetype("font.otp",fontsize).size' - cannot calculate the point at which to cut the directory
Simply using the length of the string against the length of the entry- inaccurate as the font I am using (which I don't want to change if possible) varies in length with each character
Another compromise behaviour which I tried was to make the entry "look" at the start of the path. I tried inserting at, selecting at and moving the cursor to position 0 but none of these worked
You can use xview method of Entry. xview return the visible part of the text displayed in the entry. You can use it to interactively create a text that fit the entry.
Here is a quick and dirty proof of concept
from tkinter import *
root = Tk()
v = StringVar(root)
e = Entry(root,textvariable=v)
e.pack(fill=BOTH)
v.set('abcdefghijklmnopqrstuvwxyz0123456789')
new_s = None
def check_length():
global new_s
original_s = v.get()
def shorten():
global new_s
e.xview(0)
if e.xview()[1] != 1.0:
new_s = new_s[:-4] + '...'
v.set(new_s)
print("new_s: " + new_s)
e.xview(0)
e.after(0,shorten)
print(e.xview()[1])
if e.xview() != (0.0,1.0):
new_s = original_s + '...'
shorten()
b = Button(root,text="hop",command=check_length)
b.pack()
e.mainloop()
My program is an IFS editor which has two windows: one for displaying a fractal and the other for working with the corresponding IFS. The latter requires a grid of entries containing the values of linear transformations. Since I need 24 entries (6 entries for each linear transformation, and 4 transformations), I defined instead a table of entries using some for loops. I know that I have to set textvariable to StringVar and use StringVar.set() for putting in some default values, but when I run my program, the entries are still empty.
This is what I have. Here "matrices" is a 4x6 matrix of floats:
FunctionEntries=[[],[],[],[]]
FunctionSetEntries=[[],[],[],[]]
for i in range(4):
for j in range(6):
FunctionSetEntries[i]=FunctionSetEntries[i]+[Tkinter.StringVar()]
k=Tkinter.Entry(window, width="5", textvariable = FunctionSetEntries[i][j])
FunctionSetEntries[i][j].set(matrices[i][j])
FunctionEntries[i]=FunctionEntries[i]+[k]
FunctionEntries[i][j].grid(row=3+i,column=j+1)
FunctionEntries=FunctionEntries+[FunctionEntries[i]]
The strange part is that when I defined some other entries individually, everything was ok. Here were some of the entries that showed the default values correctly:
P=[0.85,0.07,0.07,0.01]
probs1=Tkinter.StringVar()
probs1.set(P[0])
probs2=Tkinter.StringVar()
probs2.set(P[1])
probs3=Tkinter.StringVar()
probs3.set(P[2])
probs4=Tkinter.StringVar()
probs4.set(P[3])
probLabel=Tkinter.Label(FractalWindow, width="15")
probLabel.configure(text="probabilities= ")
probEntry1=Tkinter.Entry(FractalWindow, width= "5", textvariable = probs1)
probEntry2=Tkinter.Entry(FractalWindow, width= "5", textvariable = probs2)
probEntry3=Tkinter.Entry(FractalWindow, width= "5", textvariable = probs3)
probEntry4=Tkinter.Entry(FractalWindow, width= "5", textvariable = probs4)
The last few were in a different window, so is that part of the issue? But everything else in both windows is running fine as far as I can tell. I also don't see any difference between what I did here and what I did in the previous case (the order of the entry definition and .set() didn't change anything). The grids also display properly. The only thing wrong is that the entries are empty. What's going on here?
Thanks!
EDIT: There seems to be a problem with the double windows. I defined FractalWindow first, and the default values for my entries appear in FractalWindow, but not "window". On the other hand, if I define "window" first, the default values appear, but not for those in FractalWindow. Why is this happening?
FunctionSetEntries[i]=FunctionSetEntries[i]+[Tkinter.StringVar()] is going to contain a StringVar() 6 times, one for each "j". If you use one list with 24 entries for simplicity to start out, you can just do the following (and note that you only have to keep a reference to either the Entry or StringVar, not both, to get/set the contents).
function_entries=[]
for i in range(4):
for j in range(6):
s_var=Tkinter.StringVar()
function_entries.append(s_var)
Tkinter.Entry(window, width="5", textvariable = s_var).grid(etc)
## proof of concept when not using a nested list
for num in range(24):
row, column=divmod(num, 6)
print num, row, column
for row in range(4):
for column in range(6):
print "list offset for %d, %d = %d" % (row, column, row*6+column)
Ok I figured it out. I needed to set one of my windows as Toplevel() instead. That enables me to use StringVar in both places. So something like
window=Tkinter.tk()
FractalWindow=Tkinter.Toplevel()
should do the job.