Vì những gì dường như là dịp để đặt câu hỏi này đã có câu trả lời , tôi trả lời câu hỏi này như một lời giải thích mở rộng về cách nó được thực hiện (trong python
)
Chỉ báo tĩnh cơ bản
Vì Ubuntu Mate, từ 15,10, hỗ trợ các chỉ báo, không có nhiều khác biệt giữa việc viết chỉ báo và ứng dụng bảng điều khiển cho Mate. Do đó, liên kết này là điểm khởi đầu tốt cho một chỉ báo cơ bản trong python
việc sử dụng AppIndicator3
API. Liên kết là một khởi đầu tốt đẹp, nhưng không cung cấp bất kỳ thông tin nào về cách hiển thị văn bản trên chỉ báo, chứ chưa nói đến cách cập nhật văn bản (hoặc biểu tượng). Tuy nhiên, với một vài bổ sung, điều này dẫn đến một "khung" cơ bản của một chỉ báo như dưới đây. Nó sẽ hiển thị một biểu tượng, nhãn văn bản và menu:
#!/usr/bin/env python3
import signal
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
from gi.repository import Gtk, AppIndicator3
class Indicator():
def __init__(self):
self.app = 'test123'
iconpath = "/opt/abouttime/icon/indicator_icon.png"
self.indicator = AppIndicator3.Indicator.new(
self.app, iconpath,
AppIndicator3.IndicatorCategory.OTHER)
self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
self.indicator.set_menu(self.create_menu())
self.indicator.set_label("1 Monkey", self.app)
def create_menu(self):
menu = Gtk.Menu()
# menu item 1
item_1 = Gtk.MenuItem('Menu item')
# item_about.connect('activate', self.about)
menu.append(item_1)
# separator
menu_sep = Gtk.SeparatorMenuItem()
menu.append(menu_sep)
# quit
item_quit = Gtk.MenuItem('Quit')
item_quit.connect('activate', self.stop)
menu.append(item_quit)
menu.show_all()
return menu
def stop(self, source):
Gtk.main_quit()
Indicator()
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()
Trong dòng AppIndicator3.IndicatorCategory.OTHER
, danh mục được xác định, như được giải thích trong liên kết (lỗi thời một phần) này . Đặt đúng danh mục là quan trọng, áo để đặt chỉ báo vào một vị trí thích hợp trong bảng điều khiển.
Thử thách chính; cách cập nhật văn bản chỉ báo và / hoặc biểu tượng
Thách thức thực sự không phải là làm thế nào để viết một chỉ báo cơ bản, mà là làm thế nào để cập nhật định kỳ văn bản và / hoặc biểu tượng của chỉ báo của bạn, vì bạn muốn nó hiển thị thời gian (văn bản). Để làm cho chỉ báo hoạt động chính xác, chúng ta không thể chỉ cần sử dụng threading
để bắt đầu một quy trình thứ hai để định kỳ cập nhật giao diện. Vâng, thực sự chúng ta có thể, nhưng về lâu dài, nó sẽ dẫn đến xung đột, như tôi đã tìm ra.
Đây là nơi GObject
đến, đến, vì nó được đặt trong liên kết (cũng đã lỗi thời) này :
gọi gobject.threads_init()
lúc khởi tạo applicaiton. Sau đó, bạn khởi chạy các luồng của mình một cách bình thường, nhưng đảm bảo rằng các luồng không bao giờ thực hiện bất kỳ tác vụ GUI nào trực tiếp. Thay vào đó, bạn sử dụng gobject.idle_add
để lên lịch tác vụ GUI để thực thi trong luồng chính
Khi chúng ta thay thế gobject.threads_init()
bằng GObject.threads_init()
và gobject.idle_add
bởi GObject.idle_add()
, chúng tôi có khá nhiều phiên bản cập nhật được cách điều hành chủ đề trong một Gtk
ứng dụng. Một ví dụ đơn giản hóa, hiển thị số lượng khỉ ngày càng tăng:
#!/usr/bin/env python3
import signal
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
from gi.repository import Gtk, AppIndicator3, GObject
import time
from threading import Thread
class Indicator():
def __init__(self):
self.app = 'test123'
iconpath = "/opt/abouttime/icon/indicator_icon.png"
self.indicator = AppIndicator3.Indicator.new(
self.app, iconpath,
AppIndicator3.IndicatorCategory.OTHER)
self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
self.indicator.set_menu(self.create_menu())
self.indicator.set_label("1 Monkey", self.app)
# the thread:
self.update = Thread(target=self.show_seconds)
# daemonize the thread to make the indicator stopable
self.update.setDaemon(True)
self.update.start()
def create_menu(self):
menu = Gtk.Menu()
# menu item 1
item_1 = Gtk.MenuItem('Menu item')
# item_about.connect('activate', self.about)
menu.append(item_1)
# separator
menu_sep = Gtk.SeparatorMenuItem()
menu.append(menu_sep)
# quit
item_quit = Gtk.MenuItem('Quit')
item_quit.connect('activate', self.stop)
menu.append(item_quit)
menu.show_all()
return menu
def show_seconds(self):
t = 2
while True:
time.sleep(1)
mention = str(t)+" Monkeys"
# apply the interface update using GObject.idle_add()
GObject.idle_add(
self.indicator.set_label,
mention, self.app,
priority=GObject.PRIORITY_DEFAULT
)
t += 1
def stop(self, source):
Gtk.main_quit()
Indicator()
# this is where we call GObject.threads_init()
GObject.threads_init()
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()
Đó là nguyên tắc. Trong chỉ báo thực tế trong câu trả lời này , cả thời gian vòng lặp và văn bản chỉ báo được xác định bởi một mô-đun phụ, được nhập trong tập lệnh, nhưng ý tưởng chính là như nhau.