Glade + python : εμφάνιση spinner

...του ubuntu και έργων ΕΛ/ΛΑΚ (Έργα-Οδηγοί-Προτάσεις)

Συντονιστής: konnn

Glade + python : εμφάνιση spinner

Δημοσίευσηαπό parenthesis » 30 Σεπ 2011, 03:06

Ποστάρω μια απόπειρα (από τις πρώτες μου) να δημιουργήσω GUI με το Glade. Χρειάζομαι τα φώτα σας, γιατί πραγματικά μου έχουν σπάσει τα νεύρα, ψάχνω στο ίντερνετ μέρες τώρα και δεν έχω καταφέρει να βρω λύση. Λοιπόν, το πρόβλημα έχει ως εξής :
Το πρόγραμμά μου δέχεται 2 φακέλους από το χρήστη (έναν source και έναν destination) και αναλαμβάνει να αντιγράψει όλα τα αρχεία του source φακέλου στον destination, ελέγχοντας πρώτα το κάθε αρχείο αν υπάρχει, αν έχει το ίδιο μέγεθος, κλπ. Μέχρι εδώ καλά. Το θέμα μου είναι ότι κατά τη διαδικασία της αντιγραφής θέλω στον χρήστη να εμφανίζεται ένα μήνυμα του στυλ "Παρακαλώ περιμένετε" και ένα spinner. Όταν τελειώσει η αντιγραφή, θα πετάγεται ένα μήνυμα που θα λέει "Τέλος!" ξέρω γω... Μετά από αρκετές προσπάθειες κατάλαβα ότι μάλλον για να γίνουν 2 δουλειές ταυτόχρονα χρειάζεται multiprocessing (μπορεί και όχι, και να δυσκολεύω τη ζωή μου χωρίς λόγο, αλλά δε βρήκα άλλο τρόπο). Όρισα λοιπόν μία Process για την αντιγραφή των αρχείων και μια για τον spinner. Μετά από επίσης αρκετές προσπάθειες κατάφερα να βρω έναν τρόπο με τα events να ελέγχω πότε τελειώνει η αντιγραφή.
Το πρόβλημά μου είναι ότι το spinner ποτέ δεν εμφανίζεται, ενώ η διαδικασία (απ'όσο καταλαβαίνω) εκτελείται κανονικά (στο τερματικό εμφανίζεται το μήνυμα "spinner running").

Παρακάτω έχω αντικαταστήσει τη διαδικασία αντιγραφής αρχείων με μια άλλη που απλά δείχνει την εξέλιξή της εμφανίζοντας στην οθόνη 4 μηνύματα με διαφορά 1 sec.
Επίσης, η αντιγραφή ξεκινάει με το πάτημα του synchbutton, και το spinner εμφανίζεται στο ίδιο παράθυρο (mainwindow).

Όποιος μπορεί, ας βοηθήσει παρακαλώ, μια συμβουλή / ένα link / κάτι, γιατί έχω σκαλώσει άγρια... :( :?:

Κώδικας: Επιλογή όλων
#! /usr/bin/env python

import pygtk
pygtk.require('2.0')
import gtk
import threading
import thread
from multiprocessing import Process, Event
import time

def copying () :
print("Copying...")
time.sleep(1)
print("Copying...")
time.sleep(1)
print("Copying...")
time.sleep(1)
print("Copying...")
time.sleep(1)

return True

class Synchronaiz() :

def __init__(self) :
builder = gtk.Builder()
builder.add_from_file("synchronaiz.glade")

self.mainwindow = builder.get_object("mainwindow")
self.donewindow = builder.get_object("donewindow")
self.statuslabel = builder.get_object("statuslabel")
self.spinner = builder.get_object("spinner")
builder.connect_signals(self)

def on_window_destroy(self, widget, data=None) :
gtk.main_quit()

def on_synchbutton_clicked(self, widget, data=None) :

def startSpinner() :
self.statuslabel.set_text(u'Synching... It may take a few minutes.')
self.spinner.show()
self.spinner.start()
print("spinner running.")

def startCopying(event) :
isdone = False
isdone = copying()
if (isdone == True) :
event.set()

def checkCopying(event, killEvent) :
event.wait()
print("Copying is done.")
killEvent.set()

event = Event()
event.clear()
killEvent = Event()

spin = Process(target=startSpinner(), args=())
spin.start()

cop = Process(target=startCopying, args=(event, ))
cop.start()

t = threading.Thread(target=checkCopying, args=(event, killEvent))
t.start()

try :
while not killEvent.is_set() :
pass
finally :
cop.terminate()
spin.terminate()
self.mainwindow.hide()
self.donewindow.show()

if __name__ == '__main__' :
synch = Synchronaiz()
synch.mainwindow.show()
gtk.main()
1 Γνώσεις Linux: Πρώτα βήματα ┃ Προγραμματισμού: Ικανοποιητικό ┃ Αγγλικών: Πολύ καλό
2 Dual boot:
  • Ubuntu 13.04 raring 3.8.0-34-generic 64bit (el_GR.UTF-8, Unity ubuntu), Ubuntu 3.8.0-19-generic
  • Fedora 19 Schrödinger’s Cat 3.13.5-101.fc19.x86_64 64bit (el_GR.utf8, gnome)
3 Intel Core i5-3337U CPU @ 1.80GHz ‖ RAM 3844 MiB ‖ TOSHIBA VCUAA - TOSHIBA SATELLITE U940
4 Intel 3rd Gen Core processor Graphics Controller [8086:0166] {i915}
5 eth0: Realtek RTL8101E/RTL8102E Ethernet [10ec:8136] (rev 05) ⋮ wlan0: Intel Centrino Wireless-N 2230 [8086:0887] (rev c4)
Άβαταρ μέλους
parenthesis
punkTUX
punkTUX
 
Δημοσιεύσεις: 150
Εγγραφή: 06 Οκτ 2009, 22:47
Launchpad: mara_sdr
Εκτύπωση

Re: Glade + python : εμφάνιση spinner

Δημοσίευσηαπό the_eye » 03 Οκτ 2011, 17:40

Δεν ξέρω σε python πως υλοποιείτε αλλά σε τερματικό αν θέλουμε να τρέξουμε μαζί τις διεργασίες pros1, pros2 και στο τέλος να τρέξει η telos θα το γράφαμε έτσι :problem:
Κώδικας: Επιλογή όλων
pros1&pros2&&telos
Όσο λιγότερο κλειστό λογισμικό έχεις, τόσα λιγότερα προβλήματα.
1 Γνώσεις ⇛ Linux: Καλό ┃ Προγραμματισμός: Ναι PHP, MySQL ┃ Αγγλικά: Καλά
2 Ubuntu 24.04.2
3 Intel Core i5-6500 CPU @ 3.20GHz ‖ RAM 7836 MiB ‖ Gigabyte B150M-HD3 DDR3-CF - Gigabyte B150M-HD3 DDR3
4 Intel HD Graphics 530 [8086:1912] {i915}
5 enp1s0: Realtek RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller [10ec:8168] (rev 15)
Άβαταρ μέλους
the_eye
Διαχειριστής
Διαχειριστής
 
Δημοσιεύσεις: 11723
Εγγραφή: 16 Μαρ 2010, 17:19
Launchpad: ntoulasd
IRC: the_eye_
Εκτύπωση

Re: Glade + python : εμφάνιση spinner

Δημοσίευσηαπό medigeek » 03 Οκτ 2011, 19:36

parenthesis έγραψε:Μετά από αρκετές προσπάθειες κατάλαβα ότι μάλλον για να γίνουν 2 δουλειές ταυτόχρονα χρειάζεται multiprocessing (μπορεί και όχι, και να δυσκολεύω τη ζωή μου χωρίς λόγο, αλλά δε βρήκα άλλο τρόπο).

Δοκίμασε με το gobject.timeout_add
http://www.pygtk.org/pygtk2reference/go ... imeout-add
http://bazaar.launchpad.net/~timekpr-ma ... ui.py#L169
Κώδικας: Επιλογή όλων
def statusmessage(self, widget, message):
msgid = self.statusbar.push(self.statusbarCID, strftime("%Y-%m-%d %H:%M:%S ") + message)
timeoutid = gobject.timeout_add(6000, self.statusrefresh, self, msgid)

Τα "self" και "msgid" είναι attributes για το self.statusrefresh
Κύπριος; Κόπιασε στο ubuntu-cy! ┃ Launchpad Debian Github
Οδηγός για νεοεισερχόμενους -- Αρχικές οδηγίες για αρχάριους χρήστες του Ubuntu

1 Γνώσεις Linux: Πολύ καλό ┃ Προγραμματισμού: Πολύ καλό ┃ Αγγλικών: Πολύ καλό
2 Ubuntu 12.10 quantal 3.5.0-21-generic 64bit (en_US.UTF-8, GNOME cinnamon2d), Ubuntu 3.5.0-19-generic, Windows 7
3 Intel Core2 Duo CPU E6550 2.33GHz ‖ RAM 5970 MiB ‖ MSI MS-7235
4 nVidia G73 [GeForce 7300 GT] [10de:0393] {nvidia}
5 eth0: Realtek RTL-8110SC/8169SC Gigabit Ethernet [10ec:8167] (rev 10)
Άβαταρ μέλους
medigeek
Freedom
Freedom
 
Δημοσιεύσεις: 5023
Εγγραφή: 24 Μάιος 2008, 14:49
Τοποθεσία: Σερβία/Κύπρος
Launchpad: medigeek
IRC: savvas
Εκτύπωση

Re: Glade + python : εμφάνιση spinner

Δημοσίευσηαπό parenthesis » 05 Οκτ 2011, 22:45

Ευχαριστώ για τις απαντήσεις, και συγγνώμη που άργησα να τα δω, προέκυψαν κάτι θέματα υγείας.
Διαπίστωσα ότι με κάποιες μικροαλλαγές στον κώδικα το spinner ξεκινάει κανονικά και ταυτόχρονα γίνεται και η αντιγραφή των αρχείων. Μόλις ολοκληρωθεί η αντιγραφή, τίθεται το killEvent. Το πρόβλημα τώρα είναι ότι αν επιχειρήσω να βάλω κάποια λούπα που να ελέγχει πότε τίθεται το killEvent ή αν βάλω killEvent.wait() το spinner παγώνει και πάλι..... :thumbdown:

Κώδικας: Επιλογή όλων

#! /usr/bin/env python

import pygtk
pygtk.require('2.0')
import gtk
import threading
import thread
from multiprocessing import Process, Event
import time

def copying () :
print("Copying...")
time.sleep(1)
print("Copying...")
time.sleep(1)
print("Copying...")
time.sleep(1)
print("Copying...")
time.sleep(1)

return True

class Synchronaiz() :

def __init__(self) :
builder = gtk.Builder()
builder.add_from_file("synchronaiz.glade")

self.mainwindow = builder.get_object("mainwindow")
self.donewindow = builder.get_object("donewindow")
self.statuslabel = builder.get_object("statuslabel")
self.spinner = builder.get_object("spinner")
builder.connect_signals(self)

def on_window_destroy(self, widget, data=None) :
gtk.main_quit()

def on_synchbutton_clicked(self, widget, data=None) :

def startSpinner(killEvent) :
self.statuslabel.set_text(u'Synching... It may take a few minutes.')
self.spinner.show()
self.spinner.start()
print("spinner running.")

def startCopying(event) :
isdone = False
isdone = copying()
print("copying returned.")
print(isdone)
if (isdone == True) :
event.set()
print("event set.")

def checkCopying(event, killEvent) :
print("checkCopying entered.")
event.wait()
print("Copying is done.")
killEvent.set()
print("killEvent set.")

event = Event()
event.clear()
killEvent = Event()
killEvent.clear()

t = Process(target=checkCopying, args=(event, killEvent))
t.start()

cop = Process(target=startCopying, args=(event, ))
cop.start()

spin = Process(target=startSpinner(killEvent), args=(killEvent, ))
spin.start()
spin.terminate()

## Do something to check if killEvent has been set.

if __name__ == '__main__' :
synch = Synchronaiz()
synch.mainwindow.show()
gtk.main()


Επίσης παραθέτω το αντίστοιχο glade αρχείο :

Spoiler: show
Κώδικας: Επιλογή όλων
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="2.24"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkDialog" id="donewindow">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Done!</property>
<property name="resizable">False</property>
<property name="window_position">center</property>
<property name="type_hint">dialog</property>
<signal name="destroy" handler="on_window_destroy" swapped="no"/>
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="dialog-action_area2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkButton" id="exbutton">
<property name="label">gtk-quit</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="border_width">8</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_window_destroy" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="donelabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Synching finished!</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
<action-widgets>
<action-widget response="0">exbutton</action-widget>
</action-widgets>
</object>
<object class="GtkWindow" id="mainwindow">
<property name="width_request">350</property>
<property name="height_request">200</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">Main Window</property>
<property name="resizable">False</property>
<property name="window_position">center</property>
<property name="urgency_hint">True</property>
<signal name="destroy" handler="on_window_destroy" swapped="no"/>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="statuslabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSpinner" id="spinner">
<property name="height_request">20</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">15</property>
<child>
<object class="GtkButton" id="synchbutton">
<property name="label" translatable="yes">Synch!</property>
<property name="height_request">10</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="border_width">25</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="on_synchbutton_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="exibutton">
<property name="label">gtk-quit</property>
<property name="height_request">10</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="border_width">25</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_window_destroy" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</interface>


@medigeek : το πρώτο λινκ δε μου ανοίγει, και στο δεύτερο δεν καταλαβαίνω τι γίνεται. βσκ, έψαξα για το gobject στον γούγλη, αλλά μπερδεύτηκα ακόμη περισσότερο. Νομίζω ότι μάλλον αυτό κάνει για την περίπτωσή μου, αλλά δεν μπορώ να καταλάβω πώς λειτουργεί. Μήπως θα μπορούσε να εξηγήσει κάποιος;;; :geek: :problem:
1 Γνώσεις Linux: Πρώτα βήματα ┃ Προγραμματισμού: Ικανοποιητικό ┃ Αγγλικών: Πολύ καλό
2 Dual boot:
  • Ubuntu 13.04 raring 3.8.0-34-generic 64bit (el_GR.UTF-8, Unity ubuntu), Ubuntu 3.8.0-19-generic
  • Fedora 19 Schrödinger’s Cat 3.13.5-101.fc19.x86_64 64bit (el_GR.utf8, gnome)
3 Intel Core i5-3337U CPU @ 1.80GHz ‖ RAM 3844 MiB ‖ TOSHIBA VCUAA - TOSHIBA SATELLITE U940
4 Intel 3rd Gen Core processor Graphics Controller [8086:0166] {i915}
5 eth0: Realtek RTL8101E/RTL8102E Ethernet [10ec:8136] (rev 05) ⋮ wlan0: Intel Centrino Wireless-N 2230 [8086:0887] (rev c4)
Άβαταρ μέλους
parenthesis
punkTUX
punkTUX
 
Δημοσιεύσεις: 150
Εγγραφή: 06 Οκτ 2009, 22:47
Launchpad: mara_sdr
Εκτύπωση

Re: Glade + python : εμφάνιση spinner

Δημοσίευσηαπό medigeek » 06 Οκτ 2011, 00:21

Ναι κι εμένα έχει προβληματα. Δοκίμασε το pygtk.org αργότερα...
Να ένα παράδειγμα:
Κώδικας: Επιλογή όλων
#!/usr/bin/python
import gtk
import gobject

def go(d):
print("Hello after %d seconds!" % d)

gobject.timeout_add(3000, go, 3)
gobject.timeout_add(6000, go, 6)
gobject.timeout_add(9000, gtk.main_quit)
print("test")
print("Let's pretend this is in a gtk.main() loop with an active window")
print("(gobject.timeout_add works only with gtk.main()")
gtk.main()
Κύπριος; Κόπιασε στο ubuntu-cy! ┃ Launchpad Debian Github
Οδηγός για νεοεισερχόμενους -- Αρχικές οδηγίες για αρχάριους χρήστες του Ubuntu

1 Γνώσεις Linux: Πολύ καλό ┃ Προγραμματισμού: Πολύ καλό ┃ Αγγλικών: Πολύ καλό
2 Ubuntu 12.10 quantal 3.5.0-21-generic 64bit (en_US.UTF-8, GNOME cinnamon2d), Ubuntu 3.5.0-19-generic, Windows 7
3 Intel Core2 Duo CPU E6550 2.33GHz ‖ RAM 5970 MiB ‖ MSI MS-7235
4 nVidia G73 [GeForce 7300 GT] [10de:0393] {nvidia}
5 eth0: Realtek RTL-8110SC/8169SC Gigabit Ethernet [10ec:8167] (rev 10)
Άβαταρ μέλους
medigeek
Freedom
Freedom
 
Δημοσιεύσεις: 5023
Εγγραφή: 24 Μάιος 2008, 14:49
Τοποθεσία: Σερβία/Κύπρος
Launchpad: medigeek
IRC: savvas
Εκτύπωση

Re: Glade + python : εμφάνιση spinner

Δημοσίευσηαπό parenthesis » 06 Οκτ 2011, 01:37

Χμ, δηλαδή αν κατάλαβα καλά, εννοείς να κάνω κάτι τέτοιο :

Κώδικας: Επιλογή όλων
#! /usr/bin/env python

import pygtk
pygtk.require('2.0')
import gtk
import threading
import thread
from multiprocessing import Process, Event
import time
import gobject

def copying () :
print("Copying...")
time.sleep(1)
print("Copying...")
time.sleep(1)
print("Copying...")
time.sleep(1)
print("Copying...")
time.sleep(1)

return True

class Synchronaiz() :

def __init__(self) :
builder = gtk.Builder()
builder.add_from_file("synchronaiz.glade")

self.mainwindow = builder.get_object("mainwindow")
self.donewindow = builder.get_object("donewindow")
self.statuslabel = builder.get_object("statuslabel")
self.spinner = builder.get_object("spinner")
builder.connect_signals(self)

def on_window_destroy(self, widget, data=None) :
gtk.main_quit()

def on_synchbutton_clicked(self, widget, data=None) :

def startSpinner() :
def Spin():
self.statuslabel.set_text(u'Synching... It may take a few minutes.')
self.spinner.show()
self.spinner.start()
print("spinner running.")

spin = Process(target=Spin(), args=())
spin.start()
spin.terminate()

def startCopying(event) :
def Cop(event):
isdone = False
isdone = testing()
print("testing returned.")
if (isdone == True) :
event.set()
print("event set.")

cop = Process(target=Cop, args=(event, ))
cop.start()

def endAll() :
self.mainwindow.hide()
self.donewindow.show()

def checkCopying(event, killEvent) :
def Check(event):
print("checkCopying entered.")
event.wait()
print("Copying is done.")
endAll()
print("killEvent set.")

t = Process(target=Check, args=(event, ))
t.start()

event = Event()
event.clear()
killEvent = Event()
killEvent.clear()

gobject.timeout_add(500, startSpinner)
gobject.timeout_add(600, startCopying, event)

gobject.timeout_add(700, checkCopying, event)

if __name__ == '__main__' :
synch = Synchronaiz()
synch.mainwindow.show()
gtk.main()


Φαίνεται να δουλεύει, αλλά προς το τέλος μου πετάει :
python: ../../src/xcb_io.c:221: poll_for_event: Ο ισχυρισμός (((long) (event_sequence) - (long) (dpy->request)) <= 0)' απέτυχε.
synchronaiz.py: Fatal IO error 11 (Ο πόρος είναι προσωρινά μη διαθέσιμος) on X server :0.0.
Ακυρώθηκε
1 Γνώσεις Linux: Πρώτα βήματα ┃ Προγραμματισμού: Ικανοποιητικό ┃ Αγγλικών: Πολύ καλό
2 Dual boot:
  • Ubuntu 13.04 raring 3.8.0-34-generic 64bit (el_GR.UTF-8, Unity ubuntu), Ubuntu 3.8.0-19-generic
  • Fedora 19 Schrödinger’s Cat 3.13.5-101.fc19.x86_64 64bit (el_GR.utf8, gnome)
3 Intel Core i5-3337U CPU @ 1.80GHz ‖ RAM 3844 MiB ‖ TOSHIBA VCUAA - TOSHIBA SATELLITE U940
4 Intel 3rd Gen Core processor Graphics Controller [8086:0166] {i915}
5 eth0: Realtek RTL8101E/RTL8102E Ethernet [10ec:8136] (rev 05) ⋮ wlan0: Intel Centrino Wireless-N 2230 [8086:0887] (rev c4)
Άβαταρ μέλους
parenthesis
punkTUX
punkTUX
 
Δημοσιεύσεις: 150
Εγγραφή: 06 Οκτ 2009, 22:47
Launchpad: mara_sdr
Εκτύπωση

Re: Glade + python : εμφάνιση spinner

Δημοσίευσηαπό medigeek » 06 Οκτ 2011, 10:05

Δεν έχω ιδέα από threads. Με τον τρόπο που σου έδειξα θα μπορούσες να εκτελέσεις το δύο εντολές χωρίς το multiprocessing.
Για το σφάλμα που σου βγάζει, έψαξα λίγο στο google και βρήκα αυτό:
http://stackoverflow.com/questions/3212 ... -clipboard
http://jameswestby.net/weblog/tech/14-c ... t-mix.html

Νομίζω ότι δεν μπορείς να χρησιμοποιήσεις gobject και multiprocessing μαζί. Μπορεί και να κάνω λάθος όμως.
Ίσως αυτά τα παραδείγματα να σε βοηθήσουν:
http://haltcondition.net/?p=2319
https://github.com/alex/election-sim
Κύπριος; Κόπιασε στο ubuntu-cy! ┃ Launchpad Debian Github
Οδηγός για νεοεισερχόμενους -- Αρχικές οδηγίες για αρχάριους χρήστες του Ubuntu

1 Γνώσεις Linux: Πολύ καλό ┃ Προγραμματισμού: Πολύ καλό ┃ Αγγλικών: Πολύ καλό
2 Ubuntu 12.10 quantal 3.5.0-21-generic 64bit (en_US.UTF-8, GNOME cinnamon2d), Ubuntu 3.5.0-19-generic, Windows 7
3 Intel Core2 Duo CPU E6550 2.33GHz ‖ RAM 5970 MiB ‖ MSI MS-7235
4 nVidia G73 [GeForce 7300 GT] [10de:0393] {nvidia}
5 eth0: Realtek RTL-8110SC/8169SC Gigabit Ethernet [10ec:8167] (rev 10)
Άβαταρ μέλους
medigeek
Freedom
Freedom
 
Δημοσιεύσεις: 5023
Εγγραφή: 24 Μάιος 2008, 14:49
Τοποθεσία: Σερβία/Κύπρος
Launchpad: medigeek
IRC: savvas
Εκτύπωση

Re: Glade + python : εμφάνιση spinner

Δημοσίευσηαπό parenthesis » 07 Οκτ 2011, 19:18

Λοιπόν, μετά από άπειρες προσπάθειες, τα αποτελέσματα ήταν τα εξής :
όταν χρησιμοποιώ μόνο gobject.timeout_add(), το σπίνερ ξεκινάει, αλλά μόλις ξεκινήσει και η copying() παγώνει...
όταν μπλέκω gobject.timeout_add() με multiprocessing, δουλεύει αλλά μου βγάζει το error που πόσταρα παραπάνω, και κρεμάει...
γενικά, ό,τι άλλες αλχημείες έχω κάνει δεν απέδωσαν καρπούς.

Στην τελική, παραιτήθηκα από το σπίνερ και πλέον εμφανίζω ένα μνμ "Παρακαλώ περιμένετε", γιατί δεν πάει άλλο.... :thumbdown:
Αλλά, αν κάποιος καταφέρει να βρει λύση, ας την ποστάρει εδώ γιατί πραγματικά με έχει φάει η περιέργεια....
1 Γνώσεις Linux: Πρώτα βήματα ┃ Προγραμματισμού: Ικανοποιητικό ┃ Αγγλικών: Πολύ καλό
2 Dual boot:
  • Ubuntu 13.04 raring 3.8.0-34-generic 64bit (el_GR.UTF-8, Unity ubuntu), Ubuntu 3.8.0-19-generic
  • Fedora 19 Schrödinger’s Cat 3.13.5-101.fc19.x86_64 64bit (el_GR.utf8, gnome)
3 Intel Core i5-3337U CPU @ 1.80GHz ‖ RAM 3844 MiB ‖ TOSHIBA VCUAA - TOSHIBA SATELLITE U940
4 Intel 3rd Gen Core processor Graphics Controller [8086:0166] {i915}
5 eth0: Realtek RTL8101E/RTL8102E Ethernet [10ec:8136] (rev 05) ⋮ wlan0: Intel Centrino Wireless-N 2230 [8086:0887] (rev c4)
Άβαταρ μέλους
parenthesis
punkTUX
punkTUX
 
Δημοσιεύσεις: 150
Εγγραφή: 06 Οκτ 2009, 22:47
Launchpad: mara_sdr
Εκτύπωση

Re: Glade + python : εμφάνιση spinner

Δημοσίευσηαπό Phantomas » 22 Οκτ 2011, 03:00

Νομίζω ότι το προσεγγίζεις πάρα πολύ πολύπλοκα, χωρίς λόγο... Πρέπει να έχεις μια αγάπη προς τις συναρτήσεις, τις χρησιμοποιείς σε σημεία που δεν χρειάζονται καν! Δεν ξέρω τι ακριβώς κάνει η copying() σου, αφού μας την "έκρυψες" :) αλλά αν κατάλαβα καλά πρέπει να επιστρέφει True όταν έχει πετύχει η αντιγραφή και False όταν αυτή αποτυγχάνει, ίσως αν αντικαταστήσεις όλη την on_synchbutton_clicked με κάτι σαν το παρακάτω, να παίζει όπως θες...

Κώδικας: Επιλογή όλων
def on_synchbutton_clicked(self, widget, data=None):

self.statuslabel.set_text(u'Synching... It may take a few minutes.')
self.spinner.show()
self.spinner.start()

# Start Copying
result = copying()
if result is True:
print("Copying is done.")
# More action to do when copying succeeds
else:
print("Error.")
# More action to do when copying has failed

print("Telos.")
self.spinner.stop()


Απλά να θυμάσαι ότι καλές οι συναρτήσεις (όχι όμως αυτό που είχες κάνει με συνάρτηση μέσα σε συνάρτηση μέσα σε συνάρτηση) αλλά όταν κάτι γίνεται με απλές εντολές στη σειρά, το προτιμάς, γενικά! Το multi-threading εδώ πέρα δεν χρειάζεται καθόλου, ΔΕΝ κάνεις 2 πράγματα παράλληλα... αυτό που θες να κάνεις μόλις ο χρήστης πατήσει το κλικ είναι:
1) Να εμφανίσεις το spinner
2) Να το ξεκινήσεις
3) Να κάνεις την αντιγραφή (με τη συνάρτηση copying απ' ό,τι κατάλαβα) και να πάρεις το αποτέλεσμα από τη return της
4) Να εκμεταλλευτείς το αποτέλεσμα της copying και να εμφανίσεις το αντίστοιχο μήνυμα (πέτυχε/δεν πέτυχε) ή/και να κάνεις άλλες ενέργειες που θες
5) Να σταματήσεις το spinner (ίσως και να το κρύψεις με self.spinner.hide())

