ฉันจะเขียนแอพ / ตัวบ่งชี้แผงที่อัปเดตแบบไดนามิกได้อย่างไร


12

ฉันกำลังพยายามเขียนแอพพาเนลสำหรับ ubuntu Mate ฉันรู้ C / C ++ และ SDL ดีพอสมควร ฉันได้เห็นหน้าแอพพลิเคชั่นของ Mate-University แผง github แต่ฉันไม่สามารถทำงานได้อย่างถูกต้อง / ฉันมีเวลาอยู่ด้วย

ฉันแค่สงสัยว่าถ้ามีบางวิธีที่ง่ายในการเขียนแอปแผง? ฉันไม่ได้พูดถึงการใช้ตัวเรียกใช้งานแอปพลิเคชันที่กำหนดเองฉันต้องการเพิ่มฟังก์ชันการทำงานใหม่ให้กับแผงควบคุม แต่ฉันไม่แน่ใจว่าจะทำอย่างไร บทแนะนำหรือคำอธิบายเกี่ยวกับการเขียนแอปแผงอาจมีประโยชน์จริงๆ

คำตอบ:


16

เนื่องจากสิ่งที่ดูเหมือนจะเป็นโอกาสที่จะถามคำถามนี้มีคำตอบอยู่แล้วฉันจึงตอบคำถามนี้เป็นคำอธิบายเพิ่มเติมเกี่ยวกับวิธีการทำ (ในpython)

ตัวบ่งชี้พื้นฐานคงที่

ตั้งแต่ Ubuntu Mate จาก 15,10 รองรับตัวบ่งชี้จึงไม่มีความแตกต่างระหว่างการเขียนตัวบ่งชี้และแอพพาเนลสำหรับ Mate ดังนั้นลิงค์นี้เป็นจุดเริ่มต้นที่ดีสำหรับตัวบ่งชี้พื้นฐานpythonโดยใช้AppIndicator3API ลิงค์นี้เป็นจุดเริ่มต้นที่ดี แต่ไม่ได้ให้ข้อมูลใด ๆ เกี่ยวกับวิธีแสดงข้อความบนตัวบ่งชี้ให้ทำอย่างเดียววิธีอัปเดตข้อความ (หรือไอคอน) อย่างไรก็ตามด้วยการเพิ่มเติมเล็กน้อยสิ่งนี้นำไปสู่ ​​"เฟรม" พื้นฐานของตัวบ่งชี้ด้านล่าง มันจะแสดงไอคอนป้ายข้อความและเมนู:

ป้อนคำอธิบายรูปภาพที่นี่

#!/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()

ในสายAppIndicator3.IndicatorCategory.OTHERประเภทจะถูกกำหนดเป็น explaned ในการเชื่อมโยงนี้ (ล้าสมัยบางส่วน) การตั้งค่าประเภทที่เหมาะสมเป็นสิ่งสำคัญ ao เพื่อใส่ตัวบ่งชี้ในตำแหน่งที่เหมาะสมในแผง

ความท้าทายหลัก; วิธีอัปเดตข้อความและ / หรือไอคอนตัวบ่งชี้

ความท้าทายที่แท้จริงไม่ใช่วิธีการเขียนตัวบ่งชี้พื้นฐาน แต่จะปรับปรุงข้อความและ / หรือไอคอนของตัวบ่งชี้ของคุณเป็นระยะเนื่องจากคุณต้องการให้มันแสดงเวลา (ต้นฉบับ) เพื่อให้ตัวบ่งชี้ทำงานอย่างถูกต้องเราไม่สามารถใช้threadingเพื่อเริ่มกระบวนการที่สองเพื่ออัปเดตอินเทอร์เฟซเป็นระยะ จริง ๆ แล้วเราทำได้ แต่ในระยะยาวมันจะนำไปสู่ความขัดแย้งตามที่ฉันค้นพบ

นี่คือที่GObjectมาในไปที่มันถูกใส่ในลิงค์นี้ (ยังล้าสมัย) :

โทรไปgobject.threads_init()ที่การเริ่มต้นใช้งาน จากนั้นคุณเปิดใช้เธรดของคุณตามปกติ แต่ให้แน่ใจว่าเธรดจะไม่ทำงาน GUI ใด ๆ โดยตรง คุณใช้gobject.idle_addเพื่อกำหนดตารางเวลางาน GUI ให้ดำเนินการในเธรดหลักแทน

เมื่อเราเข้ามาแทนที่gobject.threads_init() โดยGObject.threads_init()และgobject.idle_addโดยGObject.idle_add()เราสวยมากมีรุ่นปรับปรุงของวิธีการเรียกใช้หัวข้อในGtkการประยุกต์ใช้ ตัวอย่างที่เรียบง่ายแสดงจำนวนลิงเพิ่มขึ้น:

ป้อนคำอธิบายรูปภาพที่นี่

#!/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()

นั่นคือหลักการ ในตัวบ่งชี้ที่แท้จริงในคำตอบนี้ทั้งเวลาลูปและข้อความตัวบ่งชี้ถูกกำหนดโดยโมดูลรองที่นำเข้ามาในสคริปต์ แต่แนวคิดหลักเหมือนกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.