全屏 Python TKinter 或 wxPython 窗口,但“停留在底部”所有窗口?

发布于 2024-12-21 17:04:30 字数 2525 浏览 1 评论 0原文

我想创建一个全屏面板,在视觉上阻止对屏幕上所有内容的访问(Ubuntu (11.10) 中的桌面、菜单、Unity 面板等),但位于其他应用程序打开的窗口下方。

这主要是为了让笔记本电脑具有儿童防护功能。我希望孩子(4 岁)能够访问一些选定的应用程序,即。 gcompris、儿童游戏、晚礼服数学等,但并非真正适用于其他应用程序和设置。像自定义桌面+启动器面板一样,没有任何破坏,无法访问文件等。

我希望面板包含一些可以启动其他应用程序的按钮(使用 subprocess.call),但面板本身需要保留在从其启动的任何内容下它或使事情变得更容易,以便它保留在任何打开的全屏游戏和每个打开的窗口下(即使面板获得焦点)。

Python tkinter 的全屏 overrideredirect(True) 将是完美的(带有受密码保护的关闭按钮),如果不是因为它不允许其他应用程序出现在它上面,而且我不确定是否可以使其停留在底部的一切。

知道如何在可能的情况下改变这种行为,或者有任何其他工具可以让我在 python 或其他方式中做到这一点吗?

编辑:附加信息:

我已经让它几乎可以工作了,但是 overrideredirect(True) 的另一个奇怪的行为。我可以在开始时降低()应用程序并且可以,但是当我使用 overrideredirect(True) 执行此操作时,应用程序完全消失。下面的非全屏测试代码:

from tkinter import *

def btn1_click():app.quit();app.destroy()
def btn2_click():app.lower()    
def handler():
    if tkinter.messagebox.askyesno("Quit?", "Are you sure you want to quit?"):
        app.quit();app.destroy()

app = Tk()
app.title("Testing...")
app.geometry('300x100+200+100')
#app.overrideredirect(True) 
#app.lower()

b1 = Button(app, text = "Exit!", width = 10, command = btn1_click);b1.pack()
b2 = Button(app, text = "Lower", width = 10, command = btn2_click);b2.pack()
app.protocol("WM_DELETE_WINDOW", handler)
app.mainloop()

当您按原样运行它时,它将打开新窗口并按“较低”按钮将其发送到后面,但是如果您取消注释 app.overrideredirect(True) 行并按按钮应用程序仍将运行,但不再可见。

编辑... 好吧,我想我明白了:

>>>help(tkinter)
...
     |  overrideredirect = wm_overrideredirect(self, boolean=None)
     |      Instruct the window manager to ignore this widget
     |      if BOOLEAN is given with 1. Return the current value if None
     |      is given.
...

所以,首先我要求窗口管理器忽略我的窗口,但后来我仍然希望 wm 对我的窗口做一些事情...... hypcracy :)

任何其他方法来剥离窗口装饰而不询问wm 忽略窗口?

编辑。使用不同的工具 - wxPython 再次查看该问题

,这次我尝试简单的方法 - 使用 Boa 构造函数。虽然窗口框架上的 app.lower() 在 Tkinter 上工作得很好,但由于某种原因,我现在在使用 wxPython 时遇到了问题。在下面的代码中 - 按下按钮在框架上打开一个 gedit 窗口,2 秒后框架被带到顶部,再过 2 秒后它应该落到窗口堆栈的底部,但这至少不会发生不在我的 Ubuntu 上。

def OnButton3Button(self, event):
    subprocess.call("gedit") #opens gedit above the Frame
    time.sleep(2) #waits for 2 seconds
    self.Raise() #brings the Frame to the top
    time.sleep(2) #waits for another 2 seconds
    self.Lower() #should Lower the Frame to the bottom, but it doesn't

如果我能让 Lower() 以某种方式工作,那么可以很容易地通过 ie. 完成:

def OnFrame1Activate(self, event):
    self.ShowFullScreen(True)

def OnFrame1EnterWindow(self, event):
    self.Lower()

现在我没有想法了,可能我会按照建议坚持使用来宾帐户。

I want to create a fullscreen panel that visually blocks access to everything on the screen (desktop, menu, Unity Panel, etc in Ubuntu (11.10)), but stays below other applications' opened windows.

This is mainly to make the laptop child proof. I want the kid (4 years old) to have access to some selected apps ie. gcompris, childs play, tux math, etc. but not really to other apps and settings. Something like custom desktop + launcher panel without anything to break, no access to files, etc.

I want the panel to contain some buttons that would start other applications (using subprocess.call) but the panel itself needs to stay under anything that's launched from it or to make things easier just so it stays under any opened fullscreen games and every opened window (even when the panel takes focus).

