I'm writing a little Chatserver/-client to learn Python.
Now I want to make the consoleinput a little bit nicer, but I don't know how to do it...
Everytime I recieve a message from the socket, I do print() in the listening thread.
But then the text already entered to input() is over the printed message and the cursor is at the bottom.
What can I do, that is works like in Minecraft-Server, so the text already entered moves to the bottom?
Would be great if someone can help :)
You can't get that level of control with the console, but you can use python's default tkinter to make a simple UI. Below is an example (Python 3) that I whipped up in a few minutes. You can type in messages, press send, and they will appear in the box above.
from tkinter import *
from tkinter import ttk
def send(view, entry):
view.insert('1.0', entry.get() + "\n")
root = Tk()
msgview = Text(root, width=100, height=20)
msgview.grid(sticky=(N,E,S,W))
mymessage = StringVar(value="type here...")
msginput = Entry(root, textvariable=mymessage)
msginput.grid(sticky=(E,W))
sendbutton = ttk.Button(root, text="send",\
command=lambda: send(msgview, msginput))
sendbutton.grid()
root.mainloop()
I suggest looking at the tkdocs tutorial over the effbot one, since it is clearer, easier to follow and is more thorough in my opinion. New Mexico Tech also provides a great reference for tkinter here
Related
I have a program in python which in which I use Listboxes, buttons and labels. So today I came conflicting with a problem. I wanted to make my listbox appear when a button is clicked and disappear when the same button is clicked again. How can I achieve this? I tried using the winfo_ismapped() method but didnt seem to work. I think I might have done something crazy. If so, please point it out and give me a corrected answer. Else please tell me a better way to do it.
My Code:
import tkinter as tk
from tkinter import *
root = tk.Tk()
root.geometry('500x500')
def showMenu():
overlay = Listbox(root, bg="green", height=22, width=58)
if overlay.winfo_ismapped() == 0:
overlay.place(x=0,y=35)
else:
overlay.placeforget()
button = tk.Button(root,text="place/remove", command=showMenu)
button.place(x=0,y=0)
root.mainloop()
Actually it comes when I press the button but hide after I press it again.
In the same way I have another issue with these labels too.
CODE:
import tkinter as tk
root = tk.Tk()
def placeFun():
successtext = tk.Label(root, text="Success", anchor='nw', bg="#212121", fg="#ff3300",font=("Consolas", 15, "bold"))
if successtext.winfo_ismapped() == 0:
successtext.place(x=0,y=50)
else:
succestext.forget()
button = tk.Button(root, text='place/rem', width=25, command=placeFun)
button.place(x=0,y=0)
root.mainloop()
Please Note: I want a professional way to handle this, I said it because, I know a way in which we use variables like:
globalvartimes = 0
def somefunc():
if times % 2 == 0:
show the listbox
global times
times += 2
else:
remove the listbox
times += 1
*This shows the listbox when times is even and remove it when it's odd.
These makes the code look non-professional and long.
The problem is every time showMenu() is called another Listbox is created. To fix that, create the Listbox outside of the function (so it's a global).
(I also noticed you misspelled the name of place_forget() method.)
import tkinter as tk
from tkinter import *
root = tk.Tk()
root.geometry('500x500')
def showMenu():
if overlay.winfo_ismapped(): # Placed?
overlay.place_forget()
else:
overlay.place(x=0,y=35)
overlay = Listbox(root, bg="green", height=22, width=58)
button = tk.Button(root,text="place/remove", command=showMenu)
button.place(x=0,y=0)
root.mainloop()
This looks like it is what is wrong with your Label example, too.
Note: If you want to write "professional" code, I suggest you read (and start following) the
PEP 8 - Style Guide for Python Code.
Please kick here to see the current output and expected output
I have a simple python program where i want to deselect the checkbutton by default. I want to see it the same way as when a user unchecks a tick box. Please let me know how to achieve it.
from tkinter import *
from tkinter import ttk
def urgentReq():
global box
state = box.state()
if(box.instate(['selected'])):
print ("--> Urgent: ",state)
else:
print ("--> Not Urgent:",state)
gui = Tk()
gui.title("GUI")
gui.geometry('200x150')
box = ttk.Checkbutton(gui, text ='Urgent Request', command=lambda: urgentReq())
box.grid(column=1, row=4, pady=40, sticky="N")
#write something here to unselect the box by default
box.state(['!alternate']) #box appear unchecked
box.state(['selected']) #box appear checked
Use the .invoke() method, but from what I read elsewhere is will also call the command, if one is associated. The instance I was trying to use this, my check button didn't have a command as a parameter, so this worked perfectly for me.
Hope this helps and good luck!
Somehow the initial state of the CheckButton = ('alternate',).
There is a workaround I found here: tkk checkbutton appears when loaded up with black box in it. If you apply it to your code like this, it seems to work:
checkVar = IntVar()
box = ttk.Checkbutton(gui, text ='Urgent Request', command=lambda: urgentReq(), variable=checkVar)
I think you can write box.deselect() to deselect it.
Edit: Oops, I just tested it, it's not working with ttk... Sorry. :)
I'm trying to create a Tkinter app that incorporates the use of a touchscreen keyboard and will be run off a Raspberry Pi. I found an onscreen keyboard called Matchbox-keyboard.
My question is: is there a way to "embed" this keyboard into a GUI created by Tkinter? I would like to embed the keyboard so it opens at the bottom of the parent window.
So far all I can come up with is:
subprocess.Popen(['matchbox-keyboard'])
which works, but it opens in a separate window.
Below is a sample of my code. Keep in mind that I haven't coded the get() functions for the text fields yet, or any of the other functions for that matter.
from tkinter import *
from tkinter import ttk
import subprocess
process_one = subprocess.Popen(['matchbox-keyboard'])
root = Tk()
bottomframe = Frame(root)
bottomframe.pack(side = BOTTOM)
root.title("PinScore")
L0 = Label(root, text = "Welcome to PinScore!")
L0.pack(side = TOP)
L1 = Label(root, text = "Initials:")
L1.pack(side = LEFT)
E1 = Entry(root, bd = 5)
E1.pack(side = RIGHT)
L2 = Label(root, text = "High Score:")
L2.pack( side = RIGHT)
E2 = Entry(root, bd = 5)
E2.pack(side = RIGHT)
B = Button(bottomframe, text = "Enter High Score")
B.pack(side = BOTTOM)
root.mainloop()
The short answer: no, but there is hope, and it will require a fair amount of work. According to the github it is made in gtk. Then the question becomes "Can I put a gtk object in my tkinter program?". To my knowledge (and a lot of Googling) there is no way to embed gtk features in the Tkinter. You may want to try pyGTK instead, because these would be much easier to integrate (I know that it is possible). I might suggest that before you get any further in your project.
Use PyGTK! The github contains the gtk source and you can do it that way.
Actually, looking more at the github, you may not need to do that. The keyboard allows for command-line options, such as -v,--override Absolute positioning on the screen and -g,--geometry <HxW.y.x> Specify keyboard's geometry (taken from the github). You won't be able to control the z position (as in whether it is above or below your window).
If you truely want the embeded feeling, the github also says that you can embed it in gtk and points to examples/matchbox-keyboard-gtk-embed.c this might be what your looking for. You probably can translate it to pygtk. I found this, which talks about XEMBED. And I found this too which actually embeds something. Finally, I'll point you to the docs for gtk.socket.
I just started to look into tkinter to develop some simple GUI applications. However, I had a hard time figuring out how the control variables are used. I simply want to retrieve the status of a checkbutton(whether it is checked) and the text of an entry, but using the control variable seems not doing the job. I know my_entry.get() can also be used to get the text, but since most of the tutorials use control variables, I believe it is worth learning to use it correctly... Really appreciate your help!
here is the sample code I had:
import tkinter as tk
def checkbtn_callback():
print(btn_state.get())
print(entry_text.get())
top = tk.Tk()
btn_state = tk.IntVar()
checkbtn=tk.Checkbutton(top,text='testbutton',variable=btn_state,command=checkbtn_callback)
checkbtn.grid()
entry_text = tk.StringVar()
entry = tk.Entry(top, text='text entry',textvariable=entry_text)
entry.grid()
tk.mainloop()
I looked through a tutorial on using Tkinter and saw that the following code:
>>> from Tkinter import *
>>> win=Tk()
This should produce a box with the title Tk and nothing else. However, when I try this code out no such box appears. I'm not getting any errors so I suspect it's working as intended. Is it possible that there are additional steps I have to take if I'm on a mac?
from Tkinter import *
root = Tk()
w = Label(root, text="Hello, world!")
w.pack()
root.mainloop()
This code runs automatically, however, in the guide it suggests that I use $ python hello1.py to run this code, which doesn't work. Any ideas on why this might be?
However, this larger block does not work:
from Tkinter import *
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.button = Button(
frame, text="QUIT", fg="red", command=frame.quit
)
self.button.pack(side=LEFT)
self.hi_there = Button(frame, text="Hello", command=self.say_hi)
self.hi_there.pack(side=LEFT)
def say_hi(self):
print "hi there, everyone!"
root = Tk()
app = App(root)
root.mainloop()
root.destroy() # optional; see description below
The issue seems to have something to do with mainloop but I'm confused because at the same time that earlier block worked just fine with a root.mainloop() part.
Do you run this code in IDLE?
Try above code in terminal (not in IDLE), then it will work as expected.
So if you want to try and run it in Terminal you should follow the steps below
note- 'I find that running programs is Terminal that involve a tkinter Gui will often crash for me, however it may work for you'
1st - Open Terminal
2nd - Type 'python3.4' then press space bar once
3rd - Open a Finder window
4th - Go to where you saved your python file in the Finder window
5th - Once you have located the file in Finder, drag the file into the Terminal window
6th - Press enter, and enjoy your python program.
another note - 'It sounds like you need a better Python IDE, you should try out PyCharm it is a great Python IDE which you can code and run python programs in including tkinter stuff'
You can download PyCharm here https://www.jetbrains.com/pycharm/