How can I align scrolled text to the right? - python

The problem is simple. The scrolled text box will be written into it in Arabic.
So I need to align the text whenever I type to the right of the box. There isn't any attribute, such as justify. Also I used a tag, but I couldn't do it.
show_note = scrolledtext.ScrolledText(canvas, width=int(monitorWidth / 65), height=int(monitorHeight / 130),
font=("Times New Roman", 14))
canvas.create_window(cord(0.45, 0.65), window=show_note, anchor="ne")
Is there an alternative to the scrolled text control, but that has these attributes (width, height, justify and can write into multiple lines)?

I did some searching and could not find any other way to do this, than to bind each keypress to a function, that adds/edits the tag to select all the item from the text box:
from tkinter import *
from tkinter import scrolledtext
root = Tk()
def tag(e):
text.tag_add('center','1.0','end')
text = scrolledtext.ScrolledText(root)
text.pack()
text.tag_config('center',justify='right')
text.bind('<KeyRelease>',tag)
root.mainloop()
You can also make your custom widget that does this, instead of repeating code for each file, so a more better form would be:
from tkinter import *
from tkinter import scrolledtext
root = Tk()
class JustifyText(scrolledtext.ScrolledText):
def __init__(self,master,*args,**kwargs):
scrolledtext.ScrolledText.__init__(self,master,*args,**kwargs)
self.tag_config('center',justify='right')
self.bind('<KeyRelease>',self.tag)
def tag(self,e):
text.tag_add('center','1.0','end')
text = JustifyText(root)
text.pack()
root.mainloop()
And yes you can make this more perfect by taking the current width of text box and shifting the insertion cursor to that point, to make it start from that point.

Related

centering a text within a button in tk

usually buttons in tkinter center their texts automatically but i can't seem to get it i don't know why!
from tkinter import *
from tkinter import messagebox
from PIL import Image,ImageTk
from getpass import getpass
huh=Tk()
huh.title('Login page')
huh.configure(bg='white')
huh.resizable(False,700)
huh.geometry('925x500+300+200')
my_fr=Frame(huh,width=350,height=350,bg='white')
my_fr.place(x=480,y=90)
btn=Button(my_fr,width=50,border=0,text="Connexion",bg='#000000',fg="#ffffff",font='Railway',anchor=CENTER)
btn.place(x=43,y=300)
huh.mainloop()
Here is a solution using grid() that positions the button, with text centered, at the x, y coordinates used with the original place() statement.
Note that resizeable() takes only boolean parameters, so '700' would be interpreted as True. Assuming that a maximum window height of 700 with a minimum height of 500 was the intention, resizeable() was replaced with minsize() and maxsize() statements.
The geometry() statement was retained, but if the system's default window position is suitable, then it can be removed.
Replacing my_fr.grid() with my_fr.pack() would horizontally center the button, thus ignoring the padx specification.
import tkinter as tk
huh = tk.Tk()
huh.title('Login page')
huh.configure(bg='white')
huh.geometry('925x500+300+200')
huh.minsize(925, 500)
huh.maxsize(925, 700)
my_fr = tk.Frame(huh, bg='white')
btn = tk.Button(my_fr, width=50, text="Connexion",
bg='black', fg="white", font='Railway')
my_fr.grid()
btn.grid(padx=43, pady=300)
huh.mainloop()

How to drag text which is printed over Image (in canvas) using mouse in python?

