2010-03-22 21 views
20

Sono nuovo di Python e sto iniziando a insegnare a me stesso di programmazione GUI (si spera) utilizzando PyQT4.7 e Python 2.6Utilizzando QtDesigner con PyQT e Python 2.6

Ho appena scaricato l'intero pacchetto PyQT/QT4 (compresi QtDesigner) dal sito Web PyQT, tuttavia sembra che QTDesigner, che sembra incredibile da utilizzare come newbie (dato che è possibile visualizzare tutti gli attributi/proprietà/valori predefiniti ecc.) di ciascun widget e modificare visivamente le proprietà è ottimo, ma PyQT sembra non impostare QTDesigner per l'integrazione diretta con PyQT e PyQTs script di generazione del codice Python:

ad esempio: premendo "Visualizza codice", tenta di eseguire lo script Designer-> C++ denominato (uic) anziché lo script pyuic.py, ecc.

C'è un modo per far sì che QTDesigner si integri strettamente con PyQT per la generazione di codice al volo come fa con C++?

In caso contrario, significa che devo codificare l'intera interfaccia QT all'interno del mio IDE Python e cercare tutta la documentazione e il codice boilerplate per ogni widget? (sembra molto inefficiente e poco elegante rispetto alla semplice integrazione con QTDesigner + Python).

Qual è il flusso di produzione di toolchain // usuale con Designer con PyQT? (Se non è possibile l'integrazione diretta - gli utenti python + pyQT saltano semplicemente usando QTDesigner tutti insieme e scrivono manualmente tutto il codice della GUI QT in python?)

Sarebbero graditi ulteriori suggerimenti/suggerimenti per un principiante PyQT. Grazie!

ps So che un sacco di voi probabilmente mi diranno di succhiarlo e di codificare tutta l'interfaccia utente QT a mano, ma se uso Designer durante l'apprendimento come richiesto sopra, si prega di fornire un modo per farlo Posso imparare più facilmente, grazie!

risposta

20

Ho iniziato a scrivere la mia prima applicazione PyQT (PyQT è usato solo per gestire GUI), e sembra che la buona toolchain sia: QtDesigner per generare .ui s e gestire le risorse e alcuni IDE, che possono impostare QtDesigner da modificare quelli. Uso Eclipse, perché è altamente personalizzabile. È possibile compilare il .qrc e .ui dalla domanda facendo un po 'come questo a inizio applicazione o alla messa a punto, o in qualsiasi altro momento:

os.system("pyrcc4.exe -o ui/images_rc.py ui/images/images.qrc") 
uic.compileUiDir(appDir + '/ui', True) 

e quindi utilizzando classi generate in questo modo:

class MyMainWindow(QtGui.QMainWindow): 

    def __init__(self, owner): 
     QtGui.QMainWindow.__init__(self) 
     # 'Ui_MyMainWindow' is the class, that was generated by uic, 
     # naming convention is: 'Ui_' plus the name of root widget in designer 
     self.ui = Ui_MyMainWindow() 
     self.ui.setupUi(self) 

oppure caricare direttamente .ui quando il contenitore inits:

QtGui.QMainWindow.__init__(self) 
    self.ui = None 
    uic.loadUi('MyMainWindowUI.ui', self.ui) 
    #now you have the instance of Ui_MyMainWindow in self.ui too, as above 

nota, che ho aggiunto UI suffisso al .ui nome del file, è stato fatto per evitare nome incrocio, causa nome di file .py, generato da uic, non è un nome di classe che inizia con 'Ui_', ma solo quello di root.

E un altro nota: alla fine del file generato posti UIC 'importazione% .qrc nome% _rc' (di default è di importazione images_rc) stringa, quindi è necessario consapevoli quando si utilizza questo pyrcc4.

L'intero approccio è abbastanza flessibile, ci vuole tutto il lavoro di codifica ui finto da voi; ma è comunque possibile eseguire alcune regolazioni fini nell'attributo MyMainWindow.ui, dove risiede l'istanza di Ui_MyMainWindow; ed evita l'ereditarietà non necessaria. Personalmente, creo i metodi _connectSlots e _initIntefrace in MyMainWindow per fare in modo che alcuni designer non possano farlo.

Ancora devo notare che scrivere codice di interfaccia da solo è un buon approccio, perché il codice, generato da uic, è UGLY. Preferisco caricare .ui in posizione di loadUi() a causa di questo :) E se hai molti controlli PyQT personalizzati, è così booorante portarli in QtDesigner ..

1

È possibile eseguire pyuic (o meglio pyuic4) da mano, nella console. Puoi creare la GUI usando designer con Python, proprio come faresti con C++.

A proposito: ho scritto tutta la roba della GUI per la mia app (10k di codice) a mano. Non mi piacciono i progettisti GUI e lavorare con il codice generato, quando è necessario modificare qualcosa.

0

QtDesigner utilizza uic.exe per generare sul vola codice C++. uic.exe è uno strumento da riga di comando, ottiene i nomi dei file come parametri di input. Per l'integrazione con python, è possibile scrivere un programma python che utilizza pyuic.py, corrispondere agli input con l'input uic.exe (ordine, switch ecc.), Convertirlo in un eseguibile (utilizzando py2exe) e rinominare l'eseguibile in uic.exe. quindi sostituirlo con uic.exe nella directory bin di Qt (uic.exe non esiste in PyQt come so). Dovresti solo fare attenzione sugli argomenti di input di uic.exe e sulla tua macro scritta a mano (dovrebbero corrispondere insieme).

Penso che il tuo programma dovrà conoscere il percorso di python (per poter usare pyuic). se si utilizza Windows, è possibile ottenere il percorso dal registro.

2

Quello che ho fatto è stato il mio eseguibile uic che è un wrapper per lo script pyuic.py.

Avrete bisogno ...

  1. prendere ed installare py2exe

  2. Sostituire PYTHON_PATH nel codice uic.py sotto

  3. Modificare il file qt.conf nella site-packages \ PyQt4 e set Binaries = Percorso alla cartella contenente uic exe una volta creato.

  4. Put uic.py e setup.py nella stessa cartella

  5. Nel prompt dei comandi per navigare alla cartella in cui setup.py e uic.py vengono quindi eseguire il seguente comando "python setup.py py2exe".

//----uic.py

#uic.py 
import subprocess 
import sys 

args = "" 

for arg in sys.argv: 
    if sys.argv[0] != arg: 
     args += arg + " " 


# Start pyuic.py script 
command = 'python %PYTHON_PATH%\\PyQt4\\uic\\pyuic.py '+ args 
out = '' 


child = subprocess.Popen(command, shell=True, stderr=subprocess.PIPE) 
complete = False 
while True: 
    out = child.stderr.read(1) 
    if out == '' and child.poll() != None: 
     break 
    if out != '': 
     sys.stdout.write(out) 
     sys.stdout.flush() 

// ----- setup.py

#setup.py  
from distutils.core import setup 
import py2exe 

setup(windows=[{"script":"uic.py"}], options={"py2exe" : {"includes" : ["sip", "PyQt4.QtCore"]}})