class VideoFrame(QWidget): def __init__(self, *args, **kwargs): super(VideoFrame, self).__init__(*args, **kwargs) self.layout = QVBoxLayout() self.img_list = [] # STREAM 1 LABEL AREA self.label = QLabel('Nothing to show right now.', self) self.label.setAlignment(Qt.AlignCenter) self.label.setGeometry(30, 20, 750, 360) self.layout.addWidget(self.label) # PLAY BUTTON self.play = QPushButton(self) icon = QPixmap(os.path.join(os.path.dirname(__file__), 'icons', 'play.png')) self.play.setIcon(QIcon(icon)) self.play.setGeometry(320, 370, 50, 30) self.play.clicked.connect(self.timerEvent) self.layout.addWidget(self.play) # PAUSE BUTTON self.pause = QPushButton(self) icon = QPixmap(os.path.join(os.path.dirname(__file__), 'icons', 'pause.png')) self.pause.setIcon(QIcon(icon)) self.pause.setGeometry(400, 370, 50, 30) self.pause.clicked.connect(self.pauseTimer) self.layout.addWidget(self.pause) # FAST-FORWARD self.ff = QPushButton(self) icon = QPixmap(os.path.join(os.path.dirname(__file__), 'icons', 'ff.png')) self.ff.setIcon(QIcon(icon)) self.ff.setGeometry(560, 370, 50, 30) self.ff.clicked.connect(self.fastForward) self.layout.addWidget(self.ff) # SLOWDOWN self.fr = QPushButton(self) icon = QPixmap(os.path.join(os.path.dirname(__file__), 'icons', 'fr.png')) self.fr.setIcon(QIcon(icon)) self.fr.setGeometry(240, 370, 50, 30) self.fr.clicked.connect(self.slowdown) self.layout.addWidget(self.fr) self.stop = QPushButton(self) icon = QPixmap(os.path.join(os.path.dirname(__file__), 'icons', 'stop.png')) self.stop.setIcon(QIcon(icon)) self.stop.setGeometry(480, 370, 50, 30) self.stop.clicked.connect(self.stopTimer) self.layout.addWidget(self.stop) # SLIDER 1 self.slider = QSlider(Qt.Horizontal, self) self.layout.addWidget(self.slider) self.slider.setGeometry(10, 400, 825, 20) self.slider.valueChanged.connect(self.showImage) # RANGE SLIDER self.range_slider = QRangeSlider(self) self.range_slider.setFixedHeight(30) self.range_slider.setFixedWidth(825) self.range_slider.move(10, 420) self.range_slider.endValueChanged.connect(self.boundEnd) self.range_slider.startValueChanged.connect(self.boundStart) self.timer = QBasicTimer() # FIXME consider something with less lag self.startIdx = 0 self.idx = 0 self.delay = 1000 self.skip = 1 self.calibrate_mode = False self.alpha = None self.beta = None self.t = None self.z = None def size(self): return len(self.img_list) def mousePressEvent(self, event): print('Calibration: ' + str(self.calibrate_mode)) if self.calibrate_mode is True: c_x, c_y = (event.x(), event.y()) self.alpha, self.beta = alpha_beta(c_x, c_y) self.t = lp_projection_calibration(self.alpha, self.beta) elif self.t is not None: c_x, c_y = (event.x(), event.y()) self.alpha, self.beta = alpha_beta(c_x, c_y) self.z = lp_projection(self.alpha, self.beta, self.t) print('Height (inches): ' + str(self.z)) def setCalibrateMode(self): self.calibrate_mode = not self.calibrate_mode def boundEnd(self): self.endIdx = self.range_slider.end() def boundStart(self): self.startIdx = self.range_slider.start() self.idx = self.startIdx def setSkipRate(self, skip_rate): self.skip = skip_rate def setFrameRate(self, delay): self.delay = delay def setImgList(self, img_list): self.img_list = img_list self.endIdx = len(self.img_list)-1 self.slider.setRange(0, len(self.img_list)-1) self.range_slider.setMax(len(self.img_list)-1) pixmap = QPixmap(self.img_list[self.idx]).scaled(600, 800, Qt.KeepAspectRatio, Qt.FastTransformation) #self.pixmap_list = [QPixmap(self.img_list[i]).scaled(600, 800, Qt.KeepAspectRatio, Qt.FastTransformation) for i in range(0, len(self.img_list))] self.label.setPixmap(pixmap) def showImage(self): if len(self.img_list) == 0: return self.idx = self.slider.value() pixmap = QPixmap(self.img_list[self.idx]).scaled(600, 800, Qt.KeepAspectRatio, Qt.FastTransformation) self.label.setPixmap(pixmap) def showImage(self, idx): if len(self.img_list) == 0 or idx > len(self.img_list)-1: return self.idx = idx self.slider.setValue(idx) pixmap = QPixmap(self.img_list[idx]).scaled(600, 800, Qt.KeepAspectRatio, Qt.FastTransformation) self.label.setPixmap(pixmap) def timerEvent(self, e=None): if len(self.img_list) == 0: return if self.idx > self.endIdx: self.timer.stop() self.idx = self.startIdx return self.timer.start(self.delay, self) self.showImage(self.idx) #self.label.setPixmap(self.pixmap_list[self.idx]) self.slider.setValue(self.idx) self.idx += self.skip def pauseTimer(self): self.timer.stop() def stopTimer(self): self.timer.stop() self.startIdx = self.range_slider.start() self.idx = self.startIdx def fastForward(self): if len(self.img_list) == 0: return self.delay /= 2 def slowdown(self): if len(self.img_list) == 0: return self.delay *= 2
class MainWindow(QMainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.setWindowIcon( QIcon(os.path.join(os.path.dirname(__file__), 'icons', 'plant.png'))) self.setWindowTitle("Video Comparison GUI") self.statusBar() self.img_list = None self.cur_video_id = 0 self.layout = QGridLayout() # Main Widget Init self.widget = QWidget() self.widget.setLayout(self.layout) self.setCentralWidget(self.widget) self.setGeometry(250, 50, 1920, 1080) # Open File Dialog openFile = QAction('Open Image Directory', self) openFile.setShortcut('Ctrl+O') openFile.setStatusTip('Open Image Directory') openFile.triggered.connect(self.fileDialog) change_framerate = QAction('Change Framerate...', self) change_framerate.setStatusTip( 'Change Playback Framerate of Video (default: 1 frame/sec)') change_framerate.triggered.connect(self.setFrameRate) change_skiprate = QAction('Change Skip Rate...', self) change_skiprate.setStatusTip( 'Change Frame Skip Rate in Selected Photos (default: 1)') change_skiprate.triggered.connect(self.setSkipRate) set_v_1 = QAction('Video 1...', self) set_v_1.setStatusTip('Set Video 1 (Top Left Corner) Settings') set_v_1.triggered.connect(self.setv1) set_v_2 = QAction('Video 2...', self) set_v_2.setStatusTip('Set Video 2 (Top Right Corner) Settings') set_v_2.triggered.connect(self.setv2) set_v_3 = QAction('Video 3...', self) set_v_3.setStatusTip('Set Video 3 (Bottom Left Corner) Settings') set_v_3.triggered.connect(self.setv3) set_v_4 = QAction('Video 4...', self) set_v_4.setStatusTip('Set Video 4 (Bottom Right Corner) Settings') set_v_4.triggered.connect(self.setv4) change_calibrate = QAction('Turn Calibration On/Off...', self) change_calibrate.setStatusTip( 'Calibrate auto height detection to plant pot') change_calibrate.triggered.connect(self.calibrate) export_video = QAction('Export Video...', self) export_video.setStatusTip( 'Export the current video frame with current settings') export_video.triggered.connect(self.export) # Menu Bar menubar = self.menuBar() file_menu = menubar.addMenu('&File') file_menu.addAction(openFile) file_menu.addAction(export_video) edit_menu = menubar.addMenu('&Edit') edit_menu.addAction(change_framerate) edit_menu.addAction(change_skiprate) video_menu = menubar.addMenu('&Video') video_menu.addAction(set_v_1) video_menu.addAction(set_v_2) video_menu.addAction(set_v_3) video_menu.addAction(set_v_4) calibrate_menu = menubar.addMenu('&Calibrate') calibrate_menu.addAction(change_calibrate) # Video Frame Objects self.v1 = VideoFrame() self.layout.addWidget(self.v1, 0, 0, 1, 2) self.v2 = VideoFrame() self.layout.addWidget(self.v2, 0, 2, 1, 2) self.v3 = VideoFrame() self.layout.addWidget(self.v3, 1, 0, 1, 2) self.v4 = VideoFrame() self.layout.addWidget(self.v4, 1, 2, 1, 2) self.video_list = [self.v1, self.v2, self.v3, self.v4] ## STREAM 1 LABEL AREA #self.label = QLabel('Nothing to show right now.') #self.label.setAlignment(Qt.AlignCenter) #self.layout.addWidget(self.label) self.bottomLayout = QVBoxLayout() # GLOBAL PLAY BUTTON #self.play = QPushButton("Play") #self.play.clicked.connect(self.timerEvent) #self.bottomLayout.addWidget(self.play) # SLOWDOWN #self.fr = QPushButton(self) #icon = QPixmap(os.path.join(os.path.dirname(__file__), 'icons', 'fr.png')) #self.fr.setIcon(QIcon(icon)) #self.fr.clicked.connect(self.slowdown) #self.layout.addWidget(self.fr, 2, 0, 1, 1) # GLOBAL PLAY BUTTON self.play = QPushButton(self) icon = QPixmap( os.path.join(os.path.dirname(__file__), 'icons', 'play.png')) self.play.setIcon(QIcon(icon)) self.play.clicked.connect(self.timerEvent) self.layout.addWidget(self.play, 2, 0, 1, 1) # GLOBAL PAUSE BUTTON self.pause = QPushButton(self) icon = QPixmap( os.path.join(os.path.dirname(__file__), 'icons', 'pause.png')) self.pause.setIcon(QIcon(icon)) self.pause.clicked.connect(self.pauseTimer) self.layout.addWidget(self.pause, 2, 1, 1, 1) # GLOBAL FAST-FORWARD self.ff = QPushButton(self) icon = QPixmap( os.path.join(os.path.dirname(__file__), 'icons', 'ff.png')) self.ff.setIcon(QIcon(icon)) self.ff.clicked.connect(self.fastForward) self.layout.addWidget(self.ff, 2, 3, 1, 1) # GLOBAL STOP self.stop = QPushButton(self) icon = QPixmap( os.path.join(os.path.dirname(__file__), 'icons', 'stop.png')) self.stop.setIcon(QIcon(icon)) self.stop.clicked.connect(self.stopTimer) self.layout.addWidget(self.stop, 2, 2, 1, 1) # GLOBAL SLIDER self.slider = QSlider(Qt.Horizontal) self.bottomLayout.addWidget(self.slider) self.slider.valueChanged.connect(self.showImage) # GLOBAL RANGE SLIDER self.range_slider = QRangeSlider() self.range_slider.setFixedHeight(20) self.bottomLayout.addWidget(self.range_slider) self.range_slider.endValueChanged.connect(self.boundEnd) self.range_slider.startValueChanged.connect(self.boundStart) self.layout.addLayout(self.bottomLayout, 3, 0, 1, 4) self.timer = QBasicTimer() # FIXME consider something with less lag self.startIdx = 0 self.idx = 0 self.delay = 1000 self.skip = 1 def fileDialog(self): self.img_list, _ = QFileDialog.getOpenFileNames( self, 'Select one or more files to open', '/home', 'Images (*.jpg)') self.img_list.sort() if len(self.img_list) == 0: return self.video_list[self.cur_video_id].setImgList(self.img_list) self.endIdx = max(self.video_list, key=lambda end: end.size() - 1) self.endIdx = self.endIdx.size() - 1 self.slider.setRange(0, self.endIdx) self.range_slider.setMax(self.endIdx) def timerEvent(self): self.v1.timerEvent() self.v2.timerEvent() self.v3.timerEvent() self.v4.timerEvent() p1 = Process(target=self.v1.timerEvent(), args=()) p2 = Process(target=self.v2.timerEvent(), args=()) p3 = Process(target=self.v3.timerEvent(), args=()) p4 = Process(target=self.v4.timerEvent(), args=()) p1.start() p2.start() p3.start() p4.start() p1.join() p2.join() p3.join() p4.join() self.slider.setValue(self.idx) self.idx += self.skip def showImage(self): self.idx = self.slider.value() for i in range(len(self.video_list)): self.video_list[i].showImage(self.idx) def setFrameRate(self): delay, _ = QInputDialog.getDouble(self, 'Change Output Framerate...', 'New Framerate (frames/second)', 1000 / self.delay, 1, 100, 1) self.delay = 1000.0 / delay self.video_list[self.cur_video_id].setFrameRate(self.delay) def setSkipRate(self): self.skip, _ = QInputDialog.getInt(self, 'Change Skip Rate...', 'New Skip Rate', self.skip, 1, 10000, 1) self.video_list[self.cur_video_id].setSkipRate(self.skip) def boundEnd(self): self.endIdx = self.range_slider.end() def boundStart(self): self.startIdx = self.range_slider.start() self.idx = self.startIdx def setv1(self): self.cur_video_id = 0 self.statusBar().showMessage(f'Selected Video {self.cur_video_id+1}') def setv2(self): self.cur_video_id = 1 self.statusBar().showMessage(f'Selected Video {self.cur_video_id+1}') def setv3(self): self.cur_video_id = 2 self.statusBar().showMessage(f'Selected Video {self.cur_video_id+1}') def setv4(self): self.cur_video_id = 3 self.statusBar().showMessage(f'Selected Video {self.cur_video_id+1}') def pauseTimer(self): for i in range(len(self.video_list)): self.video_list[i].pauseTimer() def stopTimer(self): for i in range(len(self.video_list)): self.video_list[i].stopTimer() def fastForward(self): for i in range(len(self.video_list)): self.video_list[i].fastForward() def slowdown(self): for i in range(len(self.video_list)): self.video_list[i].slowdown() def calibrate(self): self.video_list[self.cur_video_id].setCalibrateMode() def export(self): with open('imglist.txt', 'w') as file_list: for idx in range(self.video_list[self.cur_video_id].startIdx, len(self.video_list[self.cur_video_id].img_list), self.video_list[self.cur_video_id].skip): print( f'file \'{self.video_list[self.cur_video_id].img_list[idx]}\'', file=file_list) framerate = 1000 / self.video_list[self.cur_video_id].delay if framerate == 1: ff = FFmpeg(inputs={'imglist.txt': f'-f concat -safe 0 -r 1'}, outputs={ 'timelapse.mp4': f'-vf "fps={framerate}" -c:v libx264' }) else: ff = FFmpeg(inputs={'imglist.txt': f'-f concat -safe 0'}, outputs={ 'timelapse.mp4': f'-vf "fps={framerate}" -c:v libx264' }) print(ff.cmd) ff.run()
class VideoFrame(QWidget): def __init__(self, *args, **kwargs): super(VideoFrame, self).__init__(*args, **kwargs) self.layout = QVBoxLayout() self.img_list = [] # VIDEO LABEL AREA self.label = QLabel('Nothing to show right now.', self) self.label.setAlignment(Qt.AlignCenter) self.label.setGeometry(30, 20, 750, 360) self.layout.addWidget(self.label) # PLAY BUTTON self.play = QPushButton(self) icon = QPixmap( os.path.join(os.path.dirname(__file__), 'icons', 'play.png')) self.play.setIcon(QIcon(icon)) self.play.setGeometry(320, 370, 50, 30) self.play.clicked.connect(self.timerEvent) self.layout.addWidget(self.play) # PAUSE BUTTON self.pause = QPushButton(self) icon = QPixmap( os.path.join(os.path.dirname(__file__), 'icons', 'pause.png')) self.pause.setIcon(QIcon(icon)) self.pause.setGeometry(400, 370, 50, 30) self.pause.clicked.connect(self.pauseTimer) self.layout.addWidget(self.pause) # FAST-FORWARD self.ff = QPushButton(self) icon = QPixmap( os.path.join(os.path.dirname(__file__), 'icons', 'ff.png')) self.ff.setIcon(QIcon(icon)) self.ff.setGeometry(480, 370, 50, 30) self.ff.clicked.connect(self.fastForward) self.layout.addWidget(self.ff) # SLOWDOWN self.fr = QPushButton(self) icon = QPixmap( os.path.join(os.path.dirname(__file__), 'icons', 'fr.png')) self.fr.setIcon(QIcon(icon)) self.fr.setGeometry(240, 370, 50, 30) self.fr.clicked.connect(self.slowdown) self.layout.addWidget(self.fr) # SLIDER 1 self.slider = QSlider(Qt.Horizontal, self) self.layout.addWidget(self.slider) self.slider.setGeometry(10, 400, 825, 20) self.slider.valueChanged.connect(self.showImage) # RANGE SLIDER self.range_slider = QRangeSlider(self) self.range_slider.setFixedHeight(30) self.range_slider.setFixedWidth(825) self.range_slider.move(10, 420) self.range_slider.endValueChanged.connect(self.boundEnd) self.range_slider.startValueChanged.connect(self.boundStart) self.timer = QBasicTimer() # FIXME consider something with less lag self.startIdx = 0 self.endIdx = 0 self.idx = 0 self.delay = 1000 self.skip = 1 self.threadpool = QThreadPool() self.thread = None def size(self): return len(self.img_list) def boundEnd(self): self.endIdx = self.range_slider.end() def boundStart(self): self.startIdx = self.range_slider.start() self.idx = self.startIdx def setSkipRate(self, skip_rate): self.skip = skip_rate if self.thread is not None: self.thread.kwargs['skip'] = self.delay / 1000 def setFrameRate(self, delay): self.delay = delay if self.thread is not None: self.thread.kwargs['delay'] = self.delay / 1000 def setImgList(self, img_list): self.img_list = img_list self.endIdx = len(self.img_list) - 1 self.slider.setRange(0, len(self.img_list) - 1) self.range_slider.setMax(len(self.img_list) - 1) pixmap = QPixmap(self.img_list[self.idx]).scaled( 600, 800, Qt.KeepAspectRatio, Qt.FastTransformation) self.label.setPixmap(pixmap) def showImage(self): if len(self.img_list) == 0: return self.idx = self.slider.value() pixmap = QPixmap(self.img_list[self.idx]).scaled( 600, 800, Qt.KeepAspectRatio, Qt.FastTransformation) self.label.setPixmap(pixmap) def showImage(self, idx): if len(self.img_list) == 0 or idx > len(self.img_list) - 1: return self.idx = idx self.slider.setValue(idx) pixmap = QPixmap(self.img_list[idx]).scaled(600, 800, Qt.KeepAspectRatio, Qt.FastTransformation) self.label.setPixmap(pixmap) def timerEvent(self): self.thread = DelayWorker(self.startIdx, self.endIdx, delay=self.delay, skip=self.skip) self.thread.signals.idx.connect(self.showImage) self.threadpool.start(self.thread) # if len(self.img_list) == 0: # return # if self.idx > self.endIdx: # self.timer.stop() # self.idx = self.startIdx # return # self.timer.start(self.delay, self) # pixmap = QPixmap(self.img_list[self.idx]).scaled(600, 800, Qt.KeepAspectRatio, Qt.FastTransformation) # self.label.setPixmap(pixmap) # self.slider.setValue(self.idx) # self.idx += self.skip def pauseTimer(self): self.thread.stop = True self.startIdx = self.idx def fastForward(self): if len(self.img_list) == 0: return self.thread.kwargs['delay'] /= 2 def slowdown(self): if len(self.img_list) == 0: return self.thread.kwargs['delay'] *= 2
class MainWindow(QMainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.setWindowIcon(QIcon(os.path.join(os.path.dirname(__file__), 'icons', 'plant.png'))) self.setWindowTitle("Video Comparison GUI") self.statusBar() self.img_list = None self.cur_video_id = 0 self.layout = QGridLayout() # Main Widget Init self.widget = QWidget() self.widget.setLayout(self.layout) self.setCentralWidget(self.widget) self.setGeometry(250, 50, 1920, 1080) # Open File Dialog openFile = QAction('Open Image Directory', self) openFile.setShortcut('Ctrl+O') openFile.setStatusTip('Open Image Directory') openFile.triggered.connect(self.fileDialog) change_framerate = QAction('Change Framerate...', self) change_framerate.setStatusTip('Change Playback Framerate of Video (default: 1 frame/sec)') change_framerate.triggered.connect(self.setFrameRate) change_skiprate = QAction('Change Skip Rate...', self) change_skiprate.setStatusTip('Change Frame Skip Rate in Selected Photos (default: 1)') change_skiprate.triggered.connect(self.setSkipRate) set_v_1 = QAction('Video 1...', self) set_v_1.setStatusTip('Set Video 1 (Top Left Corner) Settings') set_v_1.triggered.connect(self.setv1) set_v_2 = QAction('Video 2...', self) set_v_2.setStatusTip('Set Video 2 (Top Right Corner) Settings') set_v_2.triggered.connect(self.setv2) set_v_3 = QAction('Video 3...', self) set_v_3.setStatusTip('Set Video 3 (Bottom Left Corner) Settings') set_v_3.triggered.connect(self.setv3) set_v_4 = QAction('Video 4...', self) set_v_4.setStatusTip('Set Video 4 (Bottom Right Corner) Settings') set_v_4.triggered.connect(self.setv4) # Menu Bar menubar = self.menuBar() file_menu = menubar.addMenu('&File') file_menu.addAction(openFile) edit_menu = menubar.addMenu('&Edit') edit_menu.addAction(change_framerate) edit_menu.addAction(change_skiprate) video_menu = menubar.addMenu('&Video') video_menu.addAction(set_v_1) video_menu.addAction(set_v_2) video_menu.addAction(set_v_3) video_menu.addAction(set_v_4) # Video Frame Objects self.v1 = VideoFrame() self.layout.addWidget(self.v1, 0, 0, 1, 2) self.v2 = VideoFrame() self.layout.addWidget(self.v2, 0, 2, 1, 2) self.v3 = VideoFrame() self.layout.addWidget(self.v3, 1, 0, 1, 2) self.v4 = VideoFrame() self.layout.addWidget(self.v4, 1, 2, 1, 2) self.video_list = [self.v1, self.v2, self.v3, self.v4] ## STREAM 1 LABEL AREA #self.label = QLabel('Nothing to show right now.') #self.label.setAlignment(Qt.AlignCenter) #self.layout.addWidget(self.label) self.bottomLayout = QVBoxLayout() # GLOBAL PLAY BUTTON #self.play = QPushButton("Play") #self.play.clicked.connect(self.timerEvent) #self.bottomLayout.addWidget(self.play) # SLOWDOWN self.fr = QPushButton(self) icon = QPixmap(os.path.join(os.path.dirname(__file__), 'icons', 'fr.png')) self.fr.setIcon(QIcon(icon)) self.fr.clicked.connect(self.slowdown) self.layout.addWidget(self.fr, 2, 0, 1, 1) # GLOBAL PLAY BUTTON self.play = QPushButton(self) icon = QPixmap(os.path.join(os.path.dirname(__file__), 'icons', 'play.png')) self.play.setIcon(QIcon(icon)) self.play.clicked.connect(self.playVideos) self.layout.addWidget(self.play, 2, 1, 1, 1) # GLOBAL PAUSE BUTTON self.pause = QPushButton(self) icon = QPixmap(os.path.join(os.path.dirname(__file__), 'icons', 'pause.png')) self.pause.setIcon(QIcon(icon)) self.pause.clicked.connect(self.pauseTimer) self.layout.addWidget(self.pause, 2, 2, 1, 1) # GLOBAL FAST-FORWARD self.ff = QPushButton(self) icon = QPixmap(os.path.join(os.path.dirname(__file__), 'icons', 'ff.png')) self.ff.setIcon(QIcon(icon)) self.ff.clicked.connect(self.fastForward) self.layout.addWidget(self.ff, 2, 3, 1, 1) # GLOBAL SLIDER self.slider = QSlider(Qt.Horizontal) self.bottomLayout.addWidget(self.slider) self.slider.valueChanged.connect(self.showImage) # GLOBAL RANGE SLIDER self.range_slider = QRangeSlider() self.range_slider.setFixedHeight(20) self.bottomLayout.addWidget(self.range_slider) self.range_slider.endValueChanged.connect(self.boundEnd) self.range_slider.startValueChanged.connect(self.boundStart) self.layout.addLayout(self.bottomLayout, 3, 0, 1, 4) self.timer = QBasicTimer() # FIXME consider something with less lag self.startIdx = 0 self.idx = 0 self.delay = 1000 self.skip = 1 self.threadpool = QThreadPool() def fileDialog(self): self.img_list, _ = QFileDialog.getOpenFileNames(self, 'Select one or more files to open', '/home', 'Images (*.jpg)') self.img_list.sort() self.video_list[self.cur_video_id].setImgList(self.img_list) self.endIdx = max(self.video_list, key=lambda end: end.size()-1) self.endIdx = self.endIdx.size()-1 self.slider.setRange(0, self.endIdx) self.range_slider.setMax(self.endIdx) def playVideos(self): #v1_thread = DelayWorker(self.v1.startIdx, self.v1.endIdx, # delay=self.v1.delay, skip=self.v1.skip) #v1_thread.signals.idx.connect(self.v1.showImage) #v2_thread = DelayWorker(self.v2.startIdx, self.v2.endIdx, # delay=self.v2.delay, skip=self.v2.skip) #v2_thread.signals.idx.connect(self.v2.showImage) #v3_thread = DelayWorker(self.v3.startIdx, self.v3.endIdx, # delay=self.v3.delay, skip=self.v3.skip) #v3_thread.signals.idx.connect(self.v3.showImage) #v4_thread = DelayWorker(self.v4.startIdx, self.v4.endIdx, # delay=self.v4.delay, skip=self.v4.skip) #v4_thread.signals.idx.connect(self.v4.showImage) #self.threadpool.start(v1_thread) #self.threadpool.start(v2_thread) #self.threadpool.start(v3_thread) #self.threadpool.start(v4_thread) #self.threadpool.start(v2_thread) self.v1.timerEvent() self.v2.timerEvent() self.v3.timerEvent() self.v4.timerEvent() #self.slider.setValue(self.idx) #self.idx += self.skip def showImage(self): self.idx = self.slider.value() for i in range(len(self.video_list)): self.video_list[i].showImage(self.idx) def setFrameRate(self): delay, _ = QInputDialog.getDouble(self, 'Change Framerate...', 'New Framerate (frames/second)', 1000/self.delay, 1, 100, 1) self.delay = 1000.0/delay self.video_list[self.cur_video_id].setFrameRate(self.delay) def setSkipRate(self): self.skip, _ = QInputDialog.getInt(self, 'Change Skip Rate...', 'New Skip Rate', self.skip, 1, 100, 1) self.video_list[self.cur_video_id].setSkipRate(self.skip) def boundEnd(self): self.endIdx = self.range_slider.end() def boundStart(self): self.startIdx = self.range_slider.start() self.idx = self.startIdx def setv1(self): self.cur_video_id = 0 self.statusBar().showMessage(f'Selected Video {self.cur_video_id+1}') def setv2(self): self.cur_video_id = 1 self.statusBar().showMessage(f'Selected Video {self.cur_video_id+1}') def setv3(self): self.cur_video_id = 2 self.statusBar().showMessage(f'Selected Video {self.cur_video_id+1}') def setv4(self): self.cur_video_id = 3 self.statusBar().showMessage(f'Selected Video {self.cur_video_id+1}') def pauseTimer(self): for i in range(len(self.video_list)): self.video_list[i].pauseTimer() def fastForward(self): for i in range(len(self.video_list)): self.video_list[i].fastForward() def slowdown(self): for i in range(len(self.video_list)): self.video_list[i].slowdown()