I want to add a Drag Text Feature in canvas to change the position of text using mouse.
from PIL import Image,ImageFont,ImageDraw,ImageTk
import tkinter as tk
root = tk.Tk()
root.title('Demo')
root.geometry('400x50')
def func_image():
img_window = tk.Toplevel()
img_window.grab_set()
photo = Image.open(r'E:\side_300.png')
wi,hi = photo.size
fonty = ImageFont.truetype('arial.ttf',18)
draw = ImageDraw.Draw(photo)
draw.text((50,50),text=text.get(),fill='red',font=fonty)
new_photo = photo
can_photo = ImageTk.PhotoImage(new_photo)
canvas = tk.Canvas(img_window,height=500,width=500)
canvas.pack(anchor='n')
canvas.create_image(wi/2,hi/2,image=can_photo,anchor='center')
img_window.mainloop()
lbl_text = tk.Label(root,text='Enter Text :')
lbl_text.grid(row=0,column=0)
text = tk.Entry()
text.grid(row=0,column=1)
btn = tk.Button(root,text='Click Me',command=func_image)
btn.grid(row=0,column=2)
root.mainloop()
When you run the code it will firstly open a window with name 'Demo' which contains one entry box and a button.
When you click on a Button 'Click Me' after entering some text into entry box it will go to a function func_image and opens a new window which contain a canvas filled with new_image.
Quick Disclaimer: I don't have a lot of experience with PIL, so i don't know how to remove text that has already been drawn. Maybe you can figure that one out yourself. But apart from that, i know some things about tkinter. My idea would be the following:
Bind a function to the <B1-motion> event (Button 1 is being held down and moved) that will constantly get the position of the mouse inside the window and draw new text at that position, while deleting the previous text.
import...
...
def func_image():
img_window = tk.Toplevel()
...
...
draw = ImageDraw.Draw(photo)
draw.text((50,50),text=text.get(),fill='red',font=fonty)
...
def move_text(event):
# here you would delete your previous text
x = event.x
y = event.y
draw.text((x,y),text=text.get(),fill='red',font=fonty
img_window.bind('<B1-Motion>', move_text)
That being said, i think it would be a better idea to use Canvas.create_text (more on effbot.org) in order to write your text on the image. It's really easy to drag around text on a Canvas, here's a little example:
import tkinter as tk
root = tk.Tk()
def change_position(event):
x = event.x
y = event.y
# 20x20 square around mouse to make sure text only gets targeted if the mouse is near it
if text in c.find_overlapping(str(x-10), str(y-10), str(x+10), str(y+10)):
c.coords(text, x, y) # move text to mouse position
c = tk.Canvas(root)
c.pack(anchor='n')
text = c.create_text('10', '10', text='test', fill='red', font=('arial', 18)) # you can define all kinds of text options here
c.bind("<B1-Motion>", change_position)
root.mainloop()

Showing text in tkinter´s canvas repeatedly

I´m trying to use tkinter in order to show a popup window in front of all other windows that reminds me of something through a text displayed in the canvas. I want that the window pops up during some time, eg 5 seconds, and then dissapear for other time. I need this to repeat in a loop. When i tried to do it, a window appear but without the text and the specified dimensions. Here is the code:
from tkinter import *
from time import sleep as s
for i in range(5):
root = Tk()
root.lift()
root.attributes('-topmost',True)
canvas = Canvas(root,width=700,height=100)
canvas.pack()
canvas.create_text(350,50,text='Registrar rabia'+str(i),font=
('fixedsys','25'))
print('Hola')
s(1)
root.destroy()
s(1)
Also, is there a more pythonic way to do it?
EDIT:
from tkinter import *
root = Tk()
for _ in range(6):
#root.deiconify()
root.attributes('-topmost',True)
root.title("About this application...")
about_message = 'Este es el mensaje'
msg = Message(root, text=about_message)
msg.pack()
button = Button(root, text="Dismiss", command=root.withdraw)
button.pack()
root.after(1000)
It didn´t work. I need only one message and one button, and in the code above,
python shows 6 messages and 6 buttons... Also i need to put a delay between appearances but i can´t understand how to use the after method in this particular case.

tkinter grid manager behaviour

So i want to build an assistant off sorts which will do auto backs ups etc and instead of using .place i would like a proper grid to place widgets.
I cannot find a good example of the grid manager.
self.parent = tk.Frame(window, bg = BLACK)
username_label = ttk.Label(self.parent, text = "Username")
password_label = ttk.Label(self.parent, text = "Password")
self.parent.grid(column = 0, row = 0)
username_label.grid(column = 1, row = 1)
password_label.grid(column = 2, row = 2)
self.parent.grid_columnconfigure(0, weight = 1)
I want...
Button
Button
Label Entry Button
Label Entry Button
Button
I don't understand how i can position them like this as i want a blank space above the labels. so far grid has only let me place things next to each other.
Honestly, any websites or code examples would be greatly appreciated
So, if you want blank space above the label, you can either set pady as an argument to the grid method or simply put them in the corresponding row. Consider the following example:
import tkinter as tk
root=tk.Tk()
for i in range(6):
tk.Button(root,text='Button %d'%i).grid(row=i,column=1)
tk.Label(root,text='Label 0').grid(row=2,column=0,pady=20)
tk.Label(root,text='Label 1').grid(row=3,column=0)
root.mainloop()
Notice the effect of the pady argument. Also, if you only want a blank line above the Label, you can try to put a blank Label in the row above. E.g.:
import tkinter as tk
root=tk.Tk()
for i in range(6):
tk.Button(root,text='Button %d'%i).grid(row=i,column=1)
tk.Label(root,text='Label 0').grid(row=2,column=0,pady=20)
tk.Label(root,text='Label 1').grid(row=3,column=0)
tk.Label(root,text='').grid(row=6)
tk.Label(root,text='This is a Label with a blank row above').grid(row=7,columnspan=2)
root.mainloop()
You can refer to effbot for more information, which is the blog of tkinter's developer.

Inserting a button into a tkinter listbox on python?

...
self.myListbox=tkinter.Listbox()
self.myListbox.pack()
self.myButton=tkinter.Button(self.myListbox,text="Press")
self.myListbox.insert(1,myButton.pack())
...
I want to insert a button into listbox like inserting a sting. How can I do this?
You can't. From the listbox documentation: "A listbox is a widget that displays a list of strings".
You can, of course, use pack, place or grid to put a button inside the widget but it won't be part of the listbox data -- it won't scroll for example, and might obscure some of the data.
An alternative to a ListBox is a scrollable frame;
import functools
try:
from tkinter import *
import tkinter as tk
except ImportError:
from Tkinter import *
import Tkinter as tk#
window = Tk()
frame_container=Frame(window)
canvas_container=Canvas(frame_container, height=100)
frame2=Frame(canvas_container)
myscrollbar=Scrollbar(frame_container,orient="vertical",command=canvas_container.yview) # will be visible if the frame2 is to to big for the canvas
canvas_container.create_window((0,0),window=frame2,anchor='nw')
def func(name):
print (name)
mylist = ['item1','item2','item3','item4','item5','item6','item7','item8','item9']
for item in mylist:
button = Button(frame2,text=item,command=functools.partial(func,item))
button.pack()
frame2.update() # update frame2 height so it's no longer 0 ( height is 0 when it has just been created )
canvas_container.configure(yscrollcommand=myscrollbar.set, scrollregion="0 0 0 %s" % frame2.winfo_height()) # the scrollregion mustbe the size of the frame inside it,
#in this case "x=0 y=0 width=0 height=frame2height"
#width 0 because we only scroll verticaly so don't mind about the width.
canvas_container.pack(side=LEFT)
myscrollbar.pack(side=RIGHT, fill = Y)
frame_container.pack()
window.mainloop()

Categories

Resources