#1 Le 10/10/2013, à 07:56
- k3c
conseils pour une petite application graphique
Ave
J'ai écrit un petit programme graphique avec 3 boutons qui enrobe la récupération de vidéos de la BBC avec get_iplayer.
J'ai utilisé Tkinter, c'est moche et ça marche.
Que me conseillez-vous ?
Pyqt, WxPython...
Merci pour vos lumières/ idées d'amélioration
Si vous voulez tester, installez get_iplayer, rentrez par exemple
Wrong Mans
puis cliquer sur Film
cela va vous proposer les épisodes 1, 2, et 3
vous en sélectionnez un, puis cliquez sur download
et vous aurez une vidéo et un fichier de sous-titres, du même nom.
le code du programme graphique
#!/usr/bin/python
#-*- coding:utf-8 -*-
#
import os
import os.path
import posixpath
import shutil
import re
import StringIO
import ConfigParser
import subprocess
from threading import Thread
try:
from tkinter import *
except:
from Tkinter import *
from ScrolledText import ScrolledText
import tkMessageBox
from tkColorChooser import askcolor
import tkFileDialog
import distutils.dir_util
from Queue import Queue, Empty
ON_POSIX = 'posix' in sys.builtin_module_names
Finished = False
thread1 = None
force = None
root = None
process = None
queue = Queue()
def start_thread(func, *args):
t = Thread(target=func, args=args)
t.daemon = True
t.start()
return t
def consume(infile):
for line in iter(infile.readline, ''):
queue.put(line)
infile.close()
def callback1():
global dirfilms, lsb, thread1, txt
# print 'callback1', dirfilms.get()
lsb.delete(0, END)
args = ["get_iplayer", dirfilms.get()]
app = subprocess.Popen(args=args, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
(stdout, stderr) = app.communicate()
if app.returncode == 1: # sortie en erreur →
txt.insert(END, 'get_iplayer fail\n')
else:
lines = stdout.split('\n')
for line in lines:
txt.insert(END, line + '\n')
lines = lines[6:-3]
n = 0
for line in lines:
line = line.replace('\t', ' ')
if line.startswith('...'): continue
line = line.replace('Added: ','')
n += 1
lsb.insert(END, line)
txt.insert(END, 'get_iplayed success, %s founds\n' % (n,))
def callback3():
global lsb, process
sel = lsb.curselection()
sel = None if len(sel) == 0 else sel[0]
# print 'callback3', sel,
if sel:
# print lsb.get(sel)
# print 'force=', force.get()
args = ["python", "/home/gg/bbc33.py", lsb.get(sel).split(':')[0], str(force.get())]
process = subprocess.Popen(args=args, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, close_fds=ON_POSIX)
thread1 = start_thread(consume, process.stdout)
# thread1.join() # wait for IO completion
# if app.returncode == 1: # sortie en erreur →
# print 'ko'
# else:
# print 'ok', stdout
else:
print
def on_delete():
global root, process
if process:
process.kill()
print "sortie du programme"
root.destroy()
def on_after():
global queue, txt, root
while True:
try:
v = queue.get_nowait()
except Empty:
break;
txt.insert(END, v)
root.after(200, on_after)
root = Tk()
bt1 = Button(root, text='Films', command=callback1)
dirfilms = StringVar()
Entry(root, textvariable=dirfilms, width=100).pack()
bt1.pack()
fr = Frame(root)
scrollbar = Scrollbar(fr)
scrollbar.pack(side=RIGHT, fill=Y)
lsb = Listbox(fr)
lsb.pack(fill=X)
fr.pack(fill=X)
# attach listbox to scrollbar
lsb.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=lsb.yview)
fr = Frame()
bt2 = Button(fr, text='Download', command=callback3)
bt2.pack(side=LEFT)
force = IntVar()
force.set(0)
Checkbutton(fr, text="Force", variable=force).pack(side=LEFT)
fr.pack()
txt=ScrolledText(root, width=100,height=50)
txt.pack(fill=X)
root.wm_protocol ("WM_DELETE_WINDOW", on_delete)
root.after(1000, on_after)
root.mainloop()
Le code du script Python appelé
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# bbc_proxy version 0.2 par k3c, sortie quand deja telecharge
# passage de proxy en 2 ème parametre
import subprocess, sys, shlex
import random
import urllib2
import bs4 as BeautifulSoup
import socket
from threading import Thread
ON_POSIX = 'posix' in sys.builtin_module_names
Finished = False
listeUserAgents = [ 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_5; fr-fr) AppleWebKit/525.18 (KHTML, like Gecko) Version/3.1.2 Safari/525.20.1',
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.186 Safari/535.1',
'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13\
',
'Mozilla/5.0 (X11; U; Linux x86_64; en-us) AppleWebKit/528.5+ (KHTML, like Gecko, Safari/528.5+) midori',
'Mozilla/5.0 (Windows NT 6.0) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.107 Safari/535.1',
'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/312.1 (KHTML, like Gecko) Safari/312',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.12 Safari/535.11',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.8 (KHTML, like Gecko) Chrome/17.0.940.0 Safari/535.8' ]
allTimeouts = (3, 10, 15, 20)
class FlushFile(object):
"""Write-only flushing wrapper for file-type objects."""
def __init__(self, f):
self.f = f
def write(self, x):
self.f.write(x)
self.f.flush()
def start_thread(func, *args):
t = Thread(target=func, args=args)
t.daemon = True
t.start()
return t
def consume(infile):
global Finished
for line in iter(infile.readline, ''):
if 'Finished writing to temp file.' in line:
Finished = True
if 'Already in history' in line:
Finished = True
print line,
infile.close()
def getProxy():
opener = urllib2.build_opener()
opener.addheaders = [('User-agent', random.choice(listeUserAgents))]
data = opener.open('http://free-proxy-list.net/uk-proxy.html').read()
opener.close()
soup = BeautifulSoup.BeautifulSoup(data)
lst = []
for tr in soup.tbody.findAll('tr'):
i = 0
slst = []
for td in tr.find_all('td'):
i += 1
if i in (1, 2, 5):
slst.append(td.contents[0])
elif i == 8:
i = 0
lst.append(slst)
slst = []
for href in lst:
yield href
def getValidProxy():
for timeout in allTimeouts:
print 'Timeout =', timeout
socket.setdefaulttimeout(timeout)
for host, port, typeproxy in getProxy():
try:
print 'Trying %s:%s' % (host, port)
params = (host, int(port))
# buffer_size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(params)
s.close()
yield host, port, typeproxy
# except urllib2.URLError:
# pass
except socket.timeout:
pass
except socket.error:
pass
def main():
global Finished
# Replace stdout with an automatically flushing version
sys.stdout = FlushFile(sys.__stdout__)
idvideo = sys.argv[1]
for host, port, typeproxy in getValidProxy():
print host, port, typeproxy
if len(sys.argv) > 1 and sys.argv[2] == '1':
cmds = "get_iplayer --get "+idvideo + " --subtitles --force -p 'http://"+host+":"+port+"'"
else:
cmds = "get_iplayer --get "+idvideo + " --subtitles -p 'http://"+host+":"+port+"'"
arguments = shlex.split(cmds)
print cmds
Finished = False
process = subprocess.Popen(arguments, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
thread1 = start_thread(consume, process.stdout)
thread2 = start_thread(consume, process.stderr)
thread1.join() # wait for IO completion
thread2.join() # wait for IO completion
retcode = process.wait()
print retcode
if Finished:
break
if __name__ == "__main__":
main()
Debian 12 sur Thinkpad reconditionné
Hors ligne
#2 Le 10/10/2013, à 16:59
- k3c
Re : conseils pour une petite application graphique
Nouvelle version de la partie graphique
#!/usr/bin/python
#-*- coding:utf-8 -*-
#
import os
import os.path
import posixpath
import shutil
import re
import StringIO
import ConfigParser
import subprocess
from threading import Thread
try:
from tkinter import *
except:
from Tkinter import *
from ScrolledText import ScrolledText
import tkMessageBox
from tkColorChooser import askcolor
import tkFileDialog
import distutils.dir_util
from Queue import Queue, Empty
ON_POSIX = 'posix' in sys.builtin_module_names
Finished = False
thread1 = None
force = None
root = None
process = None
queue = Queue()
manager = None
txt = None
df = None
def busy():
global manager, df
txt.config(cursor="watch")
df.config(cursor="watch")
root.config(cursor="watch")
def notbusy():
global manager, df
txt.config(cursor="")
df.config(cursor="")
root.config(cursor="")
def start_thread(func, *args):
t = Thread(target=func, args=args)
t.daemon = True
t.start()
return t
def consume(infile):
for line in iter(infile.readline, ''):
queue.put(line)
infile.close()
def callback0():
global dirfilms, lsb, thread1, txt
# print 'callback1', dirfilms.get()
lsb.delete(0, END)
txt.delete(1.0, END)
args = ["get_iplayer", dirfilms.get()]
if refresh.get():
args.append('-f')
app = subprocess.Popen(args=args, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
(stdout, stderr) = app.communicate()
notbusy()
if app.returncode == 1: # sortie en erreur →
txt.insert(END, 'get_iplayer fail\n')
else:
lines = stdout.split('\n')
for line in lines:
txt.insert(END, line + '\n')
n = 1
for line in lines:
if line.startswith('Matches:'):
break
n += 1
lines = lines[n:-3] if n <= len(lines) else []
n = 0
for line in lines:
line = line.replace('\t', ' ')
line = line.replace('Added: ','')
n += 1
lsb.insert(END, line)
txt.insert(END, 'get_iplayed success, %s founds\n' % (n,))
def callback1():
global root
busy()
root.after_idle(callback0)
def callback3():
global lsb, process
sel = lsb.curselection()
sel = None if len(sel) == 0 else sel[0]
# print 'callback3', sel,
if sel:
# print lsb.get(sel)
# print 'force=', force.get()
args = ["python", "/home/gg/bbc33.py", lsb.get(sel).split(':')[0], str(force.get())]
process = subprocess.Popen(args=args, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, close_fds=ON_POSIX)
thread1 = start_thread(consume, process.stdout)
# thread1.join() # wait for IO completion
# if app.returncode == 1: # sortie en erreur →
# print 'ko'
# else:
# print 'ok', stdout
else:
print
def on_delete():
global root, process
if process:
process.kill()
print "sortie du programme"
root.destroy()
def on_after():
global queue, txt, root
while True:
try:
v = queue.get_nowait()
except Empty:
break;
txt.insert(END, v)
root.after(200, on_after)
root = Tk(root)
fr = Frame()
bt1 = Button(fr, text='Films/Séries', command=callback1)
dirfilms = StringVar()
refresh = IntVar()
refresh.set(0)
df = Entry(fr, textvariable=dirfilms, width=100)
df.pack(side=LEFT)
bt1.pack(side=LEFT)
Checkbutton(fr, text="refresh du cache de la BBC", variable=refresh).pack(side=LEFT)
fr.pack()
fr = Frame(root)
scrollbar = Scrollbar(fr)
scrollbar.pack(side=RIGHT, fill=Y)
lsb = Listbox(fr)
lsb.pack(fill=X)
fr.pack(fill=X)
# attach listbox to scrollbar
lsb.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=lsb.yview)
fr = Frame(root)
bt2 = Button(fr, text='Download', command=callback3)
bt2.pack(side=LEFT)
force = IntVar()
force.set(0)
Checkbutton(fr, text="Force", variable=force).pack(side=LEFT)
fr.pack()
fr = Frame(root)
txt = ScrolledText(fr, width=100,height=50)
txt.pack(fill=X)
fr.pack(fill=X)
root.wm_protocol ("WM_DELETE_WINDOW", on_delete)
root.after(1000, on_after)
root.mainloop()
Debian 12 sur Thinkpad reconditionné
Hors ligne
#3 Le 11/10/2013, à 08:34
- LapiGNU
Re : conseils pour une petite application graphique
Salut,
je ne sais pas à quoi ressemble ton appli, mais si tu veux quelque chose qui ressemble à tes applis GTK, je te suggère gtkdialog ; pour voir à quoi ça ressemble côté visuel et côté code (dans du bash, en l'occurence) : http://puppy2.org/slaxer/Porteus/Gtkdia … color.html
Hoplà !
PS: tu bootes quoi sur clé USB dans ton Ebox ? Perso, j'ai mis un dur 2"5 dans le mien, ça ouvre pas mal de perspectives ! (bon, là mon dur est mort ...)
frenchKISS sur www.tchitcha.info, Ubuntu clé en main pour les réseaux de postes de travail.
et surtout : Sauvez les arbres, mangez des castors. Sauvez les castors, ne mangez pas d'arbres !
Hors ligne
#4 Le 11/10/2013, à 12:19
- k3c
Re : conseils pour une petite application graphique
Je vais regarder GTKDialog, merci.
J'ai essayé plusieurs OS, j'ai préféré Toutou Linux (variante française de Puppy Linux).
Sinon DSL (Damn Small Linux) est très bien aussi.
Debian 12 sur Thinkpad reconditionné
Hors ligne