La FAQ PyQt & PySide
La FAQ PyQt & PySideConsultez toutes les FAQ
Nombre d'auteurs : 4, nombre de questions : 38, dernière mise à jour : 29 août 2021
- Comment se connecter à un serveur FTP ?
- Comment faire un téléversement sur un serveur FTP ?
- Comment faire un téléchargement depuis un serveur FTP ?
- Comment naviguer dans l'arborescence d'un serveur FTP et l'afficher ?
- Comment lister le contenu d'un répertoire FTP ?
- Comment suivre la progression du téléversement ou télchargement d'un fichier depuis ou sur un serveur FTP ?
- Comment créer un dossier sur un serveur FTP ?
PyQt et PySide possèdent le module QtNetwork et plus précisément la classe QFtp qui permet de se connecter à un serveur ftp distant en utilisant la fonction connectToHost(serveur[, port]), de s'identifier avec la fonction login(user, password) et de s'y déconnecter avec la fonction close().
À noter que le signal stateChanged() est émis en fonction du changement d'état du serveur.
# -*- coding: iso-8859-1 -*-
#Code pour Python3. Pour Python2, enlever les parenthèses après les print.
import
sys
from
PyQt4 import
QtGui, QtNetwork
h =
50
l =
220
etat =
{0
:"Aucune connexion"
, 1
:"Résolution du nom en cours"
, 2
:"Tentative de connexion en cours"
,
3
:"Connexion établie"
, 4
:"Identification établie"
, 5
:"Déconnexion en cours"
}
class
Frame
(
QtGui.QMainWindow):
def
__init__
(
self, parent=
None
):
QtGui.QMainWindow.__init__
(
self, parent)
self.resize
(
l,h)
self.setFont
(
QtGui.QFont
(
"Verdana"
,8
))
self.btn =
QtGui.QPushButton
(
"Se connecter"
, self)
self.btn.move
(
10
, 10
)
self.btn1 =
QtGui.QPushButton
(
"Se déconnecter"
, self)
self.btn1.move
(
110
, 10
)
self.ftp =
QtNetwork.QFtp
(
self)
self.btn.clicked.connect
(
self.actionCo)
self.ftp.stateChanged.connect
(
self.stateServer)
self.btn1.clicked.connect
(
self.actionDeco)
def
actionCo
(
self):
if
self.ftp.state
(
) !=
0
:
print
(
'Serveur en cours de connexion ou connecté'
)
else
:
print
(
'Début de connexion'
)
self.ftp.connectToHost
(
'developpez.com'
)
self.ftp.login
(
'ceg'
, 'motdepasse'
)
def
actionDeco
(
self):
if
self.ftp.state
(
) ==
0
:
print
(
'Serveur non connecté'
)
else
:
self.ftp.close
(
)
def
stateServer
(
self):
print
(
etat[self.ftp.state
(
)])
print
(
)
app =
QtGui.QApplication
(
sys.argv)
frame =
Frame
(
)
frame.show
(
)
sys.exit
(
app.exec_
(
))
Lien : Documentation Qt de QFtp
Lien : Documentation PySide de QFtp
La fonction put() de la classe QtNetwork.QFtp permet de faire des téléversements de fichiers, c'est à dire d'envoyer un fichier à un serveur. Pour cela, il est nécessaire d'indiquer au moins à la fonction put(), le fichier à charger et la destination sur le serveur. Ce fichier à charger doit être avant tout ouvert en lecture uniquement.
# -*- coding: iso-8859-1 -*-
#Code pour Python3. Pour Python2 enlever les parenthèse après les print.
import
sys
from
PyQt4 import
QtGui, QtNetwork, QtCore
h =
150
l =
220
etat =
{0
:"Aucune connexion"
, 1
:"Résolution du nom en cours"
, 2
:"Tentative de connexion en cours"
,
3
:"Connexion établie"
, 4
:"Identification établie"
, 5
:"Déconnexion en cours"
}
class
Frame
(
QtGui.QMainWindow):
def
__init__
(
self, parent=
None
):
QtGui.QMainWindow.__init__
(
self, parent)
self.resize
(
l,h)
self.setFont
(
QtGui.QFont
(
"Verdana"
,8
))
self.btn =
QtGui.QPushButton
(
"Se connecter"
, self)
self.btn.move
(
10
, 10
)
self.btn1 =
QtGui.QPushButton
(
"Se déconnecter"
, self)
self.btn1.move
(
110
, 10
)
self.btn2 =
QtGui.QPushButton
(
"Upload"
, self)
self.btn2.move
(
10
, 90
)
self.ftp =
QtNetwork.QFtp
(
self)
self.btn.clicked.connect
(
self.actionCo)
self.ftp.stateChanged.connect
(
self.stateServer)
self.btn1.clicked.connect
(
self.actionDeco)
self.btn2.clicked.connect
(
self.upload)
def
actionCo
(
self):
if
self.ftp.state
(
) !=
0
:
print
(
'Serveur en cours de connexion ou connecté'
)
else
:
print
(
'Début de connexion'
)
self.ftp.connectToHost
(
serveur, port)
self.ftp.login
(
login, mdp)
def
actionDeco
(
self):
if
self.ftp.state
(
) ==
0
:
print
(
'Serveur non connecté'
)
else
:
self.ftp.close
(
)
def
stateServer
(
self):
print
(
etat[self.ftp.state
(
)])
print
(
)
def
upload
(
self):
file =
QtCore.QFile
(
"toto1.txt"
)
file.open(
QtCore.QIODevice.ReadOnly)
self.ftp.put
(
file.readAll
(
), "toto1_depuis_local.txt"
)
app =
QtGui.QApplication
(
sys.argv)
frame =
Frame
(
)
frame.show
(
)
sys.exit
(
app.exec_
(
))
La fonction get() de la classe QtNetwork.QFtp permet de télécharger un fichier depuis un serveur ftp. L'une des méthodes d'utilisation de la fonction get() est de lui passer comme argument uniquement le fichier à télécharger. Cette méthode renvoie le signal readyRead(), ce qui est très pratique puisque ceci permet de vérifier le bon état du téléchargement. Cette méthode permet aussi de lire directement les données via les fonctions read() ou readAll().
# -*- coding: iso-8859-1 -*-
#Code pour Python3. Pour Python2, enlever les parenthèses après les print.
import
sys
from
PyQt4 import
QtGui, QtNetwork, QtCore
h =
150
l =
220
etat =
{0
:"Aucune connexion"
, 1
:"Résolution du nom en cours"
, 2
:"Tentative de connexion en cours"
,
3
:"Connexion établie"
, 4
:"Identification établie"
, 5
:"Déconnexion en cours"
}
class
Frame
(
QtGui.QMainWindow):
def
__init__
(
self, parent=
None
):
QtGui.QMainWindow.__init__
(
self, parent)
self.resize
(
l,h)
self.setFont
(
QtGui.QFont
(
"Verdana"
,8
))
self.btn =
QtGui.QPushButton
(
"Se connecter"
, self)
self.btn.move
(
10
, 10
)
self.btn1 =
QtGui.QPushButton
(
"Se déconnecter"
, self)
self.btn1.move
(
110
, 10
)
self.btn2 =
QtGui.QPushButton
(
"Download"
, self)
self.btn2.move
(
110
, 50
)
self.ftp =
QtNetwork.QFtp
(
self)
self.btn.clicked.connect
(
self.actionCo)
self.ftp.stateChanged.connect
(
self.stateServer)
self.btn1.clicked.connect
(
self.actionDeco)
self.btn2.clicked.connect
(
self.download)
def
actionCo
(
self):
if
self.ftp.state
(
) !=
0
:
print
(
'Serveur en cours de connexion ou connecté'
)
else
:
print
(
'Début de connexion'
)
self.ftp.connectToHost
(
serveur, port)
self.ftp.login
(
login, mdp)
def
actionDeco
(
self):
if
self.ftp.state
(
) ==
0
:
print
(
'Serveur non connecté'
)
else
:
self.ftp.close
(
)
def
stateServer
(
self):
print
(
etat[self.ftp.state
(
)])
print
(
)
def
download
(
self):
fileServer =
"toto.txt"
self.reply =
self.ftp.get
(
fileServer)
self.ftp.readyRead.connect
(
self.readyRead)
self.ftp.errorString (
)
def
readyRead
(
self):
print
(
"Données prêtes à être lues"
)
file =
QtCore.QFile
(
"toto1_depuis_serveur.txt"
)
file.open(
QtCore.QIODevice.WriteOnly)
file.write
(
self.ftp.readAll
(
))
app =
QtGui.QApplication
(
sys.argv)
frame =
Frame
(
)
frame.show
(
)
sys.exit
(
app.exec_
(
))
La fonction QFtp.cd(dir) permet d'accéder au dossier dir. À noter que le retour au dossier parent se fait par la commande cd('..'). Il peut alors être utile d'afficher l'arborescence du dossier courant et naviguer graphiquement dans les dossiers enfants ou retourner dans le dossier parent.
L'utilisation conjointe de QFtp.list(), QFtp.listInfo(), QFtp.cd() et QtGui.QTreewidget permet de réaliser facilement ceci. Le code ci-dessous illustre une manière de faire.
# -*- coding: iso-8859-1 -*-
#Code pour Python3. Pour Python2, enlever les parenthèses après les print.
import
sys
from
PyQt4 import
QtGui, QtNetwork, QtCore
h =
200
l =
400
serveur =
monserveur
port =
monport
login =
monlogin
mdp =
monmdp
etat =
{0
:"Aucune connexion"
, 1
:"Résolution du nom en cours"
, 2
:"Tentative de connexion en cours"
,
3
:"Connexion établie"
, 4
:"Identification établie"
, 5
:"Déconnexion en cours"
}
class
Frame
(
QtGui.QMainWindow):
def
__init__
(
self, parent=
None
):
QtGui.QMainWindow.__init__
(
self, parent)
self.resize
(
l,h)
self.setFont
(
QtGui.QFont
(
"Verdana"
,8
))
self.btn =
QtGui.QPushButton
(
"Se connecter"
, self)
self.btn.move
(
10
, 10
)
self.btn1 =
QtGui.QPushButton
(
"Se déconnecter"
, self)
self.btn1.move
(
110
, 10
)
self.btn2 =
QtGui.QPushButton
(
"Liste"
, self)
self.btn2.move
(
210
, 10
)
self.txt =
QtGui.QTextEdit
(
self)
self.txt.setGeometry
(
10
, 50
, 150
, 100
)
self.treewid =
QtGui.QTreeWidget
(
self)
self.treewid.setGeometry
(
200
, 50
, 150
, 100
)
self.ftp =
QtNetwork.QFtp
(
self)
self.btn.clicked.connect
(
self.actionCo)
self.ftp.stateChanged.connect
(
self.stateServer)
self.btn1.clicked.connect
(
self.actionDeco)
self.btn2.clicked.connect
(
self.list_)
self.treewid.itemClicked.connect
(
self.cd_)
self.ftp.listInfo.connect
(
self.list_info)
def
actionCo
(
self):
if
self.ftp.state
(
) !=
0
:
print
(
'Serveur en cours de connexion ou connecté'
)
else
:
print
(
'Début de connexion'
)
self.ftp.connectToHost
(
serveur, port)
self.ftp.login
(
login, mdp)
def
actionDeco
(
self):
if
self.ftp.state
(
) ==
0
:
print
(
'Serveur non connecté'
)
else
:
self.ftp.close
(
)
def
stateServer
(
self):
print
(
etat[self.ftp.state
(
)])
print
(
)
def
list_
(
self):
self.txt.clear
(
)
self.treewid.clear
(
)
racine =
QtGui.QTreeWidgetItem
(
)
racine.setText
(
0
,'..'
)
self.treewid.addTopLevelItem
(
racine)
self.liste =
self.ftp.list(
)
def
list_info
(
self,i):
item =
QtGui.QTreeWidgetItem
(
)
if
i.isDir
(
):
item.setText
(
0
,i.name
(
))
self.treewid.addTopLevelItem
(
item)
if
i.isFile
(
):
self.txt.append
(
i.name
(
))
def
cd_
(
self, item, col):
self.ftp.cd
(
item.text
(
0
))
self.list_
(
)
app =
QtGui.QApplication
(
sys.argv)
frame =
Frame
(
)
frame.show
(
)
sys.exit
(
app.exec_
(
))
La classe QFtp possède une fonction permettant de lister le contenu d'un répertoire. Pour cela il faut utiliser la fonction list(dir), où dir représente le chemin du répertoire en question et récupérer le signal listInfo(i) émis. Les éléments contenus dans dir sont alors stockés dans i sous forme de QtNetwork.QUrlInfo.
# -*- coding: iso-8859-1 -*-
#Code pour Python3. Pour Python2, enlever les parenthèses après les print.
import
sys
from
PyQt4 import
QtGui, QtNetwork, QtCore
h =
150
l =
220
serveur =
monserveur
port =
monport
login =
monlogin
mdp =
monmdp
etat =
{0
:"Aucune connexion"
, 1
:"Résolution du nom en cours"
, 2
:"Tentative de connexion en cours"
,
3
:"Connexion établie"
, 4
:"Identification établie"
, 5
:"Déconnexion en cours"
}
class
Frame
(
QtGui.QMainWindow):
def
__init__
(
self, parent=
None
):
QtGui.QMainWindow.__init__
(
self, parent)
self.resize
(
l,h)
self.setFont
(
QtGui.QFont
(
"Verdana"
,8
))
self.btn =
QtGui.QPushButton
(
"Se connecter"
, self)
self.btn.move
(
10
, 10
)
self.btn1 =
QtGui.QPushButton
(
"Se déconnecter"
, self)
self.btn1.move
(
110
, 10
)
self.btn2 =
QtGui.QPushButton
(
"Liste"
, self)
self.btn2.move
(
10
, 50
)
self.ftp =
QtNetwork.QFtp
(
self)
self.btn.clicked.connect
(
self.actionCo)
self.ftp.stateChanged.connect
(
self.stateServer)
self.btn1.clicked.connect
(
self.actionDeco)
self.btn2.clicked.connect
(
self.list_)
self.ftp.listInfo.connect
(
self.list_info)
def
actionCo
(
self):
if
self.ftp.state
(
) !=
0
:
print
(
'Serveur en cours de connexion ou connecté'
)
else
:
print
(
'Début de connexion'
)
self.ftp.connectToHost
(
serveur, port)
self.ftp.login
(
login, mdp)
def
actionDeco
(
self):
if
self.ftp.state
(
) ==
0
:
print
(
'Serveur non connecté'
)
else
:
self.ftp.close
(
)
def
stateServer
(
self):
print
(
etat[self.ftp.state
(
)])
print
(
)
def
list_
(
self):
liste =
self.ftp.list(
)
def
list_info
(
self,i):
print
(
i.name
(
))
def
actionOn
(
self):
print
(
"Action en cours"
)
def
actionOff
(
self):
print
(
"Action terminée"
)
app =
QtGui.QApplication
(
sys.argv)
frame =
Frame
(
)
frame.show
(
)
sys.exit
(
app.exec_
(
))
Lors du téléchargement ou du téléversement d'un fichier, le signal dataTransferProgress est émis. Celui-ci permet de connaitre la progression de l'action en cours. Il est possible de l'associer à un QProgressBar.
# -*- coding: iso-8859-1 -*-
#Code pour Python3. Pour Python2, enlever les parenthèses après les print.
import
sys
from
PyQt4 import
QtGui, QtNetwork, QtCore
h =
150
l =
220
etat =
{0
:"Aucune connexion"
, 1
:"Résolution du nom en cours"
, 2
:"Tentative de connexion en cours"
,
3
:"Connexion établie"
, 4
:"Identification établie"
, 5
:"Déconnexion en cours"
}
class
Frame
(
QtGui.QMainWindow):
def
__init__
(
self, parent=
None
):
QtGui.QMainWindow.__init__
(
self, parent)
self.resize
(
l,h)
self.setFont
(
QtGui.QFont
(
"Verdana"
,8
))
self.btn =
QtGui.QPushButton
(
"Se connecter"
, self)
self.btn.move
(
10
, 10
)
self.btn1 =
QtGui.QPushButton
(
"Se déconnecter"
, self)
self.btn1.move
(
110
, 10
)
self.btn3 =
QtGui.QPushButton
(
"Download"
, self)
self.btn3.move
(
110
, 50
)
self.btn4 =
QtGui.QPushButton
(
"Upload"
, self)
self.btn4.move
(
10
, 90
)
self.ftp =
QtNetwork.QFtp
(
self)
self.btn.clicked.connect
(
self.actionCo)
self.ftp.stateChanged.connect
(
self.stateServer)
self.btn1.clicked.connect
(
self.actionDeco)
self.btn3.clicked.connect
(
self.download)
self.btn4.clicked.connect
(
self.upload)
self.ftp.dataTransferProgress.connect
(
self.test)
def
test
(
self, done, tot):
print
(
'Chargement :
%s
sur
%s
'
%
(
done, tot))
def
actionCo
(
self):
if
self.ftp.state
(
) !=
0
:
print
(
'Serveur en cours de connexion ou connecté'
)
else
:
print
(
'Début de connexion'
)
self.ftp.connectToHost
(
serveur, port)
self.ftp.login
(
login, mdp)
def
actionDeco
(
self):
if
self.ftp.state
(
) ==
0
:
print
(
'Serveur non connecté'
)
else
:
self.ftp.close
(
)
def
stateServer
(
self):
print
(
etat[self.ftp.state
(
)])
print
(
)
def
upload
(
self):
file =
QtCore.QFile
(
"toto1.txt"
)
file.open(
QtCore.QIODevice.ReadOnly)
self.ftp.put
(
file.readAll
(
), "toto1_depuis_local.txt"
)
self.ftp.errorString (
)
def
download
(
self):
fileServer =
"toto.txt"
self.reply =
self.ftp.get
(
fileServer)
self.ftp.readyRead.connect
(
self.readyRead)
def
readyRead
(
self):
print
(
"Données prêtes à être lues"
)
file =
QtCore.QFile
(
"toto1_depuis_serveur.txt"
)
file.open(
QtCore.QIODevice.WriteOnly)
file.write
(
self.ftp.readAll
(
))
app =
QtGui.QApplication
(
sys.argv)
frame =
Frame
(
)
frame.show
(
)
sys.exit
(
app.exec_
(
))
Une fois la connexion au serveur FTP établie grâce à la classe QFtp, il est possible de créer un dossier sur ce serveur. La fonction permettant ceci est QFtp.mkdir() qui produira le signal commandStarted() lorsque la commande sera lancée et le signal commandFinished() lorsque la commande sera finie.
Note importante : par commande finie, il ne faut pas comprendre tâche effectuée. En effet, j'ai noté que l'effet de certaines actions était retardé. Ceci est un fonctionnement normal de la classe QFtp.
# -*- coding: iso-8859-1 -*-
#Code pour Python3. Pour Python2, enlever les parenthèses après les print.
import
sys
from
PyQt4 import
QtGui, QtNetwork
h =
100
l =
220
etat =
{0
:"Aucune connexion"
, 1
:"Résolution du nom en cours"
, 2
:"Tentative de connexion en cours"
,
3
:"Connexion établie"
, 4
:"Identification établie"
, 5
:"Déconnexion en cours"
}
class
Frame
(
QtGui.QMainWindow):
def
__init__
(
self, parent=
None
):
QtGui.QMainWindow.__init__
(
self, parent)
self.resize
(
l,h)
self.setFont
(
QtGui.QFont
(
"Verdana"
,8
))
self.btn =
QtGui.QPushButton
(
"Se connecter"
, self)
self.btn.move
(
10
, 10
)
self.btn1 =
QtGui.QPushButton
(
"Se déconnecter"
, self)
self.btn1.move
(
110
, 10
)
self.btn2 =
QtGui.QPushButton
(
"Créer un dossier"
, self)
self.btn2.move
(
60
, 50
)
self.ftp =
QtNetwork.QFtp
(
self)
self.btn.clicked.connect
(
self.actionCo)
self.ftp.stateChanged.connect
(
self.stateServer)
self.btn1.clicked.connect
(
self.actionDeco)
self.btn2.clicked.connect
(
self.actionBtn2)
def
actionCo
(
self):
if
self.ftp.state
(
) !=
0
:
print
(
'Serveur en cours de connexion ou connecté'
)
else
:
print
(
'Début de connexion'
)
self.ftp.connectToHost
(
serveur, port)
self.ftp.login
(
login, mdp)
def
actionDeco
(
self):
if
self.ftp.state
(
) ==
0
:
print
(
'Serveur non connecté'
)
else
:
self.ftp.close
(
)
def
stateServer
(
self):
print
(
etat[self.ftp.state
(
)])
print
(
)
def
actionBtn2
(
self):
if
self.ftp.state
(
) !=
4
:
print
(
"Serveur non connecté. Réessayer plus tard ou connectez vous"
)
else
:
self.ftp.mkdir
(
"NouveauDossier"
)
self.ftp.commandStarted.connect
(
self.actionOn)
self.ftp.commandFinished.connect
(
self.actionOff)
app =
QtGui.QApplication
(
sys.argv)
frame =
Frame
(
)
frame.show
(
)
sys.exit
(
app.exec_
(
))