我可以让倒计时窗口显示下次暂停的时间吗?

当我需要去某个地方的时候我偶尔会把我的电脑留下来,但我会把它留给我绝对信任的人,我很快就会回来,所以不需要暂停(就像它的家人一样,我只是突然出现在厕所里面。离我所在的地方只有一小段距离你知道,这样的话总是暂停我的机器是不方便的,或者可能有其他原因我想要这个,比如知道我是否应该跑到我的机器上摆动鼠标在进入睡眠状态之前,或者我是否能以较慢的速度进入我的电脑。

无论如何,为了达到目的,我希望能够启动一个倒计时(最好是在屏幕右上角的所有内容的透明视图(透视位不是必须的)窗口在顶部栏的下方)显示,它将显示下一个暂停时间的倒计时。

这可以在每次与机器交互时重置计时器,或者以某种方式直接与挂起系统连接,以告知下一次挂起的时间(因为我假设有某种倒计时)。 怎么可能实现这样的事情(当然我不希望窗口总是打开,而是让我能够在任何时候启动窗口运行命令,或者它甚至可以在终端窗口中倒计时如果GUI位有问题,我会移动或自动位于右上角)?

我正在使用GNOME 3.18运行Ubuntu GNOME 15.10,但该解决方案也应该与Ubuntu GNOME 16.04和GNOME 3.20一起使用,因为我计划很快升级。

编辑

在下面的原始答案中, 在任意空闲时间之后出现倒计时窗口。 重新阅读您的问题,您可能会永久地想要它。 永久版本低于(更简单),原始答案进一步下降。


1A。 版本,永久显示倒计时时间

该解决方案是一个后台脚本,显示了一个半透明的倒计时窗口。 窗口的行为类似于通知:它总是在顶部可见,但(当然)您可以像往常一样在其他窗口中工作:

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

初始时间是应该激活暂停之前的空闲时间。 鼠标键盘事件重置时间。

如图所示,脚本带有不同的预设颜色选项(请参见下文)。

如何设置

  1. 该脚本需要xprintidle

     sudo apt-get install xprintidle 
  2. 将下面的脚本复制到一个空文件中,将其另存为countdown.py
  3. 以空闲时间作为参数运行它:

     python3 /path/to/countdown.py  

    例如

     python3 /path/to/countdown.py 300 

    5分钟后进入暂停状态。

  4. 如果一切正常,请将其添加到启动应用程序:Dash> Startup Applications> Add。 添加命令:

      /path/to/runner.py  

剧本

 #!/usr/bin/env python3 import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, Gdk, GObject, Pango from threading import Thread import subprocess import time import signal import sys import os # --- set the color (index) below (1 is the first) color = 1 # --- textcolors = ["grey", "orange", "green", "blue", "white"] # --- don't change anything below txtcolor = textcolors[color-1] countdown = int(sys.argv[1]) susp = os.path.dirname(os.path.realpath(__file__))+"/susp.sh" class CountDown(Gtk.Window): def __init__(self): Gtk.Window.__init__(self) maingrid = Gtk.Grid() self.add(maingrid) maingrid.set_border_width(40) # set initial text for the spash window self.label = Gtk.Label(convert_seconds(countdown)) self.label.modify_font(Pango.FontDescription('Ubuntu 22')) self.label.set_width_chars(10) maingrid.attach(self.label, 0, 0, 1, 1) self.update = Thread(target=self.start_countdown, args=[countdown]) # daemonize the thread self.update.setDaemon(True) self.update.start() def start_countdown(self, countdown): idle1 = idletime() t = countdown while True: time.sleep(1) idle2 = idletime() if idle2 < idle1: t = countdown else: t -= 1 if t <= 0: subprocess.Popen(["systemctl", "suspend"]) GObject.idle_add(self.label.set_text, convert_seconds(t), priority=GObject.PRIORITY_DEFAULT) idle1 = idle2 def stop(self): Gtk.main_quit() def get_screen(): scr = [s.split("x") for s in subprocess.check_output([ "xrandr"]).decode("utf-8").split() if "+0+0" in s][0] return int(scr[0]) - 300 def convert_seconds(sec): timedisplay = [ str(int(sec/3600)), str(int((sec % 3600)/60)), str(int(sec % 60)), ] for i, n in enumerate(timedisplay): if len(n) == 1: timedisplay[i] = "0"+n return ":".join(timedisplay) def idletime(): return int(subprocess.check_output( "xprintidle" ).decode("utf-8").strip())/1000 def splashwindow(): window = CountDown() window.set_decorated(False) window.set_resizable(False) window.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(0,0,0,1)) window.modify_fg(Gtk.StateFlags.NORMAL, Gdk.color_parse(txtcolor)) window.set_opacity(0.6) window.move(get_screen(), 80) window.set_keep_above(True) window.show_all() Gtk.main() GObject.threads_init() splashwindow() 

注意

可以更改文本颜色,如答案第二版底部所述。

1B。 根据评论中的要求:相同脚本的豪华版:如果一半时间过去,文本颜色会变为黄色,在暂停前30秒变为红色。

在此处输入图像描述 > 在此处输入图像描述 > 在此处输入图像描述

完全像1a一样使用它。

剧本

 #!/usr/bin/env python3 import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, Gdk, GObject, Pango from threading import Thread import subprocess import time import signal import sys import os # --- set the color (index) below (1 is the first) color = 1 # --- textcolors = ["grey", "orange", "green", "blue", "white", "yellow", "red"] # --- don't change anything below txtcolor = textcolors[color-1] al_cl1 = textcolors[5]; al_cl2 = textcolors[6] countdown = int(sys.argv[1]) alarm1 = int(countdown/2) alarm2 = 30 class CountDown(Gtk.Window): def __init__(self): Gtk.Window.__init__(self) maingrid = Gtk.Grid() self.add(maingrid) maingrid.set_border_width(40) # set initial text for the spash window self.label = Gtk.Label(convert_seconds(countdown)) self.label.modify_font(Pango.FontDescription('Ubuntu 22')) self.label.modify_fg(Gtk.StateFlags.NORMAL, Gdk.color_parse(txtcolor)) self.label.set_width_chars(10) maingrid.attach(self.label, 0, 0, 1, 1) self.update = Thread(target=self.start_countdown, args=[countdown]) # daemonize the thread self.update.setDaemon(True) self.update.start() def mod_color(self, color): self.label.modify_fg(Gtk.StateFlags.NORMAL, Gdk.color_parse(color)) def start_countdown(self, countdown): idle1 = idletime() t1 = countdown t2 = countdown while True: time.sleep(1) idle2 = idletime() if idle2 < idle1: t2 = countdown if t1 <= alarm1: # print("change textcolor default") GObject.idle_add(self.mod_color, txtcolor, priority=GObject.PRIORITY_DEFAULT) else: t2 -= 1 if all([t2 <= alarm2, t1 > alarm2]): # print("change textcolor red") GObject.idle_add(self.mod_color, al_cl2, priority=GObject.PRIORITY_DEFAULT) elif all([t2 <= alarm1, t1 > alarm1]): # print("change textcolor yellow") GObject.idle_add(self.mod_color, al_cl1, priority=GObject.PRIORITY_DEFAULT) if t2 <= 0: subprocess.Popen(["systemctl", "suspend"]) GObject.idle_add(self.label.set_text, convert_seconds(t2), priority=GObject.PRIORITY_DEFAULT) idle1 = idle2 t1 = t2 def stop(self): Gtk.main_quit() def get_screen(): scr = [s.split("x") for s in subprocess.check_output([ "xrandr"]).decode("utf-8").split() if "+0+0" in s][0] return int(scr[0]) - 300 def convert_seconds(sec): timedisplay = [ str(int(sec/3600)), str(int((sec % 3600)/60)), str(int(sec % 60)), ] for i, n in enumerate(timedisplay): if len(n) == 1: timedisplay[i] = "0"+n return ":".join(timedisplay) def idletime(): return int(subprocess.check_output( "xprintidle" ).decode("utf-8").strip())/1000 def splashwindow(): window = CountDown() window.set_decorated(False) window.set_resizable(False) window.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(0,0,0,1)) window.set_opacity(0.6) window.move(get_screen(), 80) window.set_keep_above(True) window.show_all() Gtk.main() GObject.threads_init() splashwindow() 


2.原始答案:版本,显示x空闲时间后的倒计时时间

下面的设置将显示下一次暂停的倒计时(在任意时间长度内):

在此处输入图像描述

窗口始终位于所有其他窗口的顶部,与通知气泡完全相同。

该设置取代了“正常”挂起设置,这意味着您需要从系统设置中禁用挂起。

关于解决方案

暂停在脚本中的命令是:

  systemctl suspend 

这不需要sudo 。 结果是您至少需要15.04才能使用此解决方案。
该脚本是在Ubuntu (Unity) 15.10上编写和测试的,但其中没有特定的代码应该是Unity特定的。 我认为它适用于所有默认的Ubuntu版本> 15.04

这个怎么运作

要设置(下面的详细版本),只需将涉及的三个脚本复制到同一个目录中,完全按照指示命名。 要运行,只需运行主脚本(运行时间检查)。

  • 如果空闲时间超过某个限制,则调用倒计时窗口。
  • 如果在倒计时期间计算机变为空闲(鼠标或键盘事件),则窗口关闭(其pid被杀死)。
  • 如果计时器已经结束倒计时,它会运行一个简单的脚本来暂停

如何设置

  1. 该脚本需要xprintidle

     sudo apt-get install xprintidle 
  2. 将下面的三个脚本复制到单独的空文件中,将其保存在同一个目录中 ,完全按照指示命名:

    A.保存(确切)为win.py

     #!/usr/bin/env python3 import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, Gdk, GObject, Pango from threading import Thread import subprocess import time import signal import sys import os # --- set the color (index) below (1 is the first) color = 1 # --- textcolors = ["grey", "orange", "green", "blue", "white"] # --- don't change anything below txtcolor = textcolors[color-1] countdown = int(sys.argv[1]) susp = os.path.dirname(os.path.realpath(__file__))+"/susp.sh" class CountDown(Gtk.Window): def __init__(self): Gtk.Window.__init__(self) maingrid = Gtk.Grid() self.add(maingrid) maingrid.set_border_width(40) # set initial text for the spash window self.label = Gtk.Label(convert_seconds(countdown)) self.label.modify_font(Pango.FontDescription('Ubuntu 22')) self.label.set_width_chars(10) maingrid.attach(self.label, 0, 0, 1, 1) self.update = Thread(target=self.start_countdown, args=[countdown]) # daemonize the thread self.update.setDaemon(True) self.update.start() def start_countdown(self, countdown): t = countdown while t > 0: time.sleep(1) t -= 1 GObject.idle_add(self.label.set_text, convert_seconds(t), priority=GObject.PRIORITY_DEFAULT) print(t) subprocess.Popen(["/bin/bash", susp]) self.stop() def stop(self): Gtk.main_quit() def get_screen(): scr = [s.split("x") for s in subprocess.check_output([ "xrandr"]).decode("utf-8").split() if "+0+0" in s][0] return int(scr[0]) - 300 def convert_seconds(sec): timedisplay = [ str(int(sec/3600)), str(int((sec % 3600)/60)), str(int(sec % 60)), ] for i, n in enumerate(timedisplay): if len(n) == 1: timedisplay[i] = "0"+n return ":".join(timedisplay) def splashwindow(): window = CountDown() window.set_decorated(False) window.set_resizable(False) window.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(0,0,0,1)) window.modify_fg(Gtk.StateFlags.NORMAL, Gdk.color_parse(txtcolor)) window.set_opacity(0.6) window.move(get_screen(), 80) window.set_keep_above(True) window.show_all() Gtk.main() GObject.threads_init() splashwindow() 

    B.完全保存为runner.py

     #!/usr/bin/env python3 import subprocess import time import os import sys window_mod = os.path.dirname(os.path.realpath(__file__))+"/win.py" suspend = int(sys.argv[1]) countdown = int(sys.argv[2]) w = False while True: time.sleep(1) idletime = int(subprocess.check_output( "xprintidle" ).decode("utf-8").strip())/1000 if all([idletime > suspend-countdown, w == False]): subprocess.Popen(["python3", window_mod, str(countdown)]) w = True elif all([idletime < suspend-countdown, w == True]): try: procdata = subprocess.check_output([ "pgrep", "-f", window_mod ]).decode("utf-8").strip() procs = procdata.splitlines() except subprocess.CalledProcessError: pass else: for p in procs: subprocess.Popen(["kill", p]) w = False 

    C.保存(确切)为susp.sh

     #!/bin/bash sleep 3 systemctl suspend 
  3. 使所有三个脚本都可执行 ,并再次确保它们位于同一个目录中。

  4. 你几乎完成了。

    • 禁用“常规”暂停设置
    • 测试 - 运行脚本的暂停时间(应该应用挂起之前的空闲时间),以及作为参数的倒计时时间(以秒为单位),例如:

       /path/to/runner.py 600 300 

      将空闲时间设置为10分钟,计数器在暂停前5分钟开始。

  5. 如果一切正常,请将其添加到启动应用程序:Dash> Startup Applications> Add。 添加命令:

      /path/to/runner.py   

笔记

  1. win.py的head部分,您可以为显示的文本设置不同的颜色:

     # --- set the color (index) below (1 is the first) color = 1 # --- textcolors = ["grey", "orange", "green", "blue", "white"] 
  2. 使用行中的值:

     maingrid.set_border_width(10) 

     return int(scr[0]) - 200 

    (来自函数get_screen ,其中200是窗口左侧到屏幕右侧的距离),以及

     window.move(get_screen(), 35) 

    (其中35是窗口和屏幕顶部之间的距离),您可以轻松更改窗口的几何形状,例如:

    在此处输入图像描述

玩得开心 :)

您可以安装一个名为xprintidle的程序来为您提供计算机的空闲时间,但您必须提供某种脚本才能在屏幕上显示它

我不擅长编写脚本,所以这是我能提出的所有帮助…希望它能给你一个开始的地方。