Python tkinter's fullscreen overrideredirect(True) would be perfect (with a password protected close button) if not the fact that it does not allow other applications to appear over it and I'm not sure if it is possible to make it stay at the bottom of everything.

Any idea how to change this behavior if possible, or any other tools that would enable me to do this in python or otherwise?

Edit: additional info:

I have got it nearly working but another strange behaviour with overrideredirect(True). I could lower() the app at the start and its ok, but when I do it with the overrideredirect(True) the app disappears completely. Non-fullscreen testing code below:

from tkinter import *

def btn1_click():app.quit();app.destroy()
def btn2_click():app.lower()    
def handler():
    if tkinter.messagebox.askyesno("Quit?", "Are you sure you want to quit?"):
        app.quit();app.destroy()

app = Tk()
app.title("Testing...")
app.geometry('300x100+200+100')
#app.overrideredirect(True) 
#app.lower()

b1 = Button(app, text = "Exit!", width = 10, command = btn1_click);b1.pack()
b2 = Button(app, text = "Lower", width = 10, command = btn2_click);b2.pack()
app.protocol("WM_DELETE_WINDOW", handler)
app.mainloop()

when you run it as it is it will open new window and pressing the 'Lower' button will send it to the back, but if you uncomment the app.overrideredirect(True) line and press the button the app will still run but will no longer be visible.

Edit...
Ok, I think I get it:

>>>help(tkinter)
...
     |  overrideredirect = wm_overrideredirect(self, boolean=None)
     |      Instruct the window manager to ignore this widget
     |      if BOOLEAN is given with 1. Return the current value if None
     |      is given.
...

So, first I am asking the window manager to ignore my window, but later I still want the wm to do something to my window... hypcracy :)

Any other ways to strip window decoration without asking the wm to ignore the window?

Edit. Another look at the problem with a different tool - wxPython

This time I'm trying it the easy way - using the Boa Constructor. While app.lower() on a windowed Frame worked fine with Tkinter, for some reason I have a problem with wxPython now. In the code below - pressing the button opens a gedit window over the Frame, than 2 seconds later frame is brought to the top and another 2 seconds later it should fall to the bottom of the window stack, but that does not happen, at least not on my Ubuntu.

def OnButton3Button(self, event):
    subprocess.call("gedit") #opens gedit above the Frame
    time.sleep(2) #waits for 2 seconds
    self.Raise() #brings the Frame to the top
    time.sleep(2) #waits for another 2 seconds
    self.Lower() #should Lower the Frame to the bottom, but it doesn't

if I could make the Lower() work somehow it would be easily done by ie.:

def OnFrame1Activate(self, event):
    self.ShowFullScreen(True)

def OnFrame1EnterWindow(self, event):
    self.Lower()

Now I run out of ideas, probably I will just stick to the Guest Account as suggested.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

滥情稳全场 2024-12-28 17:04:30

这就是我在 Windows 上的 pygame 中设置窗口位置的方法。
有了这个,它将覆盖所有其他窗口,如果你将-1更改为1,它将位于其他窗口后面,我只知道它在Windows中有效。

import pygame, time, datetime, ctypes
from pygame.locals import *
from ctypes import windll

pygame.init()
set_window_pos = windll.user32.SetWindowPos
monitorsize = ctypes.windll.user32
resolution_X = monitorsize.GetSystemMetrics(0)
resolution_Y = monitorsize.GetSystemMetrics(1)

screen = pygame.display.set_mode((255, 242), pygame.NOFRAME)
set_window_pos(pygame.display.get_wm_info()['window'], -1, (resolution_X - 255), 50, 0, 0, 0x0001)

使窗口全屏化是通过以下方式完成的:

screen = pygame.display.set_mode((800, 350), FULLSCREEN) # this works in linux

This is how I set the window position in pygame on windows.
With this, it will cover all other windows, if you change the -1 to a 1 it will be behind other windows, I only know it works in windows.

import pygame, time, datetime, ctypes
from pygame.locals import *
from ctypes import windll

pygame.init()
set_window_pos = windll.user32.SetWindowPos
monitorsize = ctypes.windll.user32
resolution_X = monitorsize.GetSystemMetrics(0)
resolution_Y = monitorsize.GetSystemMetrics(1)

screen = pygame.display.set_mode((255, 242), pygame.NOFRAME)
set_window_pos(pygame.display.get_wm_info()['window'], -1, (resolution_X - 255), 50, 0, 0, 0x0001)

Making a window FULLSCREEN is done with:

screen = pygame.display.set_mode((800, 350), FULLSCREEN) # this works in linux
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文