tkinter only displays top of label text - python-3.x

I am making an alarm clock radio using python3, tkinter on a raspberry pi 3 using a 2.8in PiTFT. And I am using a true type font called digital-7. When I create a tkinter Label to hold the time, then only the top 3/4s of the text is displayed. If I add a "\n", then the full text displays. I've done a lot of searching but haven't been able to find a solution. Any help would be appreciated.
Here is a snippet of the code:
import datetime
import tkinter as tk
root = tk.Tk()
root.configure(background='black')
# make root use full screen
root.overrideredirect(True)
root.geometry("{0}x{1}+0+0".format(root.winfo_screenwidth(), root.winfo_screenheight()))
# using 2.8 PiTFT with 320x240 display
timeText = tk.StringVar()
# digital-7 is a true type font, which shows clock in 7 segment display
timeLabel = tk.Label(root, font=('digital-7', 120), fg='red', bg='black', textvariable=timeText, anchor='n')
timeLabel.grid(row=0, columnspan=6)
def updateDate():
global timeText
dt = datetime.datetime.now()
# without the '\n' the bottom part of the time gets cropped
tts = dt.strftime('%H:%M')
timeText.set(tts+'\n')
root.after(2000, updateDate)
updateDate()
root.mainloop()
The full code is here (it is still a work in progress):
https://raw.githubusercontent.com/dumbo25/tkinter-alarm-clock-radio-gui/master/acr.py
digital-7 goes in /home/pi/.fonts and here is where I got digital 7 from:
https://github.com/dec/angular-canvas-gauge/blob/master/Sample/fonts/digital-7-mono.ttf

Related

How to take screenshot by ignoring the main window in tkinter? [duplicate]

I am trying to create a translucent window in Tkinter like the one in windows 11
How to do this? If we cannot do this can we capture a part of a screen and blur it using cv2 and use it as a continuously updating background?
No, this is not directly possible with tkinter. But:
If you use PIL, you can get the location of the window, and then take a screenshot, then blur it and then make it your app background. But this wont work if user tries to move/resize the application. But here is a rough code:
from tkinter import *
from PIL import ImageTk, ImageGrab, ImageFilter # pip install Pillow
root = Tk()
root.overrideredirect(1) # Hide the titlebar etc..
bg = Canvas(root)
bg.pack(fill='both',expand=1)
root.update()
# Get required size and then add pixels to remove title bar and window shadow
left = root.winfo_rootx()
top = root.winfo_rooty()
right = left + root.winfo_width()
bottom = top + root.winfo_height()
root.withdraw() # Hide the window
img = ImageGrab.grab((left,top,right,bottom)) # Get the bg image
root.deiconify() # Show the window
img = img.filter(ImageFilter.GaussianBlur(radius=5)) # Blur it
img = ImageTk.PhotoImage(img)
bg.create_image(0,0, image=img, anchor='nw') # Show in canvas
label = Label(root,text='This is a translucent looking app')
bg.create_window(bg.winfo_width()/2,bg.winfo_height()/2,window=label) # Position in the center
root.mainloop()
Output with tkinter:
tkinter is not the best choice if you are trying to go for a modern look, use PyQt and check qtacrylic
Output with PyQt:
For live blur (native Windows blur) use "BlurWindow":
python -m pip install BlurWindow
from tkinter import *
from ctypes import windll
from BlurWindow.blurWindow import blur
root = Tk()
root.config(bg='green')
root.wm_attributes("-transparent", 'green')
root.geometry('500x400')
root.update()
hWnd = windll.user32.GetForegroundWindow()
blur(hWnd)
def color(hex):
hWnd = windll.user32.GetForegroundWindow()
blur(hWnd,hexColor=hex)
e = Entry(width=9)
e.insert(0,'#12121240')
e.pack()
b = Button(text='Apply',command=lambda:[color(e.get())])
b.pack()
root.mainloop()

Display serial incoming data on tkinter scrollbar

