Làm thế nào tôi có thể viết một ứng dụng / chỉ báo bảng điều khiển được cập nhật động?


12

Tôi đang cố gắng viết một số ứng dụng bảng điều khiển cho ubfox Mate. Tôi biết C / C ++ và SDL khá hợp lý. Tôi đã thấy trang github của ứng dụng bảng điều khiển Mate-University, nhưng tôi không thể làm cho nó hoạt động bình thường / Tôi có một khoảng thời gian với nó.

Tôi chỉ tự hỏi, nếu có một số con đường dễ dàng để viết ứng dụng bảng điều khiển? Tôi không nói về việc sử dụng trình khởi chạy ứng dụng tùy chỉnh, tôi muốn thêm chức năng mới vào bảng điều khiển, nhưng tôi không biết phải làm thế nào. Một hướng dẫn, hoặc mô tả về viết ứng dụng bảng điều khiển có thể thực sự hữu ích.

Câu trả lời:


16

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 pythonviệc sử dụng AppIndicator3API. 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:

nhập mô tả hình ảnh ở đây

#!/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()gobject.idle_addbở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:

nhập mô tả hình ảnh ở đây

#!/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.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.