问题
I'm writing a script to output things to a window comprising a Tkhtml widget and a text widget displayed above each other in a ttk::panedwindow. Both widgets are scrollable both vertically and horizontally. There's also a button allowing the user to clear the text widget.
I'm doing some of the development on a laptop running Ubuntu. The window manager allows for four desktop workspaces in a 2x2 array, and when the GUI is first displayed, the bottom fifth or so bleeds from the workspace I'm using into the one below. It's irritating to have to muck around resizing the window to make it short enough to fit onto the screen so I want to resize it.
(I think) I know approximately how to do this, i.e bind to an appropriate event so that I can run a script when the window is first displayed. (Reset the binding from within the script so that it only fires once.) I believed that the "appropriate event" was <Map>
, but when the window was first mapped, the two widgets had zero height (as reported by [winfo height]
). I tried binding to <Expose>
and this seems to work, ([winfo height]
returns sensible numbers,) so:
Question 1: Which event should I bind to?
When the binding fires, [wm geometry]
reports the geometry as 815x1029+49+24, [winfo height]
reports the two heights of the two widgets as 600 and 366, and [wm screenheight]
returns a height of 800. I know there are various other bits and pieces in the GUI so I'm not surprised that there are 63 pixels unaccounted for in the initial layout. I assume that I need the same amount of space after resizing, so I should request a geometry of 815x737+49+24, but when I do, a sliver (approximately the lower horizontal scrollbar) still bleeds onto the next workspace.
By mucking around manually, I know that when everything fits nicely onto the screen the geometry should be 815x717+49+24, so I've added a fudge factor of 20 to the amount of space I allow for the "other bits and pieces of the GUI". This works fine but seems a little inelegant (massive British understatement :-) ), so:
Question 2: What have I missed, requiring use of a fudge factor?
I'm using Tk 8.6.1 on Ubuntu 12.04.5 LTS. I'm using version 0.9.7.12 of the Compiz window manager.
Update
It struck me that I ought to find the height of the various panes, rather than the Tkhtml and text widgets as that would account for the scrollbars and the "Clear" button. The pane heights are 615 and 409 initially, but this just means that I have to increase my fudge factor from 20 to 78 to get the request height to my desired value of 717. Is there any way to predict what height to request for the toplevel containing my paned window in order to get that toplevel to fill the screen?
回答1:
I recommend binding to <Map>
. I would wait for all of: the paned window, the main tkhtml window, the text window and the scrollbars to be mapped before trying to adjust heights.
For Linux, the [winfo screenheight .]
does not know about any panels that are configured, so you have to subtract those. You can get the actual screenheight available by creating a window, doing a wm attributes . -zoomed 1
, then getting the geometry of the window.
The title bar and borders of the window take up space. The space needed for these can be calculated by comparing the output from [winfo geometry .]
and [wm geometry .]
.
There is also the panedwindow sash height and any margins and padding.
You can calculate the total of these by subtracting the panedwindow heights from [winfo height .]
.
Here is one method that would always work, however, it is not very attractive, as the user would see the windows flashing as they change size.
- Maximize the window (
wm attributes . -zoomed 1
) - Get the window geometry and parse out the screenheight.
- De-maximize the window (
wm attributes . -zoomed 0
) - Get the window geometry and replace the screenheight with the maximized screenheight.
- Set the window geometry.
来源:https://stackoverflow.com/questions/36378029/when-and-how-to-set-window-size-using-tk