Εσύ μάλλον προσπαθούσες να τα κάνεις όλα αυτά τα βήματα παράλληλα σε 1... αλλά ο υπολογιστής είναι πολύ πιο γρήγορος από ότι ίσως υπέθετες, οπότε μεταξύ βήματος 2 και 3 π.χ. ο χρόνος είναι πραγματικά μηδενικός! :)
Άβαταρ μέλους
Phantomas
punkTUX
punkTUX
 
Δημοσιεύσεις: 156
Εγγραφή: 28 Ιούλ 2008, 15:57
IRC: Phantomas
Εκτύπωση

Re: Glade + python : εμφάνιση spinner

Δημοσίευσηαπό parenthesis » 22 Οκτ 2011, 15:10

Phantomas έγραψε:
Spoiler: show
Νομίζω ότι το προσεγγίζεις πάρα πολύ πολύπλοκα, χωρίς λόγο... Πρέπει να έχεις μια αγάπη προς τις συναρτήσεις, τις χρησιμοποιείς σε σημεία που δεν χρειάζονται καν! Δεν ξέρω τι ακριβώς κάνει η copying() σου, αφού μας την "έκρυψες" :) αλλά αν κατάλαβα καλά πρέπει να επιστρέφει True όταν έχει πετύχει η αντιγραφή και False όταν αυτή αποτυγχάνει, ίσως αν αντικαταστήσεις όλη την on_synchbutton_clicked με κάτι σαν το παρακάτω, να παίζει όπως θες...