I downloaded a small arduino program in order for it to produce serial data.
My goal (first iteration) is to create an application that will replace the arduino IDE serial - since i only want to read serial data.
This is how the data looks like on the arduino IDE serial interface.
This is my code so far:
import tkinter as tk
import tkinter.ttk as ttk
import serial.tools.list_ports
from tkinter import scrolledtext
#new stuff
import time
import serial
import threading
import continuous_threading
#to be used on our canvas
HEIGHT = 700
WIDTH = 800
#hardcoded baud rate
baudRate = 9600
#Serial Stuff-----------------------------------------
ser = serial.Serial('COM16', baudRate)
val1 = 0
index = []
def readSerial():
global val1
ser_bytes = ser.readline()
ser_bytes = ser_bytes.decode("utf-8")
val1 = ser_bytes
index.append(val1)
disp = tk.Label(frame2, text=index[0])
disp.config(font=("TkDefaultFont", 8))
disp.place(relx = 0.1, rely=0.3, relwidth=0.3, relheight=0.5)
t1 = continuous_threading.PeriodicThread(0.5, readSerial)
# --- main ---
root = tk.Tk() #here we create our tkinter window
root.title("Sensor Interface")
#we use canvas as a placeholder, to get our initial screen size (we have defined HEIGHT and WIDTH)
canvas = tk.Canvas(root, height=HEIGHT, width=WIDTH)
canvas.pack()
# --- frame 2 ---
frame2 = tk.Frame(root, bg='#80c1ff') #remove color later
frame2.place(relx=0, rely=0.1, relheight=1, relwidth=1, anchor='nw')
# make a scrollbar
scrollbar = scrolledtext.ScrolledText(frame2)
scrollbar.place(relx=0, rely=0, relheight=1, relwidth=1, anchor='nw')
# --- frame 2 ---
t1.start()
root.mainloop() #here we run our app
I have a frame2 which is a scrollText that i want my data to appear (i also have another frame above it, that i removed it here so that i don't confuse people with unnecessary code).
Ideally i would like the data to appear like in the arduino IDE, with autoscroll - but first i have to walk before i can run.
All the serial "action" happens in the portion i have marked with comments called 'Serial stuff'.
Is my placement code correct?
disp = tk.Label(frame2, text=index[0])
disp.config(font=("TkDefaultFont", 8))
disp.place(relx = 0.1, rely=0.3, relwidth=0.3, relheight=0.5)
I want each line to be placed in a new line in the textbox, like my first picture
EDIT: I followed scotty3685's advice (Thanks a lot sir!) but look at what i get now at my tkinter frame:
If you compare with the first picture, it's close but it's not really there.
The way to insert text into a ScrolledText widget is as follows
s.insert("end","some_text that I want to insert")
s is the name of the scrolledtext widget (in your case this is
called scrollbar confusingly)
The first argument to insert "end"
tells the scrolled text widget to place the new text at the end of
the current text in the textbox.
and the second argument to insert is
the text you want to insert (in your case, val1).

Tkinter Widget Size Issues

EDIT: I found the solution! My xorg settings were all wacky because I have an ultrawide monitor, and it had no idea what size (and therefore dpi) my monitor was. Explicitly setting the display and font dpi in X's settings fixed the rendering in all GUI's.
ORIGINAL:
When I run any tkinter program, many of the widgets render at around 1/2 size, especially text. Why is this happening? My window manager is Window Maker, and I'm running the latest version of Tcl/Tk.
Any help will be greatly appreciated!
My code:
import tkinter as tk
window = tk.Tk()
label = tk.Label(text="Name")
entry = tk.Entry()
button = tk.Button(text="Submit")
label.pack()
entry.pack()
button.pack()
window.mainloop()
Window manager: Window Maker 0.95.0
Tk: tk 8.6.10-2
Screenshot:
In tkinter you can only change the size of a label with the font atribute, and same goes for the text inside the button. The button size can be changed with the width and height atribute.
from tkinter import *
window = Tk()
label = Label(text="Name", font='Helvetica 15')
entry = Entry()
button = Button(text="Submit",font ='Helvetica 15', height="3", width="10")
label.pack(pady = 5) # add pady inside the pack
entry.pack()
button.pack(pady = 5)
window.mainloop()

How to show image without title bar and border in opencv python

Show image like its shows in full screen but in small size. from backend we select the image size and we have to show this image without any title bar and border. only image will appear. i try lot of methods, but didn't get success. is there any way to do this ? if any body knows, please help, i stuck in this from many days
Operating System: Raspberry PI
Language Using: Python 3
With the help of tkinter window/frame, we can show image or video without any border and title bar. what we have to do is, make tkinter window transparent.
I am putting my code below, which shows webcam video without borders and title bar in any size.
import numpy as np
import cv2
from tkinter import *
#import tkinter as tk
from PIL import Image, ImageTk
import sys
window = Tk() #Makes main window
window.overrideredirect(True)
window.wm_attributes("-topmost", True)
window.geometry("+600+200")
display1 = Label(window)
display1.grid(row=1, column=0, padx=0, pady=0) #Display 1
cap = cv2.VideoCapture(0)
def show_frame():
_, frame = cap.read()
frame = cv2.resize(frame, (400,400))
#frame = cv2.flip(frame, 1)
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(master = display1, image=img)
display1.imgtk = imgtk #Shows frame for display 1
display1.configure(image=imgtk)
window.after(10, show_frame)
show_frame()
window.mainloop()
frame = cv2.resize(frame, (400,400)) this is use to resize our frame.
Windows where images are displayed in OpenCV are implemented in HighGUI module using either OpenGL or Qt. You can modify a bit what will be shown to the user (depends on system also), but i think what you're trying to achive is not possible in OpenCV.
Here is list of all flags you can use while creating new window/widget in OpenCV.
Unfortunately there is no flag to hide title bar like it is in full-screen mode. Why? It's not important to OpenCV users. They are using imshow just to see the results, mainly for debugging purposes, so they don't need to remove title-bars.
What you can do? Link your program with Qt framework and display image using Qt directly, not throught the wrapper. This might be helpful.

Bold text on tkinter canvas

How? I've tried several variations of
self.textindex = self.canvastext.create_text(0,696,font=('freemono bold',9), anchor='nw', fill='black', text='Longitude: ' + str(px))
or
self.textindex = self.canvastext.create_text(0,696,font=('bold', 'freemono bold',9), anchor='nw', fill='black', text='Longitude: ' + str(px))
etc, to either have the font type revert back to the default font or to give me errors.
I actually want some type of font that is block style font, every character has the same width, so I can setup up nice column style formatting on parts of the screen. I don't see on any programs I run, Times Roman(I think that is the right name) pop up so I'm guessing Linux Mint doesn't come standard with it:)..hence using freemono. I would stick with the default font, which is already bold, trying to format it on the screen is a lot more difficult though and I'm in kinda for the looks given how nicely this program is turning out right now.
The best way is to create a font object. For example:
# python2
import Tkinter as tk
import tkFont as tkfont
# python3
# import tkinter as tk
# from tkinter import font as tkfont
root = tk.Tk()
canvas = tk.Canvas(root, width=400, height=400, background="bisque")
canvas.pack(fill="both", expand=True)
normal_font = tkfont.Font(family="Helvetica", size=12)
bold_font = tkfont.Font(family="Helvetica", size=12, weight="bold")
canvas.create_text(50,50, text="This is normal", font=normal_font)
canvas.create_text(50,100, text="This is bold", font=bold_font)
root.mainloop()
this worked for me (Python 3):
canvas.create_text(x, y, font=('freemono', 11, 'bold'), anchor='sw', text=s)
And in addition to Bryan's answer: if you're using tkinter (as opposed to Tkinter) your code is:
from tkinter import font
...
myfont = font.Font(family='freemono', size=11, weight="bold")
canvas.create_text(x, y, font=myfont, anchor='sw', text=s)
instead of changing the weight of the letters, you could change the font of the letters by saying (font="Ariel") but with the font that is thick enough for you. Hope this helped :)

Resources