2

I have created a chat application, in which i use ListBox for showing the chat history. It looks good until I enter a long sting which goes beyond the screen. Is there a way to break the string and show in new line or any other way to show the complete string. I'm new to Tkinter and im not aware of many widgets available.

Here is my sample code

from tkinter import *

class Actions:
    def chatUpdate(chat):
        chatlist.insert(Actions.chatLast,chat)
        Actions.chatLast=Actions.chatLast+1
        chatlist.pack( side=LEFT, fill=BOTH)
        chatBox.config(command=chatlist.yview)


def callUpdater():
    txt=textBox.get()
    text_text.set("")
    Actions.chatUpdate(txt)


root = Tk()
root.title("Chat App")
frame1 = Frame(root, bd=4)
frame1.pack(side=TOP)

frame2 = Frame(root, bd=4)
frame2.pack(side=TOP)

frame3 = Frame(root, bd=4)
frame3.pack(side=TOP)

# chat box
chatBox = Scrollbar(frame1)
chatBox.pack(side=RIGHT, fill=Y)
chatlist = Listbox(frame1, yscrollcommand = chatBox.set, width=50)
Actions.chatLast=0
Actions.chatUpdate("                        ")

# text box
textView = Label(frame2, text="Input: ")
textView.pack(side=LEFT)
text_text = StringVar()
textBox = Entry(frame2, textvariable=text_text, bd=0, width=40, bg="pink")
textBox.pack(side=RIGHT)

# send button
button = Button(frame3, text="Send", fg="black", command=callUpdater)
button.pack(side=TOP)
root.mainloop()
Sathish Kanna
  • 171
  • 1
  • 8
  • This really depends on a few things. I see four methods you could use. 1) Use a `Listbox` widget and split the string whenever it is longer than the fixed width of the `Listbox` (this is hard and the only way I can find to do this is inefficient). 2) Use a `Listbox` widget and split the string at an arbitrary length such as 50 characters, 100 characters. 3) Use `Label` widgets to recreate this, this is what I would do and is *simpler* (subjectively) than using a `Listbox`. 4) Have the `Listbox` dynamically adjust in size, this could cause issues if a message is 10,000 characters long though. – Ethan Field Nov 29 '18 at 14:53
  • Personally, I would use `Label` widgets instead of a `Listbox` but this would require rewriting your program from the ground up. If any of the solutions sound right to you, I'd be happy to write up a full answer. – Ethan Field Nov 29 '18 at 15:00
  • Using Label seems to be a good idea, can that be inserted as a separate one for every entry. – Sathish Kanna Nov 29 '18 at 15:33

1 Answers1

2

You can replace the Listbox by a Text widget in 'disabled' mode which automatically wraps long lines. You will just need to put the widget back in 'normal' mode each time you insert text:

from tkinter import *

def callUpdater():
    text = textBox.get()
    textBox.delete(0, 'end')
    chat.configure(state='normal')
    chat.insert('end', text + '\n')
    chat.configure(state='disabled')

root = Tk()
chatBox = Scrollbar(root)
chat = Text(root, wrap='word', state='disabled', width=50,
            yscrollcommand=chatBox.set)
chatBox.configure(command=chat.yview)

chat.grid(row=0, columnspan=2, sticky='ewns')
chatBox.grid(row=0, column=2, sticky='ns')
Label(root, text="Input: ").grid(row=1, column=0)

textBox = Entry(root, bd=0, width=40, bg="pink")
textBox.grid(row=1, column=1)

Button(root, text="Send", command=callUpdater).grid(row=2, columnspan=2)
root.mainloop()

By the way, both the Listbox and Text widgets support the index 'end' so you don't have to keep track of how many lines you have inserted.

j_4321
  • 15,431
  • 3
  • 34
  • 61
  • is it possible to add image dynamically because when i tried using the below code in main loop it shows image but when i use in function it just displays blank white space in the image place image1 = Image.open('desktop.jpg') image1 = image1.resize((250, 250), Image.ANTIALIAS) photoImg = ImageTk.PhotoImage(image1) chat.image_create('end', image = photoImg) chat.insert('end', "\n") – Sathish Kanna Dec 01 '18 at 19:01
  • @SathishKanna Your image in the function is garbage collected, you need to keep a reference to it: https://stackoverflow.com/questions/16424091/why-does-tkinter-image-not-show-up-if-created-in-a-function – j_4321 Dec 02 '18 at 16:36
  • thanks it was really helpful. As said in the ref creating a instance variable (self.photoImg) made it – Sathish Kanna Dec 05 '18 at 13:29