How to align columns with multiple Tkinter checkbuttons? - python

I try to put sixteen checkbuttons into frame, placing them into four columns like:
c1 = Tkinter.Checkbutton(group.interior(), text = 'Name', indicatoron= 1, variable = self.Checkvar_nr, command=cb)
c1.(row = 0, column = 0)
and so on up to:
c16.(row = 3, column = 3)
Everything's fine except columns vertical alignment because of the differences in the length of the text used.
How to align then horizontally?

I don't quite understand the problem, since columns must be vertically aligned since it's a grid. I think what you're saying is that the items in each column aren't aligned to a column boundary. Try using sticky='w' when adding each checkbutton to the grid. This will cause them to "stick" to the left edge of the column.

As an option, try placing each element in a non-stretchable graphic element.
The thought is that the layout manager is maximizing the use of the screen real estate. Because you want to take up more space, which is contrary to the layout manager's algorithm, you will need to find a graphic container that doesn't "change size".
Sometimes you can do this through manually editing the text string (less preferred). Other times you can use a table like structure (HTML for instance). Other times you can use a frame with defined width and height attributes. These frames are then placed inside of the columns as elements.
Note: It's been a long time since I played with Tk. I'm going by memory. Best of luck!
(edit:) Going from memory, the columns will adjust their width based on content. If there are several three character labels in the first column and five character labels in the second column, the width of the two columns will be different. (Note: This will be depended on the layout manager.) If there is a 'fixed width' option for the layout manager in question, then it should keep all column widths the same.
With layout managers that rearrange with dimensions based on content (HTML, CSS, etc), it is sometimes necessary to place the content inside "immovable" containers. Usually these are frames. The frames work as bounding boxes. This approach works when the element that needs to have a width and height does not have that feature.

Related

Extract Text in Natural reading order using pymupdf (fitz)

I am trying to extract the text using pymupdf or flitz by applying this tutorial https://towardsdatascience.com/extracting-headers-and-paragraphs-from-pdf-using-pymupdf-676e8421c467
instead of
blocks = page.getText("dict")["blocks"]
I wrote
blocks = page.get_text("dict", sort=True)["blocks"]
according to https://pymupdf.readthedocs.io/en/latest/recipes-text.html
But still, the text is not in the order I expect. The first paragraph will appear in the middle.
This happens when a page has more than one column of text.
You made a good first step using the sort argument. But please note that PDF can address each single character separately, such that every basic sorting approach may fail with the "right" PDF counter example.
If a page contains n text characters, then there exist n! different ways to encode the page - all of them looking identical, but only one of them extracting the "natural" reading sequence right away.
If your page contains tables, or if the text is organized in multiple columns (as is customary in newspapers), then you must invest additional logic to cope with that.
If you use the PyMuPDF module, you can extract text in a layout preserving manner: python -m fitz gettext -mode layout ....
If you need to achieve a similar effect within your script, you may be forced to use text extraction detailed down to each single character: page.get_text("rawdict") and use the returned character positions to bring them in the right sequence.
BTW the sort parameter causes the text blocks to be sorted ascending by (1) vertical, (2) horizontal coordinate of their bounding boxes. So if in a multi-column page the second column has a slightly higher y-coordinate, it will come before the first column. To handle such a case you must use this knowledge for making specialized code.
Assuming you know have a 2-column page, then the following code snippet might be used:
width2 = page.rect.width / 2 # half of the page width
left = page.rect + (0, 0, -width2, 0) # the left half page
right = page.rect + (width2, 0, 0, 0) # the right half page
# now extract the 2 halves spearately:
lblocks = page.get_text("dict", clip=left, sort=True)["blocks"]
rblocks = page.get_text("dict", clip=right, sort=True)["blocks"]
blocks = lblocks + rblocks
# now process 'blocks'
...

Difference between sizes in pySimpleGUI

I would like to straighten my layout I made with pySimpleGUI. In the documentation, I found the Element Sizer which allows to specify a size in pixels. This does not seem to work easily with all other Elements which use a different measure for size (character width/height?). So if I create a layout like the following:
layout = [
[sg.Sizer(0,10), sg.Button("Test", size=(7,1))],
[sg.Text(size=(0,10)), sg.Button("Test", size=(7,1))]
]
The resulting window looks like this, with two unaligned buttons:
Is there a way to convert the "standard measure" used in most Elements to pixels? Or is simply using empty Text Elements best practise for this use case?

Python tkinter: table with variable row height possible?

For my sqlite-based search Python script (a kind of two-language translation dictionary, i.e. translation memory), I've decided to use tkinter and show results in a treeview.
Everything works OK, except for the fact that for longer strings, text gets truncated: table rows are always 1 line high. If I change row height, it then applies to the whole treeview, which is not what I want.
Judging from Brian Oakley's answer here:
How to change height of only one row in a Treeview?
it seems that having variable row heights in a treeview is not possible.
So, my question is whether it is possible (using tkinter) to have a table with e.g. 3-4 columns, in which I can vary row height, depending on number of lines of wrapped text?
Perhaps something using listboxes or labels?
This is what I have now with treeview:
And this is what I would like to have (note different row heights in the table - this was done in Perl/Tk):
So, is there any way to have such table with variable row heights, using Python and tkinter?

How wrap list within the frame boundaries in python Tkinter?

I am trying to list all the categories placed left of each other. The problem I am facing is that it is going beyond the frame boundaries and not coming down to the new line. Any work around for this ?
var = IntVar()
for i in xrange(len(ultraCategories)):
i = Radiobutton(midFrame,text=ultraCategories[i],variable=var,value=i,command=sel)
i.pack(side = LEFT)
If you use the .grid layout manager for Tkinter you can specify the row and column of where you would like to place each item. There is no built in function to split items in to a new row.
Tkinter Grid Layout

Finding The Current Size Of A tkinter.Text Widget

I am trying to create a roguelike using the Text widget.
I have figured out a few things, namely that I can set the size of the widget using width and height options and that I can find the pixel height or width of said widget. However, what I want to do is have the widget resizable (pack(expand="yes", fill="both")) but be able to refresh the displayed text on a resize. Is there a way to get the character dimensions when the widget is running without resorting to winfo_width() and math based on pixel dimensions of characters?
I've run into that exact same problem a couple times jaccarmac, and to my knowledge there is no way to find the width of a string of characters. Really the only way is to use the winfo_ commands: width, height, geometry. However, it kind of sounds like you just want to make sure that all of the text is displayed if you change the label and add more text. If that is the case, you don't have to worry about it. That should all be taken care of by the widgets themselves. If you don't see them expanding to show all of your label, that usually means one of the widgets containing that label is not set to expand (either using expand=YES with .pack, or columnconfigure(i, weight=1) for .grid).
A final thought; in the pack arguments make sure it's YES, and not "yes". That uppercase YES is not a string, but a variable name defined by Tkinter.
There is no way to automatically get the width in characters, but it's easy to calculate, assuming you're using a fixed width font. One way to do this is to use the font_measure method of a font object. Use font_measure to get the width of a '0' (or any other character for that matter; I think tk users zero internally, not that it matters with a fixed width font), then use this in your calculations.
This is an old question, but after doing some research I've found that there actually is a way to get height/width info directly without maths or playing with font widths using the Text widget's cget() method:
text_widget = tk.Text()
width_in_char = text_widget.cget('width')
height_in_char = text_wdiget.cget('height')
Since the Text widget stores its height and width configuration in characters, simply querying for those parameters will give you what you're looking for.

Categories

Resources