Κώδικας: Επιλογή όλων
def on_synchbutton_clicked(self, widget, data=None):

self.statuslabel.set_text(u'Synching... It may take a few minutes.')
self.spinner.show()
self.spinner.start()

# Start Copying
result = copying()
if result is True:
print("Copying is done.")
# More action to do when copying succeeds
else:
print("Error.")
# More action to do when copying has failed

print("Telos.")
self.spinner.stop()


Απλά να θυμάσαι ότι καλές οι συναρτήσεις (όχι όμως αυτό που είχες κάνει με συνάρτηση μέσα σε συνάρτηση μέσα σε συνάρτηση) αλλά όταν κάτι γίνεται με απλές εντολές στη σειρά, το προτιμάς, γενικά! Το multi-threading εδώ πέρα δεν χρειάζεται καθόλου, ΔΕΝ κάνεις 2 πράγματα παράλληλα... αυτό που θες να κάνεις μόλις ο χρήστης πατήσει το κλικ είναι:
1) Να εμφανίσεις το spinner
2) Να το ξεκινήσεις
3) Να κάνεις την αντιγραφή (με τη συνάρτηση copying απ' ό,τι κατάλαβα) και να πάρεις το αποτέλεσμα από τη return της
4) Να εκμεταλλευτείς το αποτέλεσμα της copying και να εμφανίσεις το αντίστοιχο μήνυμα (πέτυχε/δεν πέτυχε) ή/και να κάνεις άλλες ενέργειες που θες
5) Να σταματήσεις το spinner (ίσως και να το κρύψεις με self.spinner.hide())

Εσύ μάλλον προσπαθούσες να τα κάνεις όλα αυτά τα βήματα παράλληλα σε 1... αλλά ο υπολογιστής είναι πολύ πιο γρήγορος από ότι ίσως υπέθετες, οπότε μεταξύ βήματος 2 και 3 π.χ. ο χρόνος είναι πραγματικά μηδενικός! :)


Σαφώς και έτσι ξεκίνησα αρχικά να το κάνω, αφού ούτως ή άλλως δεν είχα ιδέα από multithreading και λοιπά, αλλά δεν πιάνει! Αν το κάνω έτσι όπως λες, αρχίζει να τρέχει η copying(), και το spinner εμφανίζεται αφού αυτή τελειώσει! Δεν ξέρω γιατί συμβαίνει αυτό, και μετά υπέθεσα ότι μάλλον πρέπει με κάποιο τρόπο να τα "εξαναγκάσω" να τρέξουν με τη σειρά που θέλω...
Εκτός κι αν πάλι κάνω καμιά πατάτα, εσύ το έτρεξες έτσι και δούλεψε; :problem:

btw, το πρόγραμμα αυτή τη στιγμή χωρίς spinner είναι κάπως έτσι (τώρα που ξαναβλέπω τι είχα γράψει, όντως, το παράκανα με τις συναρτήσεις! :P ) :
Κώδικας: Επιλογή όλων
#! /usr/bin/env python

import pygtk
pygtk.require('2.0')
import gtk
import threading
import thread
from multiprocessing import Process, Event
import time
import gobject

def copying () :
print("Copying...")
time.sleep(1)
print("Copying...")
time.sleep(1)
print("Copying...")
time.sleep(1)
print("Copying...")
time.sleep(1)

return True

class Synchronaiz() :

def __init__(self) :
builder = gtk.Builder()
builder.add_from_file("synchronaiz.glade")

self.mainwindow = builder.get_object("mainwindow")
self.donewindow = builder.get_object("donewindow")
self.statuslabel = builder.get_object("statuslabel")
self.spinner = builder.get_object("spinner")
builder.connect_signals(self)

def on_window_destroy(self, widget, data=None) :
gtk.main_quit()

def on_synchbutton_clicked(self, widget, data=None) :

def setLabel() :
self.statuslabel.set_text(u'Synching... It may take a few minutes.')

def start_copying() :
isdone = False
isdone = copying()
if (isdone == True) :
self.statuslabel.set_text(u'')
self.mainwindow.hide()
self.donewindow.show()

gobject.timeout_add(100, setLabel)
gobject.timeout_add(200, startCopying, sourcef, destf)

if __name__ == '__main__' :
synch = Synchronaiz()
synch.mainwindow.show()
gtk.main()
1 Γνώσεις Linux: Πρώτα βήματα ┃ Προγραμματισμού: Ικανοποιητικό ┃ Αγγλικών: Πολύ καλό
2 Dual boot:
  • Ubuntu 13.04 raring 3.8.0-34-generic 64bit (el_GR.UTF-8, Unity ubuntu), Ubuntu 3.8.0-19-generic
  • Fedora 19 Schrödinger’s Cat 3.13.5-101.fc19.x86_64 64bit (el_GR.utf8, gnome)
3 Intel Core i5-3337U CPU @ 1.80GHz ‖ RAM 3844 MiB ‖ TOSHIBA VCUAA - TOSHIBA SATELLITE U940
4 Intel 3rd Gen Core processor Graphics Controller [8086:0166] {i915}
5 eth0: Realtek RTL8101E/RTL8102E Ethernet [10ec:8136] (rev 05) ⋮ wlan0: Intel Centrino Wireless-N 2230 [8086:0887] (rev c4)
Άβαταρ μέλους
parenthesis
punkTUX
punkTUX
 
Δημοσιεύσεις: 150
Εγγραφή: 06 Οκτ 2009, 22:47
Launchpad: mara_sdr
Εκτύπωση

Επόμενο

Επιστροφή στο Ανάπτυξη Λογισμικού / Αλγόριθμοι