Fenster mit Headerbar - Verschieben während einer Prozesses nicht möglich

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Benutzeravatar
martinjo
User
Beiträge: 160
Registriert: Dienstag 14. Juni 2011, 20:03

Fenster mit Headerbar - Verschieben während einer Prozesses nicht möglich

Beitragvon martinjo » Montag 22. Januar 2018, 20:51

Hallo

Ich möchte gerne die Headerbar von Gtk3 nutzen: https://python-gtk-3-tutorial.readthedo ... #headerbar

Das Problem, sobald eine Operation ausgeführt wird, friert das komplette Fenster ein, also es ist noch nicht einmal möglich das Fenster zu minimieren oder zur Seite zu schieben.

GTK 3.18.9
Linux Mint 18.1

Freue mich sehr über Verschläge, Danke

Code: Alles auswählen

#!/usr/bin/env python3
#-*- coding: utf-8 -*-

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gio
import time

class HeaderBarWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="HeaderBar Demo")
        self.set_modal(False)
        self.set_border_width(10)
        self.set_default_size(400, 200)

        hb = Gtk.HeaderBar()
        hb.set_show_close_button(True)
        hb.props.title = "HeaderBar example"
        self.set_titlebar(hb)

        button = Gtk.Button()
        icon = Gio.ThemedIcon(name="mail-send-receive-symbolic")
        image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
        button.add(image)
        hb.pack_end(button)
       
        box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
        Gtk.StyleContext.add_class(box.get_style_context(), "linked")

        button = Gtk.Button()
        button.add(Gtk.Arrow(Gtk.ArrowType.LEFT, Gtk.ShadowType.NONE))
        box.add(button)

        button = Gtk.Button()
        button.add(Gtk.Arrow(Gtk.ArrowType.RIGHT, Gtk.ShadowType.NONE))
        box.add(button)

        hb.pack_start(box)
       
        self.add(Gtk.TextView())
       
        button = Gtk.Button("Sleep")
        button.connect("clicked", self.on_button_clicked)
        box.add(button)

    def on_button_clicked(self, widget):
        print "on_button_clicked"
        time.sleep(4)



if __name__ == "__main__":
    win = HeaderBarWindow()
    win.connect("delete-event", Gtk.main_quit)
    win.show_all()
    Gtk.main()
Benutzeravatar
__deets__
User
Beiträge: 2158
Registriert: Mittwoch 14. Oktober 2015, 14:29

Re: Fenster mit Headerbar - Verschieben während einer Prozesses nicht möglich

Beitragvon __deets__ » Montag 22. Januar 2018, 22:09

Willkommen in der Wunderbaren Welt der GUI Programmierung. Du darfst in der Ereignisbehandlung nur Sekundenbruchteile verbringen. Wenn du längere Aufgaben hast, brauchst du andere Mechanismen wie Timer oder Threads. Bei letzteren aber aufpassen, das du im Thread keine GUI Elemente anfasst.
Benutzeravatar
martinjo
User
Beiträge: 160
Registriert: Dienstag 14. Juni 2011, 20:03

Re: Fenster mit Headerbar - Verschieben während einer Prozesses nicht möglich

Beitragvon martinjo » Mittwoch 24. Januar 2018, 11:46

Ja, daran versuche ich mich ja schon länger.

Ich habe es jetzt bei mir so umgesetzt, dass die Funktion in einem seperaten Thread starte. Dann war es nur noch tricky die Knöpfe zu deaktivieren während die Funktion läuft.

Code: Alles auswählen

    def on_button_clicked(self, widget):
        thread = Thread(target=self.do_some_work)
        thread.start()
        widget.set_sensitive(False)
        GObject.timeout_add(200, self.manage_button_sensitivity, thread,  widget)
       
    def manage_button_sensitivity(self, thread, widget):
        if thread.is_alive():
            return True
        else:
            widget.set_sensitive(True)



Auch ganz nett ist es eine Rückmeldung zu erhalten um z.B. eine Fortschrittsleiste zu füllen:

Code: Alles auswählen

   def on_button_clicked(self, widget):
        q = Queue()
        thread = Thread(target=self.do_some_work, args=(q,))
        thread.start()
        GObject.timeout_add(50, self.set_progress, thread, q)


    def set_progress(self, thread, q):
        if thread.is_alive():
            if not q.empty():
                self.progressbar.set_fraction(q.get())
            return True
        else:
            self.progressbar.set_fraction(0)


    def do_some_work(self, q):
        time.sleep(1)
        q.put(0.25)
        time.sleep(1)
        q.put(0.50)
        time.sleep(1)
        q.put(0.75)
        time.sleep(1)

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder