0

So I have 2 rows dedicated to a messaged label widget to display any successful/unsuccessful messages to the user while they're using the tkinter GUI. Some of the messages are to long to fit within the column width, so I have used the wraplength feature for the Label widget to wrap the text to the next line.

The issue that I'm having, is that because of this feature, it shifts the placements of the widgets underneath this widget, by 1 row for every new row it wraps the text onto.

So I was wondering if there's any way to have the text wrap, without moving the lower widgets.

How the message Label looks within the GUI with height = 1: enter image description here

How the message Label looks when it wrap's the text to a newline with height = 1:

enter image description here

How the message Label looks within the GUI with height = 2: enter image description here

How the message Label looks when it wrap's the text to a newline with height = 1: enter image description here

I would like for the message Label in the 2nd image link to display the way it does, but keeping the vertical layout of the widgets as seen in the 1st image link.

The following code is for defining the widgets:

Choice_list = Listbox(window, selectmode=SINGLE, width = 17, height = 9,
                justify = CENTER)

image = PhotoImage(file = 'Dummy_Logo.gif')
Image_label = Label(window, image = image)

extract = Button(window, text = "Archive News from Webpage",
             command = func1, width = 20)
archive = Button(window, text = "Extract News from Archive",
             command = func2, width = 22)
display = Button(window, text = "Display the News",
             command = func3, width = 14)

Message_Widget = Label(window, text = '', fg = 'black', justify = CENTER,
                   height = 2, wraplength = 300)

Log_Event = Checkbutton(window, text = 'Log Event', variable = logState,
              command = logEvent)

The following code is the grid alignment for the widgets:

Image_label.grid(row = 1, column = 1)
Choice_list.grid(row = 1, column = 2, rowspan = 9, sticky = W)
Message_Widget.grid(row = 2, column = 1, rowspan = 2)
Log_Event.grid(row = 12, column = 2)
archive.grid(row = 13, column = 1, rowspan = 2, sticky = W)
extract.grid(row = 13, column = 1, rowspan = 2, sticky = E)
display.grid(row = 13, column = 2, rowspan = 2, sticky = W)
Dani Green
  • 21
  • 1
  • 6
  • 2
    Hard to say without a [mcve], but does `Message_Widget.grid(row = 2, column = 1, rowspan=2)` help at all? – Kevin Oct 24 '17 at 14:27
  • Unfortunately no it does not. Even with rowspan = 2 it still gives the same result. – Dani Green Oct 24 '17 at 14:30
  • You can't _just_ do `rowspan=2`. You need to change the layout of the GUI to accommodate that rowspan. – PM 2Ring Oct 24 '17 at 14:33
  • Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: [How to create a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). – Ethan Field Oct 24 '17 at 14:36
  • I'm not completely sure what you mean by that. There are 11 rows of space between the message Label and the 3 button widgets bellow it. You just can't see all those rows, because the listbox widget on the far right spans across 9 rows. By having message label rowspan = 2, there should be more than enough room for it? – Dani Green Oct 24 '17 at 14:39
  • 4
    Show us your code. You're asking us to fix a problem blindfolded right now. – Ethan Field Oct 24 '17 at 14:40
  • @DaniGreen From your code I can see that you're giving the label `height = 1`, Bryan has given you an answer asking you to change this to `height = 2` or `height = 3`. – Ethan Field Oct 24 '17 at 15:25
  • You might benefit from using a text widget instead. You can define the height of 1 and the box will not change in size if there are several rows of data. – Mike - SMT Oct 24 '17 at 15:41
  • From what I can tell @DaniGreen is trying to have the label move back down to a height of 1 when the label updates with text on only one row. It should not be hard to deal with however we cannot test the problem with out seeing [MCVE](https://stackoverflow.com/help/mcve) – Mike - SMT Oct 24 '17 at 15:48

3 Answers3

1

Give the label a height of 2 or 3. The problem is simply that it wants to be one character tall by default. Tkinter will allocate only one character worth of height when laying out all the widgets. When the text wraps, the label simply must become taller so that the text will fit.

By giving it a height of 2 or 3 to start out, that extra space is built-in to the GUI. When the text wraps, the label doesn't have to grow to accommodate the new text.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Alright, so that did help in a way. When I make it height = 2, it produces a GUI layout identical to image 2, so i tried making the height = 1 (since i want a result identical to image 1), but this squishes the text from two lines into the single row. Is there any way to have the wrapped text simply move into the row directly underneath, instead of being wrapped down in the same row? – Dani Green Oct 24 '17 at 14:47
  • 1
    @DaniGreen: I don't understand your question. If you need more help, you're going to have to create a [mcve] so that we can duplicate the problem. The short answer is, if you have two lines of text, it's going to require a label that has a height of 2 lines. – Bryan Oakley Oct 24 '17 at 14:56
  • I'm asking if there's any way to wrap to a new row instead of a new line within the same row. If there's no way to do that, i will try to provide my code for producing this GUI, however there is quite a bit of code. – Dani Green Oct 24 '17 at 15:02
  • 4
    @DaniGreen: your use of terminology is confusing. I don't know what you mean by "wrap to a new row". Are you asking how to get the label to occupy two rows in a grid layout? if so, just specify 'rowspan=2' when calling grid. Rest assured, what you want to do is possible. The problem is, without a [mcve] it's impossible to know for sure what you're asking. – Bryan Oakley Oct 24 '17 at 15:04
  • 4
    @DaniGreen: please _don't_ "provide my code". We don't want all your code. We want you to create the smallest possible program that illustrates the problem you are having. If your problem is with a label and a few rows in a GUI, that's all we need to see. It shouldn't take more than a dozen or two lines of code. – Bryan Oakley Oct 24 '17 at 15:06
1

This might not be a proper method of solving this problem, however I have managed to get the outcome I was looking for by only adjusting the rowspan parameter in the Message_Widget to rowspan = 11.

Message_Widget.grid(row = 2, column = 1, rowspan = 11)

This produced the following results:

With a short text: https://i.stack.imgur.com/XpGLq.png

With a long text: https://i.stack.imgur.com/iXwlR.png

Dani Green
  • 21
  • 1
  • 6
  • Judging by your results that does appear to be the correct method. I did not realize you were ok with the initial size of the label to be 2 tall. – Mike - SMT Oct 24 '17 at 18:02
0

Have you considered using a text widget for the readout?

For example this below code will wrap the text if it is to long and it will not resize the widgets. This is just an example but should be enough to help you with you problem.

from tkinter import *
import random

root = Tk()

text1 = Text(root, height=1, width=40, wrap="word")
text1.grid(row=0, column=0, sticky="ew")

def update_lbl1():
    x = ["Click and drag to see some much longer random text for updating label!!!","some short data"]
    text1.delete("1.0", "end")
    text1.insert("1.0", random.choice(x))

Button(root, text="Change label from list", command = update_lbl1).grid(row=1, column=0)

root.mainloop()
Mike - SMT
  • 14,784
  • 4
  • 35
  • 79