python - QProgressBar不显示复制进度

标签 python python-3.x pyqt pyqt5

我正在创建一个显示复制文件进度的应用程序,复制过程完美运行,问题是 QProgressBar 未使用适当的值进行更新

Copy Thread类的copy()函数负责实现复制Src_School_Admin文件夹及其中的文件的过程将其复制到在本例中创建的新目录中的 SchoolAdministration 文件夹。

为了更新 QProgressBar 的值,我执行一个循环,一旦目标目录SchoolAdministration 具有相同的权重,就会更新目标目录的大小值Src_School_Admin,则循环被打破。

self.procPartDone 信号接收一个操作作为参数,以计算 size_original_folder * 100/target_folder_size 的百分比。

但是QProgressBar的值没有更新,希望您能帮助我

文件.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>

最佳答案

我尝试了你的示例,一切都很好,QProgressBar 更新了,但速度很快:)所以我放慢了速度,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)                               # <---
# ...

enter image description here

关于python - QProgressBar不显示复制进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54897037/

相关文章:

python - 将历史盘中数据提取到每周范围内的多个调用中

python - update_or_create 在外键的两个实例上覆盖字段对象

python - 执行练习代码时,即使在 datetime 模块之后也会出现错误

python - Multiselect/Selectbox 不会在第一次选择后等待 - Streamlit

python - QLineEdit python方式中的大写输入

pyqt - PyInstaller 创建缓慢的可执行文件

qt - 用 PyQt 在 QLabel 上绘画

python - 在 Django 中更改使用 ModelForm 创建的表单元素的宽度

python - 带有默认数据类的 SQLAlchemy 不填充 postgres 数据库

Python:删除集合中字符串的较长子字符串