Program Info & Problem
I have created a Python Program Using Pygame Module which displays the Ads on the monitor.
It shows The Ad on screen But as soon as I launch different applications like kodi or vlc or chrome, etc. It goes behind those applications.
The Problem is: The program runs but behind those applications if these applications are launched after my Ad Program.
Ideal Working
Program Laucnhed
Ad Displayed on screen
Launched Other Application
The Program still displayes the ad on top of screen.
System Info
OS: Linux - Ubuntu 20
Language: Python
Module: Pygame, Pymovie, GTK3+
Architecture: amd64
Desktop Enviroment: OpenBOX
Code Launch: CLI using a bash script which launches the python program of advertisment.
Sample Screenshot of Advertiesment
Please Help!
Thank you.
Looks like the best answer I can find is from this outdated website (https://www.mail-archive.com/pygtk#daa.com.au/msg01370.html)
they say to use code below, it should work on all OSs...things are never that easy
transient.set_transient_for(main_window)
Alternatively I have four other answers lol
Taken from (How to keep a python window on top of all others (python 3.1))
stackoverflow user pyfunc says for windows you can just do
import win32gui
import win32con
win32gui.SetWindowPos(hWnd, win32con.HWND_TOPMOST, 0,0,0,0,
win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)
Since this only works for windows I think you should try python-tinker, I believe it works on linux
root = Tk()
root.wm_attributes("-topmost", 1)
Also whatnick says you can use PyGTK
gtk.Window.set_keep_above
reference: How to make python window run as "Always On Top"?
Let me know if any of these work for you, I will keep looking for a better answer.
I think PyWinCtl can make the trick in most cases. You can invoke alwaysOnTop() once for your window, or you can call it inside your loop to assure it stays on top after other apps open. Check this:
import tkinter as tk
import pywinctl as pwc
class Window(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.overrideredirect(True)
self.geometry('300x200')
self.config(background='black')
self.attributes('-alpha', 0.5)
self.label = tk.Label(text="Hello World!")
self.label.pack(fill=tk.BOTH, expand=1)
self.wait_visibility()
self.window = pwc.Window(int(self.frame(), base=16))
# Call it once at the beginning of your program...
try:
self.window.alwaysOnTop()
except:
pass
self.counter = 0
self.display()
def display(self):
if self.state() == "normal":
try:
# ... or call it repeatedly to assure it stays on top
self.window.alwaysOnTop()
except:
# On Linux, sometimes it takes more time to recognize the new window
self.window = pwc.Window(int(self.frame(), base=16))
self.label.config(text=str(self.counter))
self.counter += 1
self.after(1000, self.display)
root = Window()
root.mainloop()
Related
i'm working on a little python script, and having trouble with the tkinter destroy() function and macos. my window is set up like this:
class TextBox():
def __init__(self):
self.root = tk.Tk()
text_box = tk.Text(self.root, ...)
def quit_window(self):
self.root.destroy()
calling self.quit_window() from within the class works as expected, but creating an instance of TextBox() and calling the quit function like this:
box = TextBox()
box.quit_window()
makes the window unresponsive with the mac loading wheel spinning when focused. am i making a weird mistake? i've seen threads about some versions of tkinter having trouble with macos, but using different python installs had no effect. thanks!
I am creating a little time management tool, using Tkinter, so I can keep on task at work. I am having trouble with one aspect that I cannot seem to get working. I'm using the error box so that it is displayed in front of all other windows.
As it is now, the program starts a new thread on a function that keeps track of time, and compares it to the time the user entered for their task. Once real time > the time entered by the user, it starts another thread to spawn the tkMessageBox. I have tried this without starting a new thread to spawn the tkMessageBox, and the problem is the same. If the user enters the same time for 2 separate tasks, the error pop up freezes. I'm having trouble finding information on this topic specifically... The behaviour is odd because if I have 2 alerts, lets say 1 at 0600 and one at 0601, but I do not close the first error box that pops up and let it stay up until the second alert triggers, the second alert will just replace the first one(I would like multiple error boxes to pop up if possible). It's only the alerts that have the same trigger time that cause the pop up to freeze though.
This is my first GUI program and only started learning the concept of threading, and GUIs in the past 24 hours, so I'm not sure if this is a problem with threading or the tkMessageBox. Because of the behaviour of the error box, I’m thinking it is the thread module combined with the tkMessageBox module. The command I'm using is:
tkMessageBox.showerror('TIMER ALERT!!!', comp_msg)
Here is the source I put comments in there to help. The tkMessageBox I’m talking about is line 56.
I guess I'm not sure if I can even do what I am trying to do with the pop-up box, if I can, I'm not sure how. If I can't, is there a alternative way to spawn multiple error type pop-up boxes with Tkinter? I just want multiple boxes to be able to appear at any given time.
Thanks in advance, and I really appreciate any help at all.
EDIT:
import thread
from Tkinter import *
#Spawns Error Box. Runs in it's own thread.
def message_box(comp_msg,q): # q is an empty string because of thread module.
print "Spawning Error Box..."
eb =Toplevel()
eb.config(master=None,bg="red")
pop_l = Label(eb,text="ALERT!!!")
pop_l2=Label(eb,text=comp_msg)
pop_l.pack(pady=10,padx=10)
pop_l2.pack(pady=15,padx=10)
return eb
thread.start_new_thread(message_box,(comp_msg,""))
tkmessageBox default dialog boxes are modal. You could implement a simple none modal dialog box for this application. Here is a good document about creating custom dialog boxes.
This way you can create as many new custom dialog boxes as your app requires, since each one is just a new Toplevel.
Here is a simple Tkinter app that shows the clock on the main window. When you click on the button it starts new tkMessageBox dialog boxes in new threads. (If you run it) You could see that the main thread that runs the TK event loop is working (since the time is getting updated), but the error boxes are not showing up as expected.
#!/usr/bin/env python
import datetime
import threading
from Tkinter import *
import tkMessageBox
class MyApp(Frame):
def __init__(self, root=None):
if not root:
root = Tk()
self.time_var = StringVar()
self.time_var.set('starting timer ...')
self.root = root
Frame.__init__(self, root)
self.init_widgets()
self.update_time()
def init_widgets(self):
self.label = Label(self.root, textvariable=self.time_var)
self.label.pack()
self.btn = Button(self.root, text='show error', command=self.spawn_errors)
self.btn.pack()
def update_time(self):
self.time_var.set( str(datetime.datetime.now()) )
self.root.after(1000, self.update_time)
def spawn_errors(self):
for i in range(3):
t = threading.Thread(target=self.show_error)
t.start()
def show_error(self):
now = datetime.datetime.now()
tkMessageBox.showerror('Error: %s' % (str(now)), now)
if __name__ == '__main__':
app = MyApp()
app.mainloop()
I wrote program in wxPython and VPython, but I have huge problem: Module VPython not always run. If I run program in Interpreter, program run more often , than after compilation. Code never returns any errors. I try on the other computers, program is the same.
Win7
Python 2.7.5 32bit
wxPython 2.9.4
VPython 6.0.5
import visual as v
import wx
class Maintest(v.window):
def InitUI(self):
fileMenu = wx.Menu()
self.menubar.Append(fileMenu, '&Plik')
self.menubar.Remove(0)
def asd(self, scene):
v.box()
def main():
w = Maintest(menus=True, title="program", x=100, y=100, width=1024, height=600)
w.InitUI()
scene = v.display(window=w, x=0, y=0, width=600, height=600, up=(0,0,1), background=(1,1,1), foreground = (0,1,0), forward=(-1,-1,-1))
w.asd(scene)
while True:
v.rate(60)
if __name__ == '__main__':
main()
All is OK: http://imageshack.us/photo/my-images/199/tpp.png/
Not OK: http://imageshack.us/photo/my-images/689/akun.png/
It is only the part of main program, but problem is the same.
What is wrong? What I should to do?
I will be gratefull for answer.
With Win7 Python 2.7.5 64bit wxPython 2.9.4 VPython 6.0.5 I cannot get the program to fail. The fact that the problem is not entirely reproducible (and is entirely nonreproducible by me) suggests the possibility that the graphics driver needs to be updated. VPython uses the OpenGL 3D graphics library, which is sensitive to driver issues.
Only a guess but you may have let something out:
import wx
app = wx.App(redirect=True)
top = wx.Frame(None, title="Hello World", size=(300,200))
top.Show() # you need this
app.MainLoop() # you need this
I had a similar issue, or at least one with similar symptoms, and found that it was dependant on the position of the mouse at launch time (see full description here).
The solution was to call Hide and Show in succession after the display was created.
These calls need to be made to the panel fed to the display object.
win.panel.Hide()
win.panel.Show()
I would like to make a window in PyQt that you can click through; ie click on a window and the click is passed through so you can interact with whatever is behind it, while the window remains on top. An example of the effect I am trying to achieve is like the notifications on Ubuntu which appear in the top-right hand corner by default, which you can click through.
I would like to be able to do this in PyQt ideally; if not, my platform is linux but windows solutions are also welcome!
Cheers for the help in advance! I've been giving this a bit of thought and research, it would be great to be able to do this.
EDIT: I am trying to make a window you can use like tracing paper for the window behind
Here is a solution on Windows using PyQt4.
You need to override the eventFilter in the Front widget (on Windows it is winEvent) and then forward the events to the Back window.
I'm not completely sure, but there must be a similar approach that can be used on other platforms (instead of winEvent, maybe x11Event?)
Good luck!
from PyQt4 import QtCore, QtGui
import win32api, win32con, win32gui, win32ui
class Front(QtGui.QPushButton):
def __init__(self,text="",whndl=None):
super(Front,self).__init__(text)
self.pycwnd = win32ui.CreateWindowFromHandle(whndl)
# install an event filter for Windows' messages. Forward messages to
# the other HWND
def winEvent(self,MSG):
# forward Left button down message to the other window. Not sure
# what you want to do exactly, so I'm only showing a left button click. You could
if MSG.message == win32con.WM_LBUTTONDOWN or \
MSG.message == win32con.WM_LBUTTONUP:
print "left click in front window"
self.pycwnd.SendMessage(MSG.message, MSG.wParam, MSG.lParam)
return True, 0 # tells Qt to ignore the message
return super(Front,self).winEvent(MSG)
class Back(QtGui.QPushButton):
def __init__(self,text=""):
super(Back,self).__init__(text)
self.clicked.connect(self.onClick)
def onClick(self):
print 'back has been clicked'
def main():
a = QtGui.QApplication([])
back = Back("I'm in back...")
back.setWindowTitle("I'm in back...")
back.show()
# Get the HWND of the window in back (You need to use the exact title of that window)
whndl = win32gui.FindWindowEx(0, 0, None, "I'm in back...")
# I'm just making the front button bigger so that it is obvious it is in front ...
front = Front(text="*____________________________*",whndl=whndl)
front.setWindowOpacity(0.8)
front.show()
a.exec_()
if __name__ == "__main__":
main()
self.setAttribute(Qt.WA_TransparentForMouseEvents, True)
self.setAttribute(Qt.WA_NoChildEventsForParent, True)
self.setWindowFlags(Qt.Window|Qt.X11BypassWindowManagerHint|Qt.WindowStaysOnTopHint|Qt.FramelessWindowHint)
self.setAttribute(Qt.WA_TranslucentBackground)
This works. It is tested on Linux Mint 20.1 Cinnamon.
That means the parent blocked it WA_TransparentForMouseEvents all the time
I am using Python 2.7 with PyGTK and GTK of the according versions. (>>> import gtk >>> gtk.pygtk_version (2, 24, 0) >>> gtk.gtk_version (2, 24, 8)) I am writing an application where there is a main window and optionally (according to the state of a toggle button) also a settings window next to it.
I am trying to move the two windows at once (make the settings window STICK to the main window, move it with the main window). It works by default on my friends MacBook (no effort on my part), but not on my Windows 7 machine. I found a workaround that makes the settings window jump to the main one AFTER the move of the main window is finished - that is however not what I am aiming for.
Edit: FYI, the "settings_window" has the parent "main_window" which is (i guess?) doing the right job for Mac OS.
Any ideas will be greatly appreciated.
Thx, Erthy
this example works (on Ubuntu):
#!/usr/bin/env python
#coding:utf8
"""
This PyGtk example shows two windows, the master and his dog.
After master window moves or changes size, the dog window moves to always stay at its right border.
This example should also account for variable thickness of the window border.
Public domain, Filip Dominec, 2012
"""
import sys, gtk
class Main:
def __init__(self):
self.window1 = gtk.Window(); self.window1.set_title("Master")
self.window2 = gtk.Window(); self.window2.set_title("Dog")
self.window1.connect('configure_event', self.on_window1_configure_event) # move master -> move dog
self.window1.connect('destroy', lambda w: gtk.main_quit()) # close master -> end program
self.window1.show_all()
self.window2.show_all()
def on_window1_configure_event(self, *args):
print "Window 1 moved!"
x, y = self.window1.get_position()
sx, sy = self.window1.get_size()
tx = self.window1.get_style().xthickness
self.window2.move(x+sx+2*tx,y)
MainInstance = Main()
gtk.main()