I create script for playblast. I need some HUD data over my video like a user and scene name, fps and current frame...
First i try HUD created by headsUpDisplay() is good, but not have a background... I change color of HUD labels but sometimes they are not readable without a background.
cmds.headsUpDisplay('HUDObjectSceneName', label='label TEXT',
section=2, block=0, blockSize='large',
dfs='large', labelFontSize='large')
Second i try use HUD buttons created by hudButton() - they have a background. But one of my label - is current time. headsUpDisplay() have 'command' to refresh and change label text. But hudButton() does not have this functionality.
label = 'FPS: 25 FRAME:'
cmds.hudButton('HUDHelloButton3', s=9, b=0, vis=1, l=label,
bw=blockLen(label), lfs='large')
cmds.headsUpDisplay('HUDCurentFrame', label=label,
section=9, block=0, blockSize='large', dfs='large',
labelFontSize='large', atr=True,
command=lambda: cmds.currentTime(query=True))
hudButton() have second trouble - width of button is set manually. and when i want long label i need to calculate label width. but HUD font is not fixed and i don't know how right calculate a label width in pixels. After some experiments i create this function to calculate width. It made rough, but at least as that:
def blockLen(label):
FONT_WIDTH = 8
THIN_WIDTH = 6
BLOCK_ADD = 10
thin_symbol = ' :,.!i[];:\'"|-'
sum = BLOCK_ADD
for x in label:
sum += THIN_WIDTH if x in thin_symbol else FONT_WIDTH
return sum
I need HUD label with background and dynamic data like a current frame. But i can't find another way how create it?
ps. I try to use scriptJob() to change HUD button label when time changed. But its not worked with playblast...
scriptJobs do not execute when animations are playing. If you really need to update the hud during playback you can trigger your update from inside an expression. You'll have to call it from mel, unfortunately. And keep it as light as possible, it will slowdown interactive playback for anybody viewing the animation.
You might want to dynamically create the expression before playblasts and then delete it right afterwards so you don't leave it lying around to bother your animators.
You can also get out of using HUD buttons by creating an image plane set to an appropriate color.
One part of my problem i decided to. I don't find how to update button directly. I create headsUpDisplay() without label - he is able to updated. And i forced him to change the text on my hudButton()
def frame_label():
label = 'FPS: 24 FRAME: %s' % cmds.currentTime(query=True)
cmds.hudButton('HUDCurentFrame', e=True, l=label)
# bottom-right: FPS and current frame info
cmds.headsUpDisplay('HUDCurentFrameInvisible', label='',
section=9, block=1, blockSize='large', dfs='large',
labelFontSize='large', command=frame_label, atr=True)
cmds.hudButton('HUDCurentFrame', s=9, b=0, vis=1, l='', bw=200, lfs='large')
But second part of my problem not solved. I cant calculate text size in pixels. The correct solution is to get from the Maya which font is used for HUD. And then i can use wx library to calculate width of text using font name...
But how to get font data (name, size and decorations) from Maya?
to your second problem:
i was able to find the needed font data (only name, size) but its not really accurate(more hacking, no voting needed), if you change the view port renderer to ViewPort 2.0 and than
and changing the sizes of the font you will get the Error (nor on the default renderer):
# small display ui font size and display ui size
cmds.displayPref(sfs=9, dfs=10) #font size
cmds.savePref()
Failed trying to load font: -*-helvetica-bold-normal-*-9-*-*-*-*-*-iso8859-1
so the used font is helvetica bold and the size is relativ(you own input or the default value like cmds.optionVar(q="defaultFontSize"))
Related
I created a canvas and inside I put an image. I also can change the properties of the watermark text and would like to update the text on the canvas when I make some changes.
I created the text inside of the canvas with create_text and when I initialize the program, I created a variable. text_variable = canvas.create_text(...) However, I couldn't also adjust the opacity of the text.
Problems:
I can't adjust the opacity
I can't update color, font style, font size and position after I put this text on the canvas.
I expect:
Change the text when I change some properties from the edit menu
Add opacity adjustment to the text
self.watermark_display = self.display_canvas.create_text(self.watermark_start_position_x, self.watermark_start_position_y, text="Plese write your watermark!", font=(self.fonttype.get(),self.fontsize.get()),fill=self.color_choice)
def update_watermark_display(self):
self.display_canvas.itemconfig(self.watermark_display, self.watermark_start_position_x, self.watermark_start_position_y, text="Plese write your watermark!", font=(self.fonttype.get(),self.fontsize.get()),fill=self.color_choice)
When I try to do with this way, I got Type Error.
self.display_canvas.itemconfig(self.watermark_display, self.watermark_start_position_x, self.watermark_start_position_y, text="Plese write your watermark!", font=(self.fonttype.get(),self.fontsize.get()),fill=self.color_choice)
TypeError: Canvas.itemconfigure() takes from 2 to 3 positional arguments but 4 were given
You cannot use itemconfig to change the coordinates. Instead, use the coords method for the coordinates, and itemconfig for the item configuration.
self.display_canvas.itemconfig(
self.watermark_display,
text="Plese write your watermark!",
font=(self.fonttype.get(),self.fontsize.get()),
fill=self.color_choice
)
self.display_canvas.coords(
self.watermark_display,
self.watermark_start_position_x,
self.watermark_start_position_y
)
Situation:
I'm making a software that has to be full screen
It is all UIs and interfaces.
I want it to work on computers with screens that have different resolutions - So I need the GUI to adjust to the screen size: text will be smaller if the screen resolution is smaller, but it will still be in the middle of the screen
I've tried not using numbers in deciding the position of the text, but instead getting the screen resolution, and multiplying it
Problem:
The text is not getting smaller.
Question:
Is there an easy solution for my problem? Is there a module in python for this purpose? I'm currently using WxPython but I'm open to use any other GUI module.
def Title(object):
(sizeX, sizeY) = object.GetSize()
(displayX, displayY) = wx.GetDisplaySize()
print(displayX)
print(displayY)
print(sizeX)
print(sizeY)
object.SetPosition((displayX/2 - sizeX/2, displayY*0.01))
To adjust the text size to be appropriate to the screen size, you would have to define a custom font size.
Although I suspect that the default font size will already be roughly correct, as the user will have set the system font size, based on the screen size.
You can get the current font size as follows:
self.font = wx.SystemSettings.GetFont(wx.SYS_SYSTEM_FONT)
point_size = self.font.GetPointSize()
Define a new, appropriate, font size based on the result from wx.GetDisplaySize():
self.font.SetPointSize(new size)
Then use SetFont(font) on the items in your UI:
self.panel.SetFont(self.font)
I am trying to build a small software with the Tkinter module and python but I can't figure out how to set a widget size with percentages instead of pixels. I could of course do it by grabbing the size of the entire window at every moment and divide by 2 to get a size of 50%, but is there a better way to do it with the Tkinter module?
EDIT 1: To answer your questions I put my code here:
class Navbar:
def __init__(self, master):
self.maxsizeFrame = Frame(master, height = 50) #maxsize handler, prevent self.frame to grow too big
self.maxsizeFrame.pack(fill = X, expand = NO)
self.frame = Frame(self.maxsizeFrame)
self.frame.pack(side = TOP, fill = BOTH, expand = YES)
self.masteries = Button(self.frame, text = "Masteries")
self.masteries.pack(side = LEFT, fill = BOTH, expand = YES)
self.runes = Button(self.frame, text = "Runes")
self.runes.pack(side = RIGHT, fill = BOTH, expand = YES)
So I want to create a navigation bar with two button handled in "self.frame". But I want this design to be responsive, that's why I set expand to "YES". However I wanted to set a maximum size for "self.frame" but the only way I found was to pack this frame in an other one ("self.maxsizeFrame") and set expand to "NO" on this one. And finally, I would like to set the maximum expand size to half the main window, so it could be great if the height of "self.maxsizeframe" could be in percentage. Thanks for reading.
EDIT 2:
Actually it seems more efficient to build the software with the grid layout and the weight's option would be accurate.
If you would like to make it half the size of the window, use width=root.winfo_width / 2, height=winfo_height
In the maximum size. (I had to post it late due to the limit of posting per 30Mins
Ok, I wonder how no one responded yet.
So instead of sizing the component at the moment of creation, you can instead use the widget.place() method, define relwidth and relheight (0=0%,0.5=50%,1=100%,etc), this will give the widget x% of its parent width/height. Using place() you can also define relative starting positions for the widgets using relx and rely, and even apply width,height,x, and y by specifying screen units as you would do normally.
Now the fun stuff, which I don't see talked around, is that you can apply relwidth and width at the same time,by playing with negative values and joining relx and x properties, you can get really responsive sites.
Here is an example where I played a bit with this fields to get the responsiveness I've desired:(don't mind 'yposition' comes from the application context)
self.label.place(rely=yposition,x=0.025,relheight=0.04,width=150)
self.entry.place(rely=yposition,x=150,relheight=0.04,relwidth=0.95,width=-190)
self.button.place(rely=yposition,relx=0.98,x=-40,relheight=0.04,width=40)
Although it depends on the widget, you should be able to do width=30% and same with height. Can you please edit your post saying which widget you are using. I would not recommend percents though as they get funky some times.
Renpy uses a lot of python and custom made code, in order to show text that is displayed on screen using the say statement.
After running into some troubles with the nvl mode within renpy, I found it necessary to know how many lines are going to be displayed on screen (taking into account the font size, naturally and the size of the text window).
So my question:
As I didn't find anything in the documentation in regards to that, I'm wondering if there is any command or other possibility to precalculate the height of a text that is to be displayed?
get_virtual_layout() is part of class Text in text.py.
I copied this from text.py:
# Find the virtual-resolution layout.
virtual_layout = self.get_virtual_layout()
# The laid-out size of this Text.
vw, vh = virtual_layout.size
This looks promising, I think.
With the virtual text size (width, height) you could possibly calculate the lines of text by using the text window size (width, height).
pseudo code:
lines = int(vw/text_window.width)
#the text height would then be
text_height_needed = int(lines*vh)
# does it fit in completely
complete_text_in_window = text_window.height >= text_height_needed
# visible lines
visible_lines = int(text_window.height/vh)
Also, it is worth to take a deeper look at text.py(e.g. def render(self, width, height, st, at)), in order to get to know the use of virtual_layout.
I hope it helps somehow.
Update:
def render(...) initializes the virtual layouts, so get_virtual_layout() is not None anymore, but represents an instance of Layout() with scaled width and height.
I'm trying to create a multiline button with PyGTK. I have a label added to my subclass of gtk.Button, but I'm having trouble sizing the label to the button. If the label makes it's own size, there is no text wrapping even with label.set_line_wrap(True) because the label simply resizes beyond the bounds of the button. I would set the size of the label to that of the button, but unless I explicitly set the size of the button using set_size_request, I haven't been able to find out how big the button is (it's packed in a table).
Any suggestions?
In general, this is not possible with GTK+, because there is no stage where widgets "negotiate" sizes. Instead, widgets report their required size and after that container allocate some areas (normally, equal to or larger than required). In GTK+ 3 there will be width-for-height negotiation, so if your button (rather its label) is anyway going to be allocated several lines, it will be able to request less width and wrap its text.
In 2.x the best you can do is probably use width_chars property of gtk.Label:
import gtk
window = gtk.Window ()
align = gtk.Alignment (0.5, 0.5)
button = gtk.Button ('a very long, possibly multiline text')
label = button.child
label.props.wrap = True
label.props.width_chars = 20
window.set_default_size (500, 500)
window.connect ('destroy', lambda *ignored: gtk.main_quit ())
window.add (align)
align.add (button)
window.show_all ()
gtk.main ()
I found that in Python 3.4 GTK+3 all you need to do is add a \n where you want the break. It doesn't autowrap but you can have multiline labels for button objects. For example,
self.button = Gtk.Button(label="A lotta text \n and a lotta more.")