DearPyGui: Main window always on top - python

With dearpygui, I would like to have the main window (the one that contains all the other windows) to always be on top, even if it does not have focus.
Here is what I have so far :
from dearpygui.core import *
from dearpygui.simple import *
with window('MainWindow', width=500, height=500):
add_button('Read screen')

I went with this solution for now. I'll edit my answer if it gets supported by the library. This is a feature in their roadmap for now (see this issue).
from multiprocessing import Process
from time import sleep
import win32con
import win32gui
from dearpygui.core import *
from dearpygui.simple import *
with window('MainWindow', width=500, height=500):
add_button('Read screen')
if __name__ == '__main__':
# you have to make a new process for this in order to be able
# to call win32gui.FindWindow on your displayed window
p = Process(target=start_dearpygui)
p.start()
# sleep for a while to let your window get displayed
sleep(4)
hwnd = win32gui.FindWindow('DearPyGui', None)
win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, 100, 100, 300, 200, 0)

Related

Make tkinter window always on back

I am trying to make a desktop overlay for windows.
Here is my code:
from tkinter import *
from win32gui import SetWindowPos
from win32con import *
from win32api import Sleep
from threading import Thread
class Desktop:
def Desktop(self):
self.desktoptk = Tk()
tk = self.desktoptk
tk.overrideredirect(True)
tk.geometry(f'{tk.winfo_screenwidth()}x{tk.winfo_screenheight()}+0+0')
def sendtoback():
hwnd = tk.winfo_id()
print(hwnd)
def send():
while True:
Sleep(10)
SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE)
Thread(target=send).start()
tk.after(200, sendtoback)
bg = PhotoImage(file=R'data\bg.png')
Bg = Label(image=bg)
Bg.image = bg
Bg.place(x=0, y=0)
tk.mainloop()
Desktop().Desktop()
I didn't found anything in the internet what helps me, and i haven't come up with a solution.
I need to make my window to be always on back (opposite of always on top).

How do I open multiple Tk() windows at the same time?

My problem is simple, but i really don't know what the issue is.
I'm trying to open more than one window almost at the same time, but if i do it like that:
from tkinter import *
import threading
import time
class new_window:
def build(self, killtime):
self.w = Tk()
self.w.update()
time.sleep(killtime)
self.w.destroy()
def __init__(self, killtime):
threading.Thread(target=self.build(killtime)).start()
a = new_window(2)
time.sleep(2)
b = new_window(2)
it doesn't behave like: "open, wait, open"
but instead like: "open, wait until killed, wait, open"
What i mean is that the delay starts after the first window is closed, not after the window started. I thought a Thread would help me out, but it didn't.
Hopefully one of you knows how to fix that.
You don't really need to use the threading module.
You can use the .after() method to open a new window a little after.
Here is your code:
from tkinter import *
window = Tk()
window.title("window1")
def open_new_window():
window2 = Toplevel()
window2.title("Window2")
window.after(1000, open_new_window)
window.mainloop()
Hope this helps!
Edit: The code above opens one window, then stops doing anything. If you want new windows to keep opening with a small delay in between, you can use the below code:
from tkinter import *
window = Tk()
window.title("window1")
def open_new_window():
window2 = Toplevel()
window2.title("Window2")
window.after(1000, open_new_window)
open_new_window()
window.mainloop()
Hope this helps!
I did it like this now. But i still marked the Answer of #TheMaker as the Solution, cause its more compact and easier to understand.
from tkinter import *
import threading
import time
from random import *
root = Tk()
root.configure(background='black')
root.attributes("-fullscreen", True)
class new_window:
def build(self, delay, x, y):
self.w = Tk()
self.w.title("")
self.ws = root.winfo_screenwidth() # width of the screen
self.hs = root.winfo_screenheight() # height of the screen
self.w.geometry(f"250x100+{int(round(self.ws/100*x))}+{int(round(self.hs/100*y))}")
self.w.update()
time.sleep(delay)
def __init__(self, delay, x, y):
threading.Thread(target=self.build(delay, x, y)).start()
def rdm(delay, count):
i = 1
while i<=count:
new_window(delay, randint(1, 100), randint(1, 100))
i+=1
rdm(0.02, 100)
root.mainloop()

I Want to make a startup window in python Tkinter which should not have minimize, maximize and close button [duplicate]

I have a python program which opens a new windows to display some 'about' information. This window has its own close button, and I have made it non-resizeable. However, the buttons to maximize and minimize it are still there, and I want them gone.
I am using Tkinter, wrapping all the info to display in the Tk class.
The code so far is given below. I know its not pretty, and I plan on expanding the info making it into a class, but I want to get this problem sorted before moving along.
Anyone know how I can govern which of the default buttons are shown by the windows manager?
def showAbout(self):
if self.aboutOpen==0:
self.about=Tk()
self.about.title("About "+ self.programName)
Label(self.about,text="%s: Version 1.0" % self.programName ,foreground='blue').pack()
Label(self.about,text="By Vidar").pack()
self.contact=Label(self.about,text="Contact: adress#gmail.com",font=("Helvetica", 10))
self.contact.pack()
self.closeButton=Button(self.about, text="Close", command = lambda: self.showAbout())
self.closeButton.pack()
self.about.geometry("%dx%d+%d+%d" % (175,\
95,\
self.myParent.winfo_rootx()+self.myParent.winfo_width()/2-75,\
self.myParent.winfo_rooty()+self.myParent.winfo_height()/2-35))
self.about.resizable(0,0)
self.aboutOpen=1
self.about.protocol("WM_DELETE_WINDOW", lambda: self.showAbout())
self.closeButton.focus_force()
self.contact.bind('<Leave>', self.contactMouseOver)
self.contact.bind('<Enter>', self.contactMouseOver)
self.contact.bind('<Button-1>', self.mailAuthor)
else:
self.about.destroy()
self.aboutOpen=0
def contactMouseOver(self,event):
if event.type==str(7):
self.contact.config(font=("Helvetica", 10, 'underline'))
elif event.type==str(8):
self.contact.config(font=("Helvetica", 10))
def mailAuthor(self,event):
import webbrowser
webbrowser.open('mailto:adress#gmail.com',new=1)
In general, what decorations the WM (window manager) decides to display can not be easily dictated by a toolkit like Tkinter. So let me summarize what I know plus what I found:
import Tkinter as tk
root= tk.Tk()
root.title("wm min/max")
# this removes the maximize button
root.resizable(0,0)
# # if on MS Windows, this might do the trick,
# # but I wouldn't know:
# root.attributes(toolwindow=1)
# # for no window manager decorations at all:
# root.overrideredirect(1)
# # useful for something like a splash screen
root.mainloop()
There is also the possibility that, for a Toplevel window other than the root one, you can do:
toplevel.transient(1)
and this will remove the min/max buttons, but it also depends on the window manager. From what I read, the MS Windows WM does remove them.
from tkinter import *
qw=Tk()
qw.resizable(0,0) #will disable max/min tab of window
qw.mainloop()
from tkinter import *
qw=Tk()
qw.overrideredirect(1) # will remove the top badge of window
qw.mainloop()
here are the two ways to disable maximize and minimize option in tkinter
remember the code for button shown in image is not in example as this is solution regarding how to make max/min tab nonfunctional or how to remove
Windows
For windows, you can use -toolwindow attribute like that:
root.attributes('-toolwindow', True)
So if you want complete code, it's that
from tkinter import *
from tkinter import ttk
root = Tk()
root.attributes('-toolwindow', True)
root.mainloop()
Other window.attributes attributes:
-alpha
-transparentcolor
-disabled
-fullscreen
-toolwindow
-topmost
Important note this is only working with Windows. Not MacOS
Mac
With mac you can use overredirect attribute and a "x" button to close the window and this will do the job. :D like that:
from tkinter import *
from tkinter import ttk
window = Tk()
window.overredirect(True)
Button(window, text="x", command=window.destroy).pack()
window.mainloop()
Inspired by https://www.delftstack.com/howto/python-tkinter/how-to-create-full-screen-window-in-tkinter/
For me, it's working, i have a windows 7.
Comment me if i have a error.
I merged answers from #demyaN and the others, and the following is a way to get the job done.
import ctypes as ct
from tkinter import *
def setWinStyle(root):
set_window_pos = ct.windll.user32.SetWindowPos
set_window_long = ct.windll.user32.SetWindowLongPtrW
get_window_long = ct.windll.user32.GetWindowLongPtrW
get_parent = ct.windll.user32.GetParent
# Identifiers
gwl_style = -16
ws_minimizebox = 131072
ws_maximizebox = 65536
swp_nozorder = 4
swp_nomove = 2
swp_nosize = 1
swp_framechanged = 32
hwnd = get_parent(root.winfo_id())
old_style = get_window_long(hwnd, gwl_style) # Get the style
new_style = old_style & ~ ws_maximizebox & ~ ws_minimizebox # New style, without max/min buttons
set_window_long(hwnd, gwl_style, new_style) # Apply the new style
set_window_pos(hwnd, 0, 0, 0, 0, 0, swp_nomove | swp_nosize | swp_nozorder | swp_framechanged) # Updates
window = Tk()
Button(window, text="button").pack() # add your widgets here.
window.after(10, lambda: setWinStyle(window)) #call to change style after the mainloop started. Directly call setWinStyle will not work.
window.mainloop()
By the way, using window.attributes('-toolwindow', True) will remove the minimize and maximize boxes, but it will make the app not display in the taskbar, which is a problem for me.
Removing minimize/maximize buttons using ctypes
import ctypes as ct
set_window_pos = ct.windll.user32.SetWindowPos
set_window_long = ct.windll.user32.SetWindowLongPtrW
get_window_long = ct.windll.user32.GetWindowLongPtrW
get_parent = ct.windll.user32.GetParent
# Identifiers
gwl_style = -16
ws_minimizebox = 131072
ws_maximizebox = 65536
swp_nozorder = 4
swp_nomove = 2
swp_nosize = 1
swp_framechanged = 32
hwnd = get_parent(settings_panel.winfo_id())
# Get the style
old_style = get_window_long(hwnd, gwl_style)
# New style, without max/min buttons
new_style = old_style & ~ ws_maximizebox & ~ ws_minimizebox
# Apply the new style
set_window_long(hwnd, gwl_style, new_style)
# Updates
set_window_pos(hwnd, 0, 0, 0, 0, 0, swp_nomove | swp_nosize | swp_nozorder | swp_framechanged)

Tkinter with another infinite loop ( For speech to text conversion)

Tkinter GUI don't shows up when running in parallel with another infinity loop;i have tried Threading and multiprocessing techniques, whereas used GUI in main code and calling livespeech code or vice versa ; and defining both codes in function and calling from the main thread.But the problem remains; different result are attached below although u find it comment but have tried that method too,
#*********************************** IMPORTING MODULES*****************
import tkinter
from tkinter import*
import tkinter.messagebox
import sqlite3
import os
from multiprocessing import Process
from pocketsphinx import LiveSpeech, get_model_path
import threading
from time import sleep
model_path = get_model_path()
#*************** TKINTER GUI CODE******************
def gui():
window = tkinter.Tk()
window.title("Smart Notice Board")
top = Canvas(window,width=400,height=200)
top.pack(fill=X)
button_5 = Button(text='PORTAL SYSTEM', height = 2, width=17, activebackground = '#33B5e5', bg = 'brown', fg = 'white',command = portal )
top.create_window(80,80, anchor='nw', window = button_5)
def portal():
print("2")
#**************** speech TO text CODE***************
def speech():
speech = LiveSpeech(
verbose=False,
sampling_rate=16000,
buffer_size=2048,
no_search=False,
full_utt=False,
hmm=os.path.join(model_path, 'en-us'),
lm=os.path.join(model_path, '8582.lm'),
dic=os.path.join(model_path, '8582.dict')
)
for phrase in speech:
print(phrase)
a=str(phrase)
print(a)
#************************** MAIN LOOP************************
if __name__ == "__main__":
#************ FOR THREADING************
#thread1 = threading.Thread(target=gui)
#thread2 = threading.Thread(target=speech)
#thread1.daemon = True
#thread1.start()
#thread2.start()
#thread1.join()
#thread2.join()
#************ FOR MULTIPROCESSING****************
#processes=[]
#P1 = Process(target=gui)
#P2 = Process(target=speech)
#processes.append(P1)
#processes.append(P2)
#P2.daemon = True
# Will execute both in parallel
#P1.start()
#P2.start()
# Joins threads back to the parent process, which is this
# program
#P1.join()
#P2.join()
#****************** live speech code*************
window = tkinter.Tk()
window.title("Smart Notice Board")
top = Canvas(window,width=400,height=200)
top.pack(fill=X)
button_5 = Button(text='PORTAL SYSTEM', height = 2, width=17, activebackground = '#33B5e5', bg = 'brown', fg = 'white',command = portal )
top.create_window(80,80, anchor='nw', window = button_5)
IN multiprocessing case; no error but nothing works
This is the code I use to get mouse move event's cursor position from queue and act accordingly:
def check_mouse(self):
while True:
item = self.mouse.get_item()
if item is None:
break
else:
self.master.after_idle(self.mouse_move, *item)
self.master.after(INTERVAL, self.check_mouse)
and it's first time called just before mainloop call, with yet another self.master.after(INTERVAL, self.check_mouse).
So make you Tkinter GUI do its work in the mainloop and you should create another loop with a task that will run after INTERVAL (in miliseconds) and it will call itself every INTERVAL period after its job is finished.

Can't move image with time delay

I'm trying to figure out how to make a scrolling image in python, but I got into some issues with delay. I need the image to move after the canvas has rendered, and I also need it to move with a time delay. Here is my current code:
from Tkinter import *
import ImageTk
import time
def scrollToTop(imaget):
for x in range(100, 20, -1):
canvas.move(imaget, 0, -1)
t = Tk()
canvas = Canvas(t,height=256,width=256)
canvas.pack()
arrows = [1]
arrows[0] = ImageTk.PhotoImage(file="arrow.bmp")
image = canvas.create_image(20,100,image=arrows[0],tags="token")
t.mainloop();
scrollToTop(image);
I tried playing around where the scrollToTop() function was, and I also tried time.delay(0.1), all to no avail. I could try something like an Update() function, that measures the time passed from a "game time" variable...
Thanks in advance!
First: main loop t.mainloop() run till you close program so every instruction after t.mainloop() will be run after you close program.
You can use timer to call scrollToTop (for example) every 1 second (1000 millisecond)
from Tkinter import *
import ImageTk
import time
def scrollToTop():
print "I'm in scrollToTop()"
canvas.move(image, 0, -1)
t.after(1000, scrollToTop)
t = Tk()
canvas = Canvas(t,height=256,width=256)
canvas.pack()
arrows = [1]
arrows[0] = ImageTk.PhotoImage(file="arrow.bmp")
image = canvas.create_image(20,100,image=arrows[0],tags="token")
scrollToTop()
t.mainloop();
EDIT:
t.after() require function name without () so if you need to run functiion with arguments use lambda function
from Tkinter import *
import ImageTk
import time
def scrollToTop(imaget):
print "I'm in scrollToTop()"
canvas.move(imaget, 0, -1)
t.after(1000, lambda:scrollToTop(imaget))
t = Tk()
canvas = Canvas(t,height=256,width=256)
canvas.pack()
arrows = [1]
arrows[0] = ImageTk.PhotoImage(file="arrow.bmp")
image = canvas.create_image(20,100,image=arrows[0],tags="token")
scrollToTop(image)
t.mainloop();

Categories

Resources