Reputation: 225
I am creating an application that shows the progress of copying a file, the copying process works perfectly the problem is that the QProgressBar
is not updated with the appropriate value
The copy ()
function of the Copy Thread
class is responsible for realizing the process of copying theSrc_School_Admin
folder along with the files within it to the new directory created in this case the SchoolAdministration
folder.
To update the value of the QProgressBar
I execute a cycle that updates the size value of the target directory once the destination directorySchoolAdministration
has the same weight as Src_School_Admin
, then the cycle is broken.
The self.procPartDone
signal receives as an argument an operation to calculate the percentage that issize_original_folder * 100 / target_folder_size
.
However, the value of the QProgressBar
is not updated, I hope you can help me
File.py
from PyQt5.QtWidgets import QMainWindow,QApplication,QMessageBox
from PyQt5 import uic,QtCore
import shutil,os
import platform
import threading
class CopyThread(QtCore.QThread):
procDone = QtCore.pyqtSignal(bool)
procPartDone = QtCore.pyqtSignal(int)
def __init__(self,origen,destino,tamaño_origen):
QtCore.QThread.__init__(self)
self.origen = origen
self.destino = destino
self.tamaño = tamaño_origen
def run(self):
self.copy()
self.procDone.emit(True)
def copy(self):
print("copi hilo")
source_destino = 'C:/Program Files/SchoolAdministration'
self.total_destino = 0
while self.tamaño > self.total_destino:
for source,dirs,files in os.walk(source_destino):
for f in files:
fp = os.path.join(source,f)
self.total_destino+= os.path.getsize(fp)
print(self.total_destino,self.tamaño)
self.procPartDone.emit(self.total_destino*100/self.tamaño)
class MessageError(threading.Thread):
def __init__(self,obj):
threading.Thread.__init__(self)
self.obj = obj
def run(self):
QtCore.QMetaObject.invokeMethod(self.obj,"onError",
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(str,"Critical Access"),
QtCore.Q_ARG(str,"\nEste programa solo puede ejecutarse con permisos de Administrador.\n\nInfo:\nAsegurese de iniciar el programa con permisos de Administrador\n"))
class Install(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
uic.loadUi("Dialog_Install.ui",self)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.BClose.clicked.connect(self.Info)
self.BIniciar.pressed.connect(self.Button_Effect_start)
self.BIniciar.released.connect(self.Button_Effect_End)
self.progressBar.hide()
def Info(self):
respuesta = QMessageBox.question(None,"Salir","Desea finalizar la intalación del programa\t")
if respuesta == QMessageBox.Yes:
self.close()
def Button_Effect_start(self):
animacion = QtCore.QPropertyAnimation(self.BIniciar, b"size")
animacion.setDuration(100)
animacion.setStartValue(QtCore.QSize(138,28))
animacion.setEndValue(QtCore.QSize(138,28))
animacion.start()
def Button_Effect_End(self):
animacion = QtCore.QPropertyAnimation(self.BIniciar, b"size")
animacion.setDuration(100)
animacion.setStartValue(QtCore.QSize(141,31))
animacion.setEndValue(QtCore.QSize(141,31))
animacion.start()
self.BIniciar.hide()
self.progressBar.show()
self.LEstado.setText("Copiando archivos " + str(self.progressBar.value()) + "%")
self.label_5.setText("Instalando")
self.LEstado.setText("Creando directorio")
t=threading.Thread(target=self.Ubicacion)
t.start()
def Ubicacion(self):
arquitectura = platform.architecture()
target = "Src_School_Admin"
initial_dir = 'C:\\'
path = ''
for root, _,files in os.walk(initial_dir):
if target in root:
path = os.path.join(root)
break
tamaño_origen = 0
start = "."
source = path.replace("\\","/")
for source,dirs,files in os.walk(source):
for f in files:
fp = os.path.join(source,f)
tamaño_origen += os.path.getsize(fp)
if os.path.exists('C:\\Program Files\\SchoolAdministration'):
shutil.rmtree('C:\\Program Files\\SchoolAdministration')
self.copy1(path,tamaño_origen)
else:
self.copy1(path,tamaño_origen)
def copy1(self,path,tamaño_origen):
origen = path.replace("\\",'/')
print(origen)
destino = 'C:\\Program Files\\SchoolAdministration'
shutil.copytree(origen, destino)
self.copy_thread = CopyThread(origen, destino,tamaño_origen)
self.copy_thread.procPartDone.connect(self.update_progress)
self.copy_thread.procDone.connect(self.finished_copy)
self.copy_thread.start()
def update_progress(self,progress):
print(progress,"progress")
self.progressBar.setValue(progress)
def finished_copy(self,state):
self.close()
@QtCore.pyqtSlot(str,str)
def onError(self,title,text):
QMessageBox.critical(None,title,text)
self.close()
app = QApplication([])
i = Install()
i.show()
app.exec_()
Dialog_Install.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>638</width>
<height>433</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="styleSheet">
<string notr="true">background:#2A2E30;</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPushButton" name="BClose">
<property name="geometry">
<rect>
<x>600</x>
<y>0</y>
<width>41</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QPushButton#BClose{
background:none;
border:0px;
color:white;
}
</string>
</property>
<property name="text">
<string>X</string>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>30</x>
<y>30</y>
<width>81</width>
<height>81</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background:none;</string>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap>Src_School_Admin/Img/Logo.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>120</x>
<y>40</y>
<width>121</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">color:#4253F4;
background:none;</string>
</property>
<property name="text">
<string>School Admin</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>120</x>
<y>60</y>
<width>201</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">color:#424D99;
background:none;</string>
</property>
<property name="text">
<string>School Administration System</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>5</x>
<y>410</y>
<width>201</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>8</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">color:grey;
background:none;</string>
</property>
<property name="text">
<string>2019 v 0.1 Beta - Rev.1.0</string>
</property>
</widget>
<widget class="QPushButton" name="BIniciar">
<property name="geometry">
<rect>
<x>250</x>
<y>270</y>
<width>141</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QPushButton#BIniciar{
color:white;
background:qlineargradient(spread:pad, x1:0.475435, y1:0, x2:0.495, y2:1, stop:0 rgba(66, 83, 224, 255), stop:1 rgba(66, 77, 153, 255));
border:0px;
}
QPushButton#BIniciar:hover{
background:qlineargradient(spread:pad, x1:0.509, y1:1, x2:0.506299, y2:0, stop:0 rgba(66, 83, 224, 255), stop:1 rgba(66, 77, 153, 255));
}</string>
</property>
<property name="text">
<string>Instalar</string>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>250</x>
<y>190</y>
<width>141</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">color:lightgrey;</string>
</property>
<property name="text">
<string>Bienvenido</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QProgressBar" name="progressBar">
<property name="geometry">
<rect>
<x>20</x>
<y>280</y>
<width>601</width>
<height>23</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QProgressBar#progressBar::horizontal{
border:0px;
background:grey;
}
QProgressBar#progressBar::chunk{
border:0px;
background-color:qlineargradient(spread:pad, x1:1, y1:0.54, x2:0, y2:0.5, stop:0 rgba(45, 116, 185, 193), stop:1 rgba(26, 44, 53, 255));
}</string>
</property>
<property name="value">
<number>0</number>
</property>
<property name="textVisible">
<bool>false</bool>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
</widget>
<widget class="QLabel" name="LEstado">
<property name="geometry">
<rect>
<x>240</x>
<y>320</y>
<width>171</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">color:#4253F4;
background:none;</string>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>
Upvotes: 1
Views: 258
Reputation: 13691
I tried your example, everything is fine, QProgressBar is updated, only very quickly :) so I slowed it down a bit, QtCore.QThread.msleep (100)
.
# ...
def copy(self):
print("copi hilo-> {}({}) -> {}".format(self.origen, self.tamaño, self.destino))
source_destino = 'C:/Program Files/SchoolAdministration'
#source_destino = 'D:\\Test\\SchoolAdministration'
self.total_destino = 0
while self.tamaño > self.total_destino:
for source, dirs, files in os.walk(source_destino):
for f in files:
fp = os.path.join(source, f)
self.total_destino += os.path.getsize(fp)
print("\nemit-> {} = {} * 100 / {} "
"".format(self.total_destino*100//self.tamaño, # //
self.total_destino,
self.tamaño))
print("f=`{}` --> fp=`{}`"
"".format( f, fp))
self.procPartDone.emit(self.total_destino*100/self.tamaño)
QtCore.QThread.msleep(100) # <---
# ...
Upvotes: 3