progress bar python pyqt5 — Stack Overflow на русском
Умные головы, подскажите как правильно задать значения прогресс бару, при делении видео на кадры получается 700+ кадров например, значение cnt со 100 кадров сразу заполняет прогресс бар на 100. здесь я пытаюсь задать прогресс бар:
for i in range(len(video_colors)): video_colors[i] |= image_bits[i] video_colors = np.reshape(np.asarray(video_colors), (req_frame_count, vid_height, vid_width, 3)).astype(np.uint8) # create dirs if os.path.exists("temp"): remove_directory_content("temp") else: make_dir("temp") cnt = 1 for frame in video_colors: cv2.imwrite('./temp/frame{:09d}.png'.format(cnt), frame, [cv2.IMWRITE_PNG_COMPRESSION, 0]) cnt += 1 print('Starting write back...') while True: ret, frame = cap.read() if ret: cv2.imwrite('./temp/frame{:09d}.png'.format(cnt), frame, [cv2.IMWRITE_PNG_COMPRESSION, 0]) cnt += 1 w. progressBar.setValue(cnt) # progressbar else: break
ПОЛНЫЙ КОД:
def hide(carrier_video, image_message): cap = cv2.VideoCapture(carrier_video) msg = cv2.imread(image_message) vid_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) vid_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) vid_fps = cap.get(cv2.CAP_PROP_FPS) # count = 0 # TIME_LIMIT=100 req_frame_count = required_frame_count(cap, msg) bin_rep_width = bin_rep(msg.shape[1]).zfill(16) bin_rep_height = bin_rep(msg.shape[0]).zfill(16) bin_rep_mult = bin_rep(msg.shape[0] * msg.shape[1]).zfill(32) image_bits = [int(x == '1') for x in bin_rep_width + bin_rep_height + bin_rep_mult] for row in msg: for column in row: for color in column: for i in range(8): image_bits.append(int((color & (1 << (7 - i))) != 0)) video_colors = [] for i in range(req_frame_count): ret, frame = cap.read() if not ret: raise Exception('Error in extracting video frames') for row in frame: for column in row: for color in range(3): video_colors.append(column[color]) assert len(video_colors) >= len(image_bits) for i in range(len(video_colors) - len(image_bits)): image_bits.append(0) video_colors = [(color & 0xFE) for color in video_colors] for i in range(len(video_colors)): video_colors[i] |= image_bits[i] video_colors = np.reshape(np.asarray(video_colors), (req_frame_count, vid_height, vid_width, 3)).astype(np.uint8) # create dirs if os.path.exists("temp"): remove_directory_content("temp") else: make_dir("temp") cnt = 1 for frame in video_colors: cv2.imwrite('./temp/frame{:09d}.png'.format(cnt), frame, [cv2.IMWRITE_PNG_COMPRESSION, 0]) cnt += 1 print('Starting write back...') while True: ret, frame = cap. read() if ret: cv2.imwrite('./temp/frame{:09d}.png'.format(cnt), frame, [cv2.IMWRITE_PNG_COMPRESSION, 0]) cnt += 1 w.progressBar.setValue(cnt) # progressbar else: break
Виджеты в PyQt5 | Python 3 для начинающих и чайников
Виджеты – это основные строительные кирпичики приложения. PyQt5 имеет множество разнообразных виджетов, включая кнопки, чекбоксы, ползунки и списки. В этой части руководства, мы опишем несколько полезных виджетов: QCheckBox, ToggleButton, QSlider, QProgressBar и QCalendarWidget.
QCheckBox (чекбокс)
QCheckBox – чекбокс (виджет, который имеет два состояния: включен и выключен). Как правило, чекбоксы используют для функций приложения, которые могут быть включены или выключены.
#!/usr/bin/python3 # -*- coding: utf-8 -*- import sys from PyQt5.QtWidgets import QWidget, QCheckBox, QApplication from PyQt5.QtCore import Qt class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): cb = QCheckBox('Show title', self) cb.move(20, 20) cb.toggle() cb.stateChanged.connect(self.changeTitle) self.setGeometry(300, 300, 250, 150) self.setWindowTitle('QCheckBox') self.show() def changeTitle(self, state): if state == Qt.Checked: self.setWindowTitle('QCheckBox') else: self.setWindowTitle('') if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())
В нашем примере, мы создаём чекбокс, который переключает заголовок окна.
cb = QCheckBox('Show title', self)
Это конструктор QCheckBox.
cb.toggle()
Мы установили заголовок окна так, что мы должны к тому же проверять чекбокс. По умолчанию, заголовок окна не установлен и чекбокс выключен.
cb.stateChanged.connect(self.changeTitle)
Мы связываем наш метод changeTitle(), с сигналом stateChanged. Метод changeTitle() будет переключать заголовок окна.
def changeTitle(self, state): if state == Qt.Checked: self.setWindowTitle('QCheckBox') else: self.setWindowTitle('')
Если виджет помечен галочкой, мы устанавливаем заголовок окна. В противном случае, мы устанавливаем пустую строку в заголовке.
Кнопка переключателя (toogle button)
Кнопка переключателя – это QPushButton в особом режиме. Это кнопка, которая имеет два состояния: нажатое и не нажатое. Мы переключаемся между этими двумя состояниями, кликая по ней. Существуют ситуации, где эта функциональность отлично подходит.
#!/usr/bin/python3 # -*- coding: utf-8 -*- import sys from PyQt5.QtWidgets import (QWidget, QPushButton, QFrame, QApplication) from PyQt5.QtGui import QColor class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.col = QColor(0, 0, 0) redb = QPushButton('Red', self) redb.setCheckable(True) redb.move(10, 10) redb.clicked[bool].connect(self.setColor) greenb = QPushButton('Green', self) greenb.setCheckable(True) greenb.move(10, 60) greenb.clicked[bool].connect(self.setColor) blueb = QPushButton('Blue', self) blueb.setCheckable(True) blueb.move(10, 110) blueb.clicked[bool].connect(self.setColor) self.square = QFrame(self) self.square.setGeometry(150, 20, 100, 100) self.square.setStyleSheet("QWidget { background-color: %s }" % self.col.name()) self.setGeometry(300, 300, 280, 170) self.setWindowTitle('Toggle button') self.show() def setColor(self, pressed): source = self.sender() if pressed: val = 255 else: val = 0 if source.text() == "Red": self.col.setRed(val) elif source.text() == "Green": self.col.setGreen(val) else: self. col.setBlue(val) self.square.setStyleSheet("QFrame { background-color: %s }" % self.col.name()) if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())
В нашем примере, мы создаём три кнопки переключателя и QWidget. Мы устанавливаем чёрный цвет фона. Кнопки переключателей будут переключать красные, зелёные и синие части значений цвета. Цвет фона будет зависеть от того, на какие кнопки переключателей мы нажали.
self.col = QColor(0, 0, 0)
Это начальное значение цвета (чёрный).
redb = QPushButton('Red', self) redb.setCheckable(True) redb.move(10, 10)
Чтобы создать кнопку переключателя, мы создаём QPushButton и делаем её проверяемой, путём вызова метода setCheckable().
redb.clicked[bool].connect(self.setColor)
Мы привязываем сигнал к нашему пользовательскому методу. Мы используем сигнал clicked, который работает с логическим значением.
source = self.sender()
Мы получаем кнопку, которая была переключена.
if source.text() == "Red": self.col.setRed(val)
В случае кнопки red, мы обновляем красную часть цвета соответственно.
self.square.setStyleSheet("QFrame { background-color: %s }" % self.col.name())
Мы используем таблицы стилей, чтобы менять цвет фона.
QSlider (ползунок)
Qslider – ползунок (виджет, который имеет простой регулятор). Этот регулятор может быть утянут назад и вперёд. Таким способом, мы выбираем значение для конкретной задачи. Иногда, использование ползунка более естественно, чем ввод числа или использование переключателя-счётчика. В нашем примере, мы покажем один ползунок и одну метку. Метка будет показывать изображение. Ползунок будет контролировать метку.
#!/usr/bin/python3 # -*- coding: utf-8 -*- import sys from PyQt5.QtWidgets import (QWidget, QSlider, QLabel, QApplication) from PyQt5.QtCore import Qt from PyQt5.QtGui import QPixmap class Example(QWidget): def __init__(self): super(). __init__() self.initUI() def initUI(self): sld = QSlider(Qt.Horizontal, self) sld.setFocusPolicy(Qt.NoFocus) sld.setGeometry(30, 40, 100, 30) sld.valueChanged[int].connect(self.changeValue) self.label = QLabel(self) self.label.setPixmap(QPixmap('mute.png')) self.label.setGeometry(160, 40, 80, 30) self.setGeometry(300, 300, 280, 170) self.setWindowTitle('QSlider') self.show() def changeValue(self, value): if value == 0: self.label.setPixmap(QPixmap('mute.png')) elif value > 0 and value <= 30: self.label.setPixmap(QPixmap('min.png')) elif value > 30 and value < 80: self.label.setPixmap(QPixmap('med.png')) else: self.label.setPixmap(QPixmap('max.png')) if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())
В нашем примере, мы симулируем контроль громкости. Путём перетаскивания регулятора ползунка, мы меняем изображение на метке.
sld = QSlider(Qt.Horizontal, self)
Здесь мы создаём горизонтальный ползунок.
self.label = QLabel(self) self.label.setPixmap(QPixmap('mute.png'))
Мы создаём виджет QLabel и устанавливаем начальное изображение «Mute» на него.
sld.valueChanged[int].connect(self.changeValue)
Мы привязываем сигнал valueChanged к определенному нами методу changeValue().
if value == 0: self.label.setPixmap(QPixmap('mute.png')) ...
Основываясь на значении ползунка, мы устанавливаем изображение на метку. В коде выше, мы устанавливаем изображение mute.png на метку, если ползунок приравнен к нулю.
QProgressBar (прогресс бар)
QProgressBar – прогресс бар (виджет, который используется, когда мы обрабатываем продолжительные задачи). Он анимирует процесс, чтобы пользователи знали, что задача продвигается. Мы можем установить минимальное и максимальное значение для прогресс бара. Значения по умолчанию – 0 и 99.
#!/usr/bin/python3 # -*- coding: utf-8 -*- import sys from PyQt5.QtWidgets import (QWidget, QProgressBar, QPushButton, QApplication) from PyQt5.QtCore import QBasicTimer class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.pbar = QProgressBar(self) self.pbar.setGeometry(30, 40, 200, 25) self.btn = QPushButton('Start', self) self.btn.move(40, 80) self.btn.clicked.connect(self.doAction) self.timer = QBasicTimer() self.step = 0 self.setGeometry(300, 300, 280, 170) self.setWindowTitle('QProgressBar') self.show() def timerEvent(self, e): if self.step >= 100: self.timer.stop() self.btn.setText('Finished') return self.step = self.step + 1 self.pbar.setValue(self.step) def doAction(self): if self.timer.isActive(): self. timer.stop() self.btn.setText('Start') else: self.timer.start(100, self) self.btn.setText('Stop') if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())
В нашем примере, мы имеем горизонтальный индикатор прогресса и кнопку. Кнопка запускает и останавливает индикатор прогресса.
self.pbar = QProgressBar(self)
Это конструктор QProgressBar.
self.timer = QtCore.QBasicTimer()
Чтобы активировать индикатор прогресса, мы используем объект таймера.
self.timer.start(100, self)
Чтобы запустить событие таймера, мы вызываем его методом start(). Этот метод имеет два параметра: таймаут, и объект, который будет принимать события.
def timerEvent(self, e): if self.step >= 100: self.timer.stop() self.btn.setText('Finished') return self.step = self.step + 1 self.pbar.setValue(self.step)
Каждый QObject и его наследники имеют обработчик событий timerEvent(). Для того, чтобы реагировать на события таймера, мы переопределяем обработчик событий.
def doAction(self): if self.timer.isActive(): self.timer.stop() self.btn.setText('Start') else: self.timer.start(100, self) self.btn.setText('Stop')
Внутри метода doAction(), мы запускаем и останавливаем таймер.
QCalendarWidget (виджет календаря)
QCalendarWidget предоставляет виджет помесячного календаря. Он позволяет пользователю выбирать дату простым и интуитивно-понятным способом.
#!/usr/bin/python3 # -*- coding: utf-8 -*- import sys from PyQt5.QtWidgets import (QWidget, QCalendarWidget, QLabel, QApplication) from PyQt5.QtCore import QDate class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): cal = QCalendarWidget(self) cal.setGridVisible(True) cal.move(20, 20) cal.clicked[QDate].connect(self.showDate) self. lbl = QLabel(self) date = cal.selectedDate() self.lbl.setText(date.toString()) self.lbl.move(130, 260) self.setGeometry(300, 300, 350, 300) self.setWindowTitle('Calendar') self.show() def showDate(self, date): self.lbl.setText(date.toString()) if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())
Пример имеет виджет календаря и виджет метки. Текущая выбранная дата отображается в виджете метки.
cal.clicked[QDate].connect(self.showDate)
Если мы выбираем дату из виджета, срабатывает сигнал clicked[QDate]. Мы присоединяем этот сигнал к пользовательскому методу showDate().
def showDate(self, date): self.lbl.setText(date.toString())
Мы возвращаем выбранную дату путём вызова метода selectedDate(). Тогда мы превращаем объект даты в строку и устанавливаем его в виджет метки.
В этой части руководства PyQt5, мы изучили некоторые виджеты.
Для вставки кода на Python в комментарий заключайте его в теги <pre><code>Ваш код</code></pre>
python 3.
x — Как обновить QProgressbar из другого модуля?Задавать вопрос
спросил
Изменено 2 года, 7 месяцев назад
Просмотрено 711 раз
Я хочу обновить индикатор выполнения в моем основном классе графического интерфейса из другого модуля. Поскольку значение индикатора выполнения должно обновляться, пока графический интерфейс все еще работает в своем основном цикле событий, я создал для него поток. Я не могу обновить значение прогресса из потока.
Это просто голый код того, что я на самом деле хочу сделать, но он выдает ту же ошибку.
progress.py
из времени импорта сна из PyQt5.QtCore импортировать QObject, pyqtSignal класс ProgressUpdate(QObject): progress_signal = pyqtSignal (целое число) защита __init__(сам): супер(). __инит__() self.progress_update() def progress_update (сам): для я в диапазоне (0, 101): self.progress_signal.emit (я) сон(0,01)
main.py
из PyQt5.QtWidgets импортирует QVBoxLayout, QApplication, QProgressBar, QWidget из PyQt5 импортировать QtCore импорт системы из прогресса импорта ProgressUpdate Пример класса (QWidget): защита __init__(сам): супер().__инит__() self.init_ui() определение init_ui (я): self.progress_bar = QProgressBar(я) self.vbox = QVBoxLayout(я) self.vbox.addWidget(self.progress_bar) self.setLayout(self.vbox) self.setWindowTitle('Прогресс') self.p_thread = ProgressThread() self.p_thread.start() самовыражение() def update_progress (я, значение): self.progress_bar.setValue (значение) класс ProgressThread(QtCore.QThread): защита __init__(сам): супер().__инит__() деф запустить (самостоятельно): self.obj = ProgressUpdate() self. obj.progress_signal.connect(Пример.update_progress) деф основной(): приложение = QApplication (sys.argv) р = Пример () sys.exit(приложение.exec_()) если __name__ == '__main__': основной()
Когда я запускаю это, появляется индикатор выполнения, но он остается на 0, он не обновляется.
- python-3.x
- pyqt5
- индикатор выполнения
- слоты сигналов
Вам не нужен отдельный QObject и поток, это усложняет правильное подключение сигнала и слота. Файл progress.py может содержать QThread с циклом для выдачи значения через каждый интервал.
класс ProgressThread(QtCore.QThread): progress_signal = pyqtSignal (целое число) защита __init__(сам): супер().__инит__() деф запустить (самостоятельно): для я в диапазоне (0, 101): self.progress_signal.emit (я) сон(0,01)
И в main.py подключить сигнал от треда к слоту в классе.
Пример класса (QWidget): защита __init__(сам): супер(). __инит__() self.init_ui() определение init_ui (я): self.progress_bar = QProgressBar(я) self.vbox = QVBoxLayout(я) self.vbox.addWidget(self.progress_bar) self.setLayout(self.vbox) self.setWindowTitle('Прогресс') self.p_thread = ProgressThread() self.p_thread.progress_signal.connect(self.update_progress) self.p_thread.start() самовыражение() def update_progress (я, значение): self.progress_bar.setValue (значение) деф основной(): приложение = QApplication (sys.argv) р = Пример () sys.exit(приложение.exec_()) если __name__ == '__main__': основной()
Зарегистрируйтесь или войдите в систему
Зарегистрируйтесь с помощью Google
Зарегистрироваться через Facebook
Зарегистрируйтесь, используя электронную почту и пароль
Опубликовать как гость
Электронная почта
Требуется, но не отображается
Опубликовать как гость
Электронная почта
Требуется, но не отображается
PyQt5 QProgressBar — Как создать индикатор выполнения?
73 из740074 .0073 QPushButton( 'Start' , self ) 6 9007 4 0074 |