def add_widgets(self, layout, owner, controller): suffix_label = QLabel("Column Suffix", owner) self.suffix_box = QLineEdit(owner) transform_cols_label = QLabel("Columns to transform", owner) self.transformation_cols_box = ui_objects.ColumnList(owner, controller) perc_label = QLabel("Select quantile range to flag (inclusive)", owner) self.perc_slider = QRangeSlider(owner) layout.addWidget(suffix_label) layout.addWidget(self.suffix_box) layout.addWidget(transform_cols_label) layout.addWidget(self.transformation_cols_box) layout.addWidget(perc_label) layout.addWidget(self.perc_slider)
def make_slider_box(self, name,min,max): label = QLabel(name) qse = QRangeSlider() qse.setMax(max) qse.setMin(min) qle = QLabel("") #qle2 = QLineEdit() layout = QHBoxLayout() #qle.setEnabled(False) layout.addWidget(label) layout.addWidget(qse) layout.addWidget(qle) #layout.addWidget(qle2) #layout.addStretch(1) return (label,qse, qle,layout)
def make_slider_box(self, name, min, max, start, end): label = QLabel(name) qse = QRangeSlider() qse.setMax(max) qse.setMin(min) qse.setRange(start,end) layout = QHBoxLayout() layout.addWidget(label) layout.addWidget(qse) return (layout, qse)
def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.ui = Ui_Form() self.ui.setupUi(self) # area range slider self.area_RS = QRangeSlider() self.area_RS.setMin(0) self.area_RS.setMax(10000) self.area_RS.setRange(10, self.area_RS.max()) self.ui.area_layout.addWidget(self.area_RS) # self.area_RS.endValueChanged.connect(self.max_area_changed_callback) # self.area_RS.startValueChanged.connect(self.min_area_changed_callback) # density range slider self.density_RS = QRangeSlider() self.density_RS.setMin(-50) self.density_RS.setMax(1000) self.density_RS.setRange(10, self.density_RS.max()) self.ui.density_layout.addWidget(self.density_RS)
def make_slider_box(self, name,min,max): label = QLabel(name) qse = QRangeSlider() qse.setMax(max) qse.setMin(min) qle = QLabel("") #qle2 = QLineEdit() layout = QHBoxLayout() #qle.setEnabled(False) layout.addWidget(qse) layout.addWidget(qle) layout.addWidget(label) #layout.addWidget(qle2) #layout.addStretch(1) return (label,qse, qle,layout)
def __init__(self): QMainWindow.__init__(self) self.setMinimumSize(QSize(640,480)) self.setWindowTitle("Test") c = QWidget(self) self.setCentralWidget(c) #TODO: Add a Menu that allows user to select from certain preset filters (commonly used) mainMenu = self.menuBar() fileMenu = mainMenu.addMenu("&File") importAction = QAction("&Import Settings",self) importAction.setStatusTip("Import HSV Tolerances") importAction.triggered.connect(self.importRanges) exportAction = QAction("&Export Settings",self) exportAction.setStatusTip("Export Current Tolerances") exportAction.triggered.connect(self.exportRanges) fileMenu.addAction(importAction) fileMenu.addAction(exportAction) gridLayout = QGridLayout(self) c.setLayout(gridLayout) self.frame = QLabel(self) self.frame.resize(640, 480) gridLayout.addWidget(self.frame,0,0,4,4) self.th = vidThread() self.th.changePixmap.connect(self.setImage) self.th.start() #Initialize Range Sliders self.slider1 = QRangeSlider() self.slider1.setFixedHeight(15) self.slider2 = QRangeSlider(None,1) self.slider2.setFixedHeight(15) self.slider3 = QRangeSlider(None,2) self.slider3.setFixedHeight(15) gridLayout.addLayout(self.setupSlider(self.slider1, QLabel("Hue"),self.th.updateRange),5,0) gridLayout.addLayout(self.setupSlider(self.slider2, QLabel("Saturation"),self.th.updateRange),5,1) gridLayout.addLayout(self.setupSlider(self.slider3, QLabel("Value"),self.th.updateRange),5,2) self.slider1.drawValues()
def main(): config = { 'inputFolder': None, 'outputFolder': None, 'observationsFile': None, 'populationSize': 0, 'paramCount': 0, 'minparam': np.array([0,0]), 'maxparam':np.array([0,0]), } # init ui app = QApplication([]) window = QWidget() hlayout = QHBoxLayout() vlayout = QVBoxLayout() # buttons # -- set work folder. setWorkFolderBtn = QPushButton('Select Work folder') setWorkFolderBtn.clicked.connect(lambda: setFolderHandler(config,'inputFolder', window)) # -- sets output folder. setOutputFolderBtn = QPushButton("Select Output folder") setOutputFolderBtn.clicked.connect(lambda: setFolderHandler(config, 'outputFolder', window)) # -- set observations file path setObservationsFileBtn = QPushButton("Select Observations") setObservationsFileBtn.clicked.connect(lambda: setFolderHandler(config, 'observationsFile', window, isFolder=False)) # -- set simulate button simulateBtn = QPushButton('Simulate') simulateBtn.clicked.connect(lambda: simulate(config)) # textboxes # -- set population count textbox populationCountTxt = QLineEdit() populationCountTxt.textChanged.connect(lambda text: setValueChangeHandler(text, config, 'populationSize', window)) # arrange components in ui vlayout.addWidget(setWorkFolderBtn) vlayout.addWidget(setOutputFolderBtn) vlayout.addWidget(setObservationsFileBtn) vlayout.addWidget(QLabel('Calibration Parameters')) populationFormSet = QHBoxLayout() populationFormSet.addWidget(QLabel('Population Size')) populationFormSet.addWidget(populationCountTxt) paramFormSet = QHBoxLayout() paramFormSet.addWidget(QLabel('Number of Parameters')) paramValue = QSlider(Qt.Horizontal) paramValue.valueChanged.connect(lambda value: setValueChangeHandler(value, config, 'paramCount', window)) paramFormSet.addWidget(paramValue) maxCalibFormSet = QHBoxLayout() maxCalibFormSet.addWidget(QLabel('Max Calibration')) maxRange = QRangeSlider() maxRange.setMin(0) maxRange.setMax(1) maxCalibFormSet.addWidget(maxRange) minCalibFormSet = QHBoxLayout() minCalibFormSet.addWidget(QLabel('Min Calibration')) minRange = QRangeSlider() minRange.setMin(0) minRange.setMax(1) minCalibFormSet.addWidget(minRange) vlayout.addLayout(populationFormSet) vlayout.addLayout(paramFormSet) vlayout.addLayout(maxCalibFormSet) vlayout.addLayout(minCalibFormSet) vlayout.addWidget(simulateBtn) hlayout.addLayout(vlayout) window.setLayout(hlayout); window.show() app.exec_() # add event handlers
class BinaryPercentileTransformation(Transformation): def __init__(self): super(BinaryPercentileTransformation).__init__() self.col_ids = [] self.name = "Binary (Percentile)" def add_widgets(self, layout, owner, controller): suffix_label = QLabel("Column Suffix", owner) self.suffix_box = QLineEdit(owner) transform_cols_label = QLabel("Columns to transform", owner) self.transformation_cols_box = ui_objects.ColumnList(owner, controller) perc_label = QLabel("Select quantile range to flag (inclusive)", owner) self.perc_slider = QRangeSlider(owner) layout.addWidget(suffix_label) layout.addWidget(self.suffix_box) layout.addWidget(transform_cols_label) layout.addWidget(self.transformation_cols_box) layout.addWidget(perc_label) layout.addWidget(self.perc_slider) def add_summary_widgets(self, box, controller): box.transformation = self box.tran_label.setText("Binary (Percentile)") box.lower_perc_label = QLabel("Lower Percentile:", box) box.lower_perc_label.setFont(controller.NORMAL_FONT) box.lower_perc = QLabel(str(self.lower_perc), box) box.lower_perc.setFont(controller.SMALL_FONT) box.upper_perc_label = QLabel("Upper Percentile:", box) box.upper_perc_label.setFont(controller.NORMAL_FONT) box.upper_perc = QLabel(str(self.upper_perc), box) box.upper_perc.setFont(controller.SMALL_FONT) box.transformation_cols_label = QLabel("Columns transformed:", box) box.transformation_cols_label.setFont(controller.NORMAL_FONT) box.transformation_cols = QListWidget(box) box.transformation_cols.addItems(self.col_ids) box.content_layout.addWidget(box.lower_perc_label) box.content_layout.addWidget(box.lower_perc) box.content_layout.addWidget(box.upper_perc_label) box.content_layout.addWidget(box.upper_perc) box.content_layout.addWidget(box.transformation_cols_label) box.content_layout.addWidget(box.transformation_cols) box.setFixedHeight(500) box.setFixedWidth(500) def validate_inputs(self, owner): self.suffix = self.suffix_box.text() self.transform_cols = [ x.text() for x in self.transformation_cols_box.selectedItems() ] self.lower_perc = self.perc_slider.getRange()[0] self.upper_perc = self.perc_slider.getRange()[1] if self.suffix == "": QMessageBox.about( owner, "Warning", "Please provide a valid suffix for the resulting column(s).") return False if len(self.transform_cols) == 0: QMessageBox.about( owner, "Warning", "Please select at least one column to transform.") return False return True def create_transformation(self, df): for col in self.transform_cols: col_name = self.generate_column_name(df, col + "_" + self.suffix) self.col_ids.append(col_name) numeric_col = pd.to_numeric(df[col], errors="coerce") lower_q = np.nanquantile(numeric_col, self.lower_perc / 100) upper_q = np.nanquantile(numeric_col, self.upper_perc / 100) new_col = np.where( np.logical_and(numeric_col >= lower_q, numeric_col <= upper_q), 1, 0) new_col = np.where(new_col == np.nan, np.nan, new_col) df[col_name] = new_col return df
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
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(QtGui.QMainWindow): def __init__(self): QtGui.QMainWindow.__init__(self) self.show() self.resize(400, 600) self.setWindowTitle("Neas") self._initMenuBar_() self.mainWidget = QtGui.QWidget() self.tabWidget = QtGui.QTabWidget() self.arrayMask = None self.maskIndex = 0 self.infoFile = None self.dataFile = None self.colorZero = [0.0, 0.0, 0.0] self.colorCoeff = [0.01, 0.01, 0.01] self.colorPow = [0.2, 1, 2] self.curMax = 100 self.setCentralWidget(self.mainWidget) self.mainWidget.setLayout(QtGui.QGridLayout()) self.graphicWidgetGrid = gl.GLViewWidget() self.graphicWidgetGrid.setCameraPosition(distance=50) self.graphicWidgetGrid.setBackgroundColor("w") self.graphicWidgetDisc = gl.GLViewWidget() self.graphicWidgetDisc.setCameraPosition(distance=50) self.graphicWidgetDisc.setBackgroundColor("w") self.tabWidget.addTab(self.graphicWidgetGrid, "Grid") self.tabWidget.addTab(self.graphicWidgetDisc, "Disc") # self.mainWidget.layout().addWidget(self.graphicWidget1, 0, 0, 2, 1) self.mainWidget.layout().addWidget(self.tabWidget, 0, 0, 2, 1) self.matrixLabel = QtGui.QLabel("", self) self.rangeSlider = QRangeSlider(self.mainWidget) self.rangeSlider.setFixedHeight(30) self.mainWidget.layout().addWidget(self.rangeSlider, 2, 0) tmp = QtGui.QGridLayout() tmp.setAlignment(QtCore.Qt.AlignTop) # tmp.addWidget(QtGui.QLabel('path to info file',self),0,0) # tmp.addWidget(QtGui.QPushButton("Change"),0,1) # tmp.addWidget(QtGui.QLabel('path to data file',self),1,0) # tmp.addWidget(QtGui.QPushButton("Change"),1,1) self.changeColorButton = QtGui.QPushButton("Change Colors") # self.changeColorButton.connect(self.changeColorButton,) self.changeColorButton.released.connect(self.buttonColorChange) tmp.addWidget(self.changeColorButton, 2, 0, 1, 3) for i in xrange(0, 3): colorLabel = QtGui.QLabel(["Red", "Green", "Blue"][i], self) colorLabel.setMaximumHeight(20) colorLabel.adjustSize() colorLabel.setAlignment(QtCore.Qt.AlignTop) tmp.addWidget(colorLabel, 3, i) # for i in xrange(0,3): # tmp2 = QtGui.QSlider(QtCore.Qt.Vertical) # tmp2.setFixedHeight(100) # tmp2.sliderMoved[int].connect([self.changeRedCoeff, self.changeBlueCoeff, self.changeGreenCoeff][i]) # tmp.addWidget(tmp2, 4, i) self.colorCoeffSpin = [] for i in xrange(0, 3): tmp2 = pg.SpinBox(value=[5, 3, 0][i], step=1) tmp2.setFixedWidth(60) tmp2.sigValueChanging.connect([self.changeRedCoeff, self.changeGreenCoeff, self.changeBlueCoeff][i]) self.colorCoeffSpin.append(tmp2) tmp.addWidget(tmp2, 4, i) for i in xrange(0, 3): tmp2 = pg.SpinBox(value=self.colorPow[i], step=0.1) tmp2.setFixedWidth(60) tmp2.sigValueChanging.connect( [self.changePowColorRed, self.changePowColorGreen, self.changePowColorBlue][i] ) tmp.addWidget(tmp2, 5, i) self.combobox = QtGui.QComboBox(self) self.combobox.addItem("Without anti aliasing") self.combobox.addItem("With anti aliasing") self.combobox.activated[int].connect(self.onComboActivated) tmp.addWidget(self.combobox, 6, 0, 1, 3) # self.arrayMaskLabel = QtGui.QLabel("") # self.arrayMaskLabel.adjustSize() # self.arrayMaskLabel.setAlignment(QtCore.Qt.AlignTop) np.set_printoptions(precision=2) # tmp.addWidget(self.arrayMaskLabel, 7, 0, 1, 3) self.onComboActivated(0) self.mainWidget.layout().addLayout(tmp, 0, 1) self.startPos = 0 self.endPos = 100 self.connect(self.rangeSlider, QtCore.SIGNAL("startValueChanged(int)"), self.setStart) self.connect(self.rangeSlider, QtCore.SIGNAL("endValueChanged(int)"), self.setEnd) self.graph3DGrid = None self.graph3DDisc = None def _initActions_(self): self.exitAction = QtGui.QAction(QtGui.QIcon("exit.png"), "&Exit", self) self.exitAction.setShortcut("Ctrl+Q") self.exitAction.setStatusTip("Exit application") self.exitAction.triggered.connect(QtGui.QApplication.quit) self.openInfoFileMenu = QtGui.QAction(QtGui.QIcon("open.png"), "Open info file", self) self.openInfoFileMenu.setStatusTip("Open info file") self.openInfoFileMenu.triggered.connect(self.loadInfoFileAction) self.openDataFileMenu = QtGui.QAction(QtGui.QIcon("open.png"), "Open data file", self) self.openDataFileMenu.setStatusTip("Open data file") self.openDataFileMenu.triggered.connect(self.loadDataFileAction) def _initMenuBar_(self): self._initActions_() menubar = self.menuBar() file_menu = menubar.addMenu("File") file_menu.addAction(self.openInfoFileMenu) file_menu.addAction(self.openDataFileMenu) file_menu.addAction(self.exitAction) def loadDataFile(self): fileName = QtGui.QFileDialog.getOpenFileName(self.show(), "Open file", "") if not fileName: return dataFile = open(fileName, "rb") result = np.fromfile(dataFile, dtype=np.uint32) # return result.reshape((self.infoFile['nt'], self.infoFile['nx'], self.infoFile['ny'])) return result.reshape((self.infoFile["nx"], self.infoFile["ny"], self.infoFile["nt"])) def loadDataFileAction(self): self.dataFile = self.loadDataFile() self.plotData() def loadInfoFile(self): fileName = QtGui.QFileDialog.getOpenFileName(self.show(), "Open file", "") if not fileName: return infoFile = open(fileName, "r") result = {} with infoFile: for row in utils.delimited(infoFile): tmp = row.split("=") if len(tmp) < 2: continue result[tmp[0].strip()] = utils.num(tmp[1]) print "info values:", result return result def loadInfoFileAction(self): self.infoFile = self.loadInfoFile() self.startPos = 0 self.endPos = self.infoFile["nt"] self.rangeSlider.setRange(0, self.infoFile["nt"]) self.rangeSlider.setMin(0) self.rangeSlider.setMax(self.infoFile["nt"]) self.rangeSlider.update() self.arrayMask = utils.arrayRing( (self.infoFile["nx"], self.infoFile["ny"]), (self.infoFile["nx"] / 2 - 1, self.infoFile["ny"] / 2 - 1), (50, self.infoFile["nx"] / 2 - 1), self.maskIndex, ) def onComboActivated(self, index): # tmp = utils.arrayRing((6, 6), (2, 2), (1,2), index) # self.arrayMaskLabel.setText(' ' + str(tmp).translate(None, '[]')) # self.arrayMaskLabel.adjustSize() self.maskIndex = index if not self.infoFile is None: # self.arrayMask = utils.arrayRing((self.infoFile['nx'], self.infoFile['ny']), # (self.infoFile['nx']/2-1, self.infoFile['ny']/2-1), # (50, self.infoFile['nx'] / 2 - 1), # self.maskIndex # ) # Uncomment code above and comment code below, for non-preview mode self.arrayMask = utils.arrayRing( (self.infoFile["nx"], self.infoFile["ny"]), (self.infoFile["nx"] / 2 - 1, self.infoFile["ny"] / 2 - 1), (self.infoFile["nx"] / 2 - 1, self.infoFile["nx"] / 2 + 50), self.maskIndex, ) self.plotData() def plotData(self): if self.dataFile is None: return # sliceSum = np.sum(self.dataFile[:][:][self.startPos:self.endPos], 0) sliceSum = np.sum(self.dataFile[:, :, self.startPos : self.endPos], 2) self.curMax = np.max(sliceSum) if self.graph3DGrid is None: # x = np.linspace(0,self.infoFile['nx'],self.infoFile['nx']) # y = np.linspace(0,self.infoFile['ny'],self.infoFile['ny']) # self.graph3D = gl.GLSurfacePlotItem(z=sliceSum, shader='shaded', computeNormals=False, smooth=False, glOptions='opaque') self.graph3DGrid = gl.GLSurfacePlotItem( z=sliceSum, shader="heightColor", computeNormals=False, smooth=False ) # self.graph3D.scale(16./49., 16./49., 1.0) # self.graph3D.translate(self.infoFile['nx']/2, self.infoFile['ny']/2, 3) # self.graph3D.rotate(-90, 0, 0, 0) self.graph3DGrid.translate(-18, 2, 0) # self.graph3D.translate(-1000,-700,-700) # self.graph3D.shader()['colorMap'] = [1, 1, 1, 1, 0.5, 1, 1, 0, 1] # self.graph3D.shader()['colorMap'] = np.array([0.2, 2, 0.5, 0.2, 1, 1, 0.2, 0, 2]) self.graphicWidgetGrid.addItem(self.graph3DGrid) # self.setGraph3DColor([0.01, 0.2, 0.5, 0.01, 0.1, 1, 0.01, 0, 2]) # self.setGraph3DColor([-0.001, 0.8, 0.5, -0.001, 0.9, 1, -0.001, 1, 2]) else: self.graph3DGrid.setData(z=sliceSum) if self.graph3DDisc is None: self.graph3DDisc = gl.GLSurfacePlotItem( z=sliceSum * self.arrayMask, shader="heightColor", computeNormals=False, smooth=False ) self.graph3DDisc.translate(-18, 2, 0) self.graphicWidgetDisc.addItem(self.graph3DDisc) self.changeRedCoeff(self.colorCoeffSpin[0]) self.changeGreenCoeff(self.colorCoeffSpin[1]) self.changeBlueCoeff(self.colorCoeffSpin[2]) else: self.graph3DDisc.setData(z=sliceSum * self.arrayMask) # self.graph3D.shader()['colorMap'] = np.array([0.001, 2, 0.5, 0.001, 0.7, 0.5, 0, 0, 1]) self.updateGraph3DColor() # print "Plotted" def updateGraph3DColor(self): # self.graph3DGrid.shader()['colorMap'] = np.array(color) if self.graph3DGrid is None: return # print [j for i in zip(self.colorCoeff,self.colorZero,self.colorPow) for j in i] self.graph3DGrid.shader()["colorMap"] = np.array( [j for i in zip(self.colorCoeff, self.colorZero, self.colorPow) for j in i] ) self.graph3DGrid.update() self.graph3DDisc.update() def setStart(self, pos): if pos != self.startPos: self.startPos = pos self.plotData() def setEnd(self, pos): if pos != self.endPos: self.endPos = pos self.plotData() def changeRedCoeff(self, spinBox): # self.colorCoeff[0] = value/100. # self.colorCoeff[0] = 1./self.curMax * 255 * value * 0.001 # self.colorCoeff[0] = 1./self.curMax * spinBox.value() self.colorCoeff[0] = 0.001 * spinBox.value() self.updateGraph3DColor() def changeGreenCoeff(self, spinBox): self.colorCoeff[1] = 0.001 * spinBox.value() self.updateGraph3DColor() def changeBlueCoeff(self, spinBox): self.colorCoeff[2] = 0.001 * spinBox.value() self.updateGraph3DColor() def buttonColorChange(self): colorZero = QtGui.QColorDialog(self).getColor() if colorZero is None: return self.colorZero = [colorZero.red() / 255.0, colorZero.green() / 255.0, colorZero.blue() / 255.0] self.updateGraph3DColor() def changePowColorRed(self, spinBox): self.colorPow[0] = spinBox.value() self.updateGraph3DColor() def changePowColorGreen(self, spinBox): self.colorPow[1] = spinBox.value() self.updateGraph3DColor() def changePowColorBlue(self, spinBox): self.colorPow[2] = spinBox.value() self.updateGraph3DColor()
def __init__(self): QtGui.QMainWindow.__init__(self) self.show() self.resize(400, 600) self.setWindowTitle("Neas") self._initMenuBar_() self.mainWidget = QtGui.QWidget() self.tabWidget = QtGui.QTabWidget() self.arrayMask = None self.maskIndex = 0 self.infoFile = None self.dataFile = None self.colorZero = [0.0, 0.0, 0.0] self.colorCoeff = [0.01, 0.01, 0.01] self.colorPow = [0.2, 1, 2] self.curMax = 100 self.setCentralWidget(self.mainWidget) self.mainWidget.setLayout(QtGui.QGridLayout()) self.graphicWidgetGrid = gl.GLViewWidget() self.graphicWidgetGrid.setCameraPosition(distance=50) self.graphicWidgetGrid.setBackgroundColor("w") self.graphicWidgetDisc = gl.GLViewWidget() self.graphicWidgetDisc.setCameraPosition(distance=50) self.graphicWidgetDisc.setBackgroundColor("w") self.tabWidget.addTab(self.graphicWidgetGrid, "Grid") self.tabWidget.addTab(self.graphicWidgetDisc, "Disc") # self.mainWidget.layout().addWidget(self.graphicWidget1, 0, 0, 2, 1) self.mainWidget.layout().addWidget(self.tabWidget, 0, 0, 2, 1) self.matrixLabel = QtGui.QLabel("", self) self.rangeSlider = QRangeSlider(self.mainWidget) self.rangeSlider.setFixedHeight(30) self.mainWidget.layout().addWidget(self.rangeSlider, 2, 0) tmp = QtGui.QGridLayout() tmp.setAlignment(QtCore.Qt.AlignTop) # tmp.addWidget(QtGui.QLabel('path to info file',self),0,0) # tmp.addWidget(QtGui.QPushButton("Change"),0,1) # tmp.addWidget(QtGui.QLabel('path to data file',self),1,0) # tmp.addWidget(QtGui.QPushButton("Change"),1,1) self.changeColorButton = QtGui.QPushButton("Change Colors") # self.changeColorButton.connect(self.changeColorButton,) self.changeColorButton.released.connect(self.buttonColorChange) tmp.addWidget(self.changeColorButton, 2, 0, 1, 3) for i in xrange(0, 3): colorLabel = QtGui.QLabel(["Red", "Green", "Blue"][i], self) colorLabel.setMaximumHeight(20) colorLabel.adjustSize() colorLabel.setAlignment(QtCore.Qt.AlignTop) tmp.addWidget(colorLabel, 3, i) # for i in xrange(0,3): # tmp2 = QtGui.QSlider(QtCore.Qt.Vertical) # tmp2.setFixedHeight(100) # tmp2.sliderMoved[int].connect([self.changeRedCoeff, self.changeBlueCoeff, self.changeGreenCoeff][i]) # tmp.addWidget(tmp2, 4, i) self.colorCoeffSpin = [] for i in xrange(0, 3): tmp2 = pg.SpinBox(value=[5, 3, 0][i], step=1) tmp2.setFixedWidth(60) tmp2.sigValueChanging.connect([self.changeRedCoeff, self.changeGreenCoeff, self.changeBlueCoeff][i]) self.colorCoeffSpin.append(tmp2) tmp.addWidget(tmp2, 4, i) for i in xrange(0, 3): tmp2 = pg.SpinBox(value=self.colorPow[i], step=0.1) tmp2.setFixedWidth(60) tmp2.sigValueChanging.connect( [self.changePowColorRed, self.changePowColorGreen, self.changePowColorBlue][i] ) tmp.addWidget(tmp2, 5, i) self.combobox = QtGui.QComboBox(self) self.combobox.addItem("Without anti aliasing") self.combobox.addItem("With anti aliasing") self.combobox.activated[int].connect(self.onComboActivated) tmp.addWidget(self.combobox, 6, 0, 1, 3) # self.arrayMaskLabel = QtGui.QLabel("") # self.arrayMaskLabel.adjustSize() # self.arrayMaskLabel.setAlignment(QtCore.Qt.AlignTop) np.set_printoptions(precision=2) # tmp.addWidget(self.arrayMaskLabel, 7, 0, 1, 3) self.onComboActivated(0) self.mainWidget.layout().addLayout(tmp, 0, 1) self.startPos = 0 self.endPos = 100 self.connect(self.rangeSlider, QtCore.SIGNAL("startValueChanged(int)"), self.setStart) self.connect(self.rangeSlider, QtCore.SIGNAL("endValueChanged(int)"), self.setEnd) self.graph3DGrid = None self.graph3DDisc = None
class Prototype(QWidget): def __init__(self, parent=None): super(Prototype, self).__init__(parent) # ================================================================================ # Window Setup # ================================================================================ self.setWindowTitle("Prototype Demo") self.setWindowFlags(Qt.WindowCloseButtonHint | Qt.WindowMinimizeButtonHint) # ================================================================================ # Variable Setup # ================================================================================ self.nissl_filename = config.NISSL_DEFAULT_FILE # ================================================================================ # UI Layout Preparation # ================================================================================ layout_main = QVBoxLayout() # ***** Vertical Layout (Main) # ***** Top Layout (Input Layout + Region Layout) layout_main.addLayout(self.get_layout_top()) # Set the main layout self.setLayout(layout_main) # ================================================================================ # Routines after UI Preparation # ================================================================================ self.refresh_image() # Set default image self.thread_match = MatchingThread(self) self.thread_match.startProgress.connect(self.on_thread_match_start) self.thread_match.updateProgress.connect(self.on_thread_match_update) self.thread_match.endProgress.connect(self.on_thread_match_end) ################################################################################## # UI Layout/Widget Routines ################################################################################## def get_layout_top(self): layout = QHBoxLayout() layout.addStretch(1) layout.addWidget(self.get_widget_input()) layout.addWidget(self.get_widget_region()) return layout def get_widget_input(self): canvas_box = QGroupBox("Input Image") layout = QVBoxLayout() # *** Button (Open File) self.btn_open = QPushButton("Open Nissl file") self.btn_open.clicked.connect(self.on_click_btn_open) layout.addWidget(self.btn_open) # *** Canvas (Input Image) self.canvas_input = Graph(self, width=1, height=8, dpi=500) self.canvas_input.corners_callback = self.on_canvas_input_corners_update layout.addWidget(self.canvas_input) canvas_box.setLayout(layout) return canvas_box def get_widget_region(self): canvas_box = QGroupBox("Selected Region") layout = QVBoxLayout() # ================================================================================ # ==================== Horizontal Layout (Matches Button + Add Entire Image Button) match_layout = QHBoxLayout() # *** Button (Find Best Match) self.btn_find_match = QPushButton("Find best matches") self.btn_find_match.clicked.connect(self.on_click_btn_find_match) self.btn_find_match.setEnabled(False) match_layout.addWidget(self.btn_find_match) self.btn_add_image = QPushButton("Add entire image") self.btn_add_image.clicked.connect(self.on_click_btn_add_image) match_layout.addWidget(self.btn_add_image) layout.addLayout(match_layout) # ==================== End Horizontal Layout (Match Layout) # ================================================================================ progress_layout = QHBoxLayout() # *** ProgressBar (Matching Completion) self.progressbar_match = QProgressBar() self.progressbar_match.setValue(0) progress_layout.addWidget(self.progressbar_match) layout.addLayout(progress_layout) # *** Label (Matching Status) self.label_match_status = QLabel( "Select a region you want to find a match for") layout.addWidget(self.label_match_status) # *** Canvas (Region Crops) self.canvas_region = Graph(self, width=5, height=5, dpi=100) self.canvas_region.is_interactive = False layout.addWidget(self.canvas_region) # *** Label (Ratio Test Distance) self.label_slider_ratio_test = QLabel("") layout.addWidget(self.label_slider_ratio_test) # *** Slider (Ratio Test Distance) self.slider_ratio_test = QSlider(Qt.Horizontal) self.slider_ratio_test.valueChanged.connect( self.on_slider_change_ratio_test) self.slider_ratio_test.setMinimum(0) self.slider_ratio_test.setMaximum(100) self.slider_ratio_test.setValue(int(config.DISTANCE_RATIO * 100)) self.slider_ratio_test.setTickPosition(QSlider.NoTicks) self.slider_ratio_test.setTickInterval(1) self.slider_ratio_test.setEnabled(False) layout.addWidget(self.slider_ratio_test) if (config.UI_ANGLE): # *** Label (Angle) self.label_angle = QLabel("Angle: 0") layout.addWidget(self.label_angle) # *** Slider (Angle) self.slider_angle = QSlider(Qt.Horizontal) self.slider_angle.valueChanged.connect(self.on_slider_change_angle) self.slider_angle.setMinimum(0) self.slider_angle.setMaximum(360) self.slider_angle.setTickPosition(QSlider.NoTicks) self.slider_angle.setTickInterval(1) self.slider_angle.setEnabled(False) layout.addWidget(self.slider_angle) if (config.UI_WARP): # *** Label (Warp Points) self.label_warp_points = QLabel("") layout.addWidget(self.label_warp_points) # *** Slider (Warp Points) self.slider_warp_points = QSlider(Qt.Horizontal) self.slider_warp_points.valueChanged.connect( self.on_slider_change_warp_points) self.slider_warp_points.setMinimum(3) self.slider_warp_points.setMaximum(50) self.slider_warp_points.setTickPosition(QSlider.NoTicks) self.slider_warp_points.setTickInterval(1) self.slider_warp_points.setValue(5) self.slider_warp_points.setEnabled(False) layout.addWidget(self.slider_warp_points) # *** Label (Warp Disp Min) self.label_warp_disp_min = QLabel("Min Displacement: ") layout.addWidget(self.label_warp_disp_min) # *** Label (Warp Disp Max) self.label_warp_disp_max = QLabel("Max Displacement: ") layout.addWidget(self.label_warp_disp_max) from qrangeslider import QRangeSlider self.slider_warp_disp = QRangeSlider() self.slider_warp_disp.setMin(0) self.slider_warp_disp.setMax(50) self.slider_warp_disp.setRange(1, 5) self.slider_warp_disp.setEnabled(False) layout.addWidget(self.slider_warp_disp) self.btn_warp = QPushButton("Warp") self.btn_warp.clicked.connect(self.on_click_btn_warp) self.btn_warp.setEnabled(False) layout.addWidget(self.btn_warp) self.btn_reset = QPushButton("Reset") self.btn_reset.clicked.connect(self.on_click_btn_reset) self.btn_reset.setEnabled(False) layout.addWidget(self.btn_reset) canvas_box.setLayout(layout) return canvas_box ################################################################################## # Slider Events ################################################################################## def on_slider_change_ratio_test(self): new_ratio = float(self.slider_ratio_test.value() / 100.0) config.DISTANCE_RATIO = new_ratio self.label_slider_ratio_test.setText("Distance Ratio Test: " + str(config.DISTANCE_RATIO)) def on_slider_change_angle(self): angle = self.slider_angle.value() self.label_angle.setText("Angle: " + str(angle)) if self.canvas_region.im is not None: import scipy.misc im = scipy.misc.imrotate(self.region, angle) self.canvas_region.imshow(im) def on_slider_change_warp_points(self): points = self.slider_warp_points.value() self.label_warp_points.setText("Warp Points: " + str(points)) def on_slider_change_warp_min(self): pass def on_slider_change_warp_max(self): pass ################################################################################## # Class Functions ################################################################################## def refresh_image(self): im = util.im_read(self.nissl_filename) self.canvas_input.imshow(im) def set_im_region(self, im_region): logger.info("Image Region Shape: {0}", im_region.shape) w, h, c = im_region.shape # Reduce the size of images to a reasonable range #import scipy.misc as misc #reduction_percent = int(config.RESIZE_WIDTH/w * 100) #im_region = misc.imresize(im_region, reduction_percent) #logger.info("Resized region to {0}", im_region.shape) # Check if we should save the region for testing if config.UI_SAVE_REGION: util.im_write('region.jpg', im_region) # Save the original selection for actual matching self.region = im_region # Check if the user would like to see the region keypoints if config.UI_SHOW_KP: kp, des = sift.extract_sift(im_region) im_region = cv2.drawKeypoints( im_region, kp, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) self.canvas_region.imshow(im_region) self.canvas_input.clear_corners() self.btn_find_match.setEnabled(True) self.slider_ratio_test.setEnabled(True) if config.UI_WARP: self.btn_warp.setEnabled(True) self.btn_reset.setEnabled(True) self.slider_warp_points.setEnabled(True) self.slider_warp_disp.setEnabled(True) if config.UI_ANGLE: self.slider_angle.setEnabled(True) ################################################################################## # Canvas Events ################################################################################## def on_canvas_input_corners_update(self): count = len(self.canvas_input.corners) if count == 4: x, y = [], [] for corner in self.canvas_input.corners: # Numpy slicing uses integers x.append(corner[0].astype(np.uint64)) y.append(corner[1].astype(np.uint64)) x1, x2, y1, y2 = min(x), max(x), min(y), max(y) im_region = self.canvas_input.im[y1:y2, x1:x2].copy() self.set_im_region(im_region) # Redraw corner scatterplot return True ################################################################################## # Button Events ################################################################################## def on_click_btn_find_match(self): self.thread_match.set_im(self.region) self.thread_match.start() def on_click_btn_add_image(self): self.set_im_region(self.canvas_input.im.copy()) def on_click_btn_warp(self): min_disp = self.slider_warp_disp.getRange()[0] max_disp = self.slider_warp_disp.getRange()[1] im_warp = warping.warp(self.canvas_region.im, 5, min_disp, max_disp) self.canvas_region.imshow(im_warp) def on_click_btn_reset(self): self.set_im_region(self.region) def on_click_btn_open(self): new_filename, extra = QFileDialog.getOpenFileName( self, 'Open file', config.NISSL_DIR, "Image files (*.jpg *.png)") if new_filename: self.nissl_filename = new_filename self.refresh_image() ################################################################################## # Thread Events ################################################################################## def on_thread_match_start(self, total): self.progressbar_match.setMaximum(total) self.canvas_input.is_interactive = False self.btn_open.setEnabled(False) self.btn_find_match.setEnabled(False) self.btn_add_image.setEnabled(False) self.slider_ratio_test.setEnabled(False) if config.UI_ANGLE: self.slider_angle.setEnabled(False) # Timing timing.stopwatch() def on_thread_match_update(self, index): self.progressbar_match.setValue(index) self.label_match_status.setText("Matching with plate " + str(index)) def on_thread_match_end(self, matches): timing.stopwatch("Matching Time: ") self.canvas_input.is_interactive = True self.btn_open.setEnabled(True) self.btn_find_match.setEnabled(True) self.btn_add_image.setEnabled(True) self.slider_ratio_test.setEnabled(True) if config.UI_ANGLE: self.slider_angle.setEnabled(True) if len(matches) <= 0: self.label_match_status.setText("Didn't find a good match.") else: self.label_match_status.setText("Found " + str(len(matches)) + " possible matches") results_diag = ResultsDialog(self.nissl_filename, matches, self) results_diag.show()
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()
#!/usr/bin/env python import os import sys from PyQt4 import QtCore from PyQt4 import QtGui from PyQt4 import uic from qrangeslider import QRangeSlider app = QtGui.QApplication(sys.argv) # Example 1 rs1 = QRangeSlider() rs1.show() rs1.setWindowTitle('example 1') rs1.setRange(15, 35) rs1.setBackgroundStyle('background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #222, stop:1 #333);') rs1.setSpanStyle('background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #282, stop:1 #393);') # Example 2 rs2 = QRangeSlider() rs2.show() rs2.setWindowTitle('example 2') rs2.setFixedWidth(400) rs2.setFixedHeight(36) rs2.setMin(0) rs2.setMax(100) rs2.setRange(30, 80) rs2.setDrawValues(False)
class RangesliderZmq(QtGui.QWidget): def __init__(self): #app = QtGui.QApplication(sys.argv) super().__init__() self.gesture_dict = GestureDict() self.port = 5556 logging.basicConfig(level=logging.DEBUG, format='%(message)s') self.initUI() #sys.exit(app.exec_()) def initUI(self): port = self.port self.create_socket(port) range_label = QtGui.QLabel('events') self.range_events = QRangeSlider() self.range_events.show() self.range_events.setFixedWidth(300) self.range_events.setFixedHeight(36) self.range_events.setMin(0) self.range_events.setMax(4) self.range_events.setRange(0, 1) self.range_events.startValueChanged.connect( lambda: self.keep_slider_min(self.range_events)) hbox_events = QtGui.QHBoxLayout() hbox_events.addWidget(range_label) hbox_events.addWidget(self.range_events) self.textbox = QtGui.QLineEdit() self.update_btn = QtGui.QPushButton("update") self.update_btn.clicked.connect(lambda: self.button_click(port)) self.update_btn.setFixedWidth(100) hbox = QtGui.QHBoxLayout() hbox.addWidget(self.update_btn) magnitude_label = QtGui.QLabel('magnitude in g/10') self.range_magnitude = QRangeSlider() self.range_magnitude.show() self.range_magnitude.setFixedWidth(300) self.range_magnitude.setFixedHeight(36) self.range_magnitude.setMin(20) self.range_magnitude.setMax(80) self.range_magnitude.setRange(20, 30) hbox_magnitude = QtGui.QHBoxLayout() hbox_magnitude.addWidget(magnitude_label) hbox_magnitude.addWidget(self.range_magnitude) self.filter_length = QRangeSlider() self.filter_length.show() self.filter_length.setFixedWidth(300) self.filter_length.setFixedHeight(36) self.filter_length.setMin(0) self.filter_length.setMax(250) self.filter_length.setRange(0, 100) self.filter_length.startValueChanged.connect( lambda: self.keep_slider_min(self.filter_length)) filter_length_label = QtGui.QLabel('filter length in samples') hbox_length = QtGui.QHBoxLayout() hbox_length.addWidget(filter_length_label) hbox_length.addWidget(self.filter_length) self.message_label = QtGui.QLabel("messages will be here") self.exit_btn = QtGui.QPushButton('exit') self.exit_btn.clicked.connect( lambda: self.exit_click(self.socket, self.context, port)) vbox = QtGui.QVBoxLayout() vbox.addStretch(1) vbox.addLayout(hbox_events) vbox.addLayout(hbox_magnitude) vbox.addLayout(hbox_length) vbox.addWidget(self.message_label) vbox.addWidget(self.update_btn) vbox.addLayout(hbox) vbox.addWidget(self.exit_btn) self.setLayout(vbox) self.setGeometry(300, 300, 300, 150) self.setWindowTitle('rangesliders') self.show() @QtCore.pyqtSlot() def button_click(self, port): ''' handle button click event ''' try: self.update_gesture_dict() message = self.gesture_dict.make_json() logging.info('rangeslider sending message {}'.format(message)) self.socket.send_json(message, flags=zmq.NOBLOCK) except zmq.error.Again as e: logging.info('no receiver for the message: {}'.format(e)) # restart the socket if nothing to receive the message # if receiver closed, the socket needs to be restarted self.close_socket() self.create_socket(port) def close_socket(self): ''' close the socket and context ''' self.socket.close() self.context.term() def create_socket(self, port): ''' create a socket using pyzmq with PAIR context ''' self.context = zmq.Context() self.socket = self.context.socket(zmq.PAIR) self.socket.setsockopt(zmq.LINGER, 0) self.socket.bind("tcp://*:%s" % port) stream_pair = zmqstream.ZMQStream(self.socket) stream_pair.on_recv(self.process_message) def exit_click(self, socket, context, port): ''' handle exit button click ''' socket.close() context.term() sys.exit() def filter_length_change(self): ''' filter length slider has changed ''' length = self.filter_length.value() self.set_message_label('filter_length: {}'.format(length)) def keep_slider_min(self, slider): ''' keep the slider length minimum as one ''' try: slider.setStart(0) except RuntimeError as e: pass self.set_message_label('cannot change this') def process_message(self, msg): time = datetime.now() time = time.strftime('%H:%M:%S') text = ('{}: {}'.format(time, msg)) self.message_label.setText(text) def set_message_label(self, text): self.message_label.setText(text) def timer_timeout(self): ''' handle the QTimer timeout ''' try: msg = self.socket.recv(flags=zmq.NOBLOCK).decode() self.process_message(msg) except zmq.error.Again as e: return def update_gesture_dict(self): ''' get status of all the rangesliders into GestureDict object ''' magnitude_min, magnitude_max = self.range_magnitude.getRange() filter_length = self.filter_length.end() events = self.range_events.end() self.gesture_dict.update_dict(magnitude_min=magnitude_min, \ magnitude_max=magnitude_max/10, events=events, \ filter_length=filter_length)
def initUI(self): # ==================================== Set up window and wrapping layout self.setWindowTitle("Visualization") wrapper = QVBoxLayout() # ========================================== Set up FPS and error labels labels_layout = QHBoxLayout() self.label_error = QLabel("") self.label_fps = QLabel("") self.label_fps.setAlignment(Qt.AlignRight | Qt.AlignVCenter) labels_layout.addWidget(self.label_error) labels_layout.addStretch() labels_layout.addWidget(self.label_fps) # ================================================== Set up graph layout graph_view = pg.GraphicsView() graph_layout = pg.GraphicsLayout(border=(100,100,100)) graph_view.setCentralItem(graph_layout) # Mel filterbank plot fft_plot = graph_layout.addPlot(title='Filterbank Output', colspan=3) fft_plot.setRange(yRange=[-0.1, 1.2]) fft_plot.disableAutoRange(axis=pg.ViewBox.YAxis) x_data = np.array(range(1, config.N_FFT_BINS + 1)) self.mel_curve = pg.PlotCurveItem() self.mel_curve.setData(x=x_data, y=x_data*0) fft_plot.addItem(self.mel_curve) # Visualization plot graph_layout.nextRow() led_plot = graph_layout.addPlot(title='Visualization Output', colspan=3) led_plot.setRange(yRange=[-5, 260]) led_plot.disableAutoRange(axis=pg.ViewBox.YAxis) # Pen for each of the color channel curves r_pen = pg.mkPen((255, 30, 30, 200), width=4) g_pen = pg.mkPen((30, 255, 30, 200), width=4) b_pen = pg.mkPen((30, 30, 255, 200), width=4) # Color channel curves self.r_curve = pg.PlotCurveItem(pen=r_pen) self.g_curve = pg.PlotCurveItem(pen=g_pen) self.b_curve = pg.PlotCurveItem(pen=b_pen) # Define x data x_data = np.array(range(1, config.N_PIXELS + 1)) self.r_curve.setData(x=x_data, y=x_data*0) self.g_curve.setData(x=x_data, y=x_data*0) self.b_curve.setData(x=x_data, y=x_data*0) # Add curves to plot led_plot.addItem(self.r_curve) led_plot.addItem(self.g_curve) led_plot.addItem(self.b_curve) # ================================================= Set up button layout label_active = QLabel("Active Effect") button_grid = QGridLayout() buttons = {} connecting_funcs = {} grid_width = 4 i = 0 j = 0 # Dynamically layout buttons and connect them to the visualisation effects def connect_generator(effect): def func(): visualizer.current_effect = effect func.__name__ = effect return func # Where the magic happens for effect in visualizer.effects: connecting_funcs[effect] = connect_generator(effect) buttons[effect] = QPushButton(effect) buttons[effect].clicked.connect(connecting_funcs[effect]) button_grid.addWidget(buttons[effect], j, i) i += 1 if i % grid_width == 0: i = 0 j += 1 # ============================================== Set up frequency slider # Frequency range label label_slider = QLabel("Frequency Range") # Frequency slider def freq_slider_change(tick): minf = freq_slider.tickValue(0)**2.0 * (config.MIC_RATE / 2.0) maxf = freq_slider.tickValue(1)**2.0 * (config.MIC_RATE / 2.0) t = 'Frequency range: {:.0f} - {:.0f} Hz'.format(minf, maxf) freq_label.setText(t) config.MIN_FREQUENCY = minf config.MAX_FREQUENCY = maxf dsp.create_mel_bank() def set_freq_min(): config.MIN_FREQUENCY = freq_slider.start() dsp.create_mel_bank() def set_freq_max(): config.MAX_FREQUENCY = freq_slider.end() dsp.create_mel_bank() freq_slider = QRangeSlider() freq_slider.show() freq_slider.setMin(0) freq_slider.setMax(20000) freq_slider.setRange(config.MIN_FREQUENCY, config.MAX_FREQUENCY) freq_slider.setBackgroundStyle('background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #222, stop:1 #333);') freq_slider.setSpanStyle('background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #282, stop:1 #393);') freq_slider.setDrawValues(True) freq_slider.endValueChanged.connect(set_freq_max) freq_slider.startValueChanged.connect(set_freq_min) freq_slider.setStyleSheet(""" QRangeSlider * { border: 0px; padding: 0px; } QRangeSlider > QSplitter::handle { background: #fff; } QRangeSlider > QSplitter::handle:vertical { height: 3px; } QRangeSlider > QSplitter::handle:pressed { background: #ca5; } """) # ============================================ Set up option tabs layout label_options = QLabel("Effect Options") opts_tabs = QTabWidget() # Dynamically set up tabs tabs = {} grid_layouts = {} self.grid_layout_widgets = {} options = visualizer.effect_opts.keys() for effect in visualizer.effects: # Make the tab self.grid_layout_widgets[effect] = {} tabs[effect] = QWidget() grid_layouts[effect] = QGridLayout() tabs[effect].setLayout(grid_layouts[effect]) opts_tabs.addTab(tabs[effect],effect) # These functions make functions for the dynamic ui generation # YOU WANT-A DYNAMIC I GIVE-A YOU DYNAMIC! def gen_slider_valuechanger(effect, key): def func(): visualizer.effect_opts[effect][key] = self.grid_layout_widgets[effect][key].value() return func def gen_float_slider_valuechanger(effect, key): def func(): visualizer.effect_opts[effect][key] = self.grid_layout_widgets[effect][key].slider_value return func def gen_combobox_valuechanger(effect, key): def func(): visualizer.effect_opts[effect][key] = self.grid_layout_widgets[effect][key].currentText() visualizer._wavelength_set_color_mode(visualizer.effect_opts[effect][key]) return func def gen_checkbox_valuechanger(effect, key): def func(): visualizer.effect_opts[effect][key] = self.grid_layout_widgets[effect][key].isChecked() return func # Dynamically generate ui for settings if effect in visualizer.dynamic_effects_config: i = 0 connecting_funcs[effect] = {} for key, label, ui_element, opts in visualizer.dynamic_effects_config[effect][:]: if ui_element == "slider": connecting_funcs[effect][key] = gen_slider_valuechanger(effect, key) self.grid_layout_widgets[effect][key] = QSlider(Qt.Horizontal) self.grid_layout_widgets[effect][key].setMinimum(opts[0]) self.grid_layout_widgets[effect][key].setMaximum(opts[1]) self.grid_layout_widgets[effect][key].setValue(opts[2]) self.grid_layout_widgets[effect][key].valueChanged.connect( connecting_funcs[effect][key]) grid_layouts[effect].addWidget(QLabel(label),i,0) grid_layouts[effect].addWidget(self.grid_layout_widgets[effect][key],i,1) elif ui_element == "float_slider": connecting_funcs[effect][key] = gen_float_slider_valuechanger(effect, key) self.grid_layout_widgets[effect][key] = QFloatSlider(*opts) self.grid_layout_widgets[effect][key].valueChanged.connect( connecting_funcs[effect][key]) grid_layouts[effect].addWidget(QLabel(label),i,0) grid_layouts[effect].addWidget(self.grid_layout_widgets[effect][key],i,1) elif ui_element == "dropdown": connecting_funcs[effect][key] = gen_combobox_valuechanger(effect, key) self.grid_layout_widgets[effect][key] = QComboBox() self.grid_layout_widgets[effect][key].addItems(opts.keys()) self.grid_layout_widgets[effect][key].currentIndexChanged.connect( connecting_funcs[effect][key]) grid_layouts[effect].addWidget(QLabel(label),i,0) grid_layouts[effect].addWidget(self.grid_layout_widgets[effect][key],i,1) elif ui_element == "checkbox": connecting_funcs[effect][key] = gen_checkbox_valuechanger(effect, key) self.grid_layout_widgets[effect][key] = QCheckBox() #self.grid_layout_widgets[effect][key].addItems(opts.keys()) self.grid_layout_widgets[effect][key].stateChanged.connect( connecting_funcs[effect][key]) grid_layouts[effect].addWidget(QLabel(label),i,0) grid_layouts[effect].addWidget(self.grid_layout_widgets[effect][key],i,1) i += 1 #visualizer.effect_settings[effect] else: grid_layouts[effect].addWidget(QLabel("No customisable options for this effect :("),0,0) # ============================================= Add layouts into wrapper self.setLayout(wrapper) wrapper.addLayout(labels_layout) wrapper.addWidget(graph_view) wrapper.addWidget(label_active) wrapper.addLayout(button_grid) wrapper.addWidget(label_slider) wrapper.addWidget(freq_slider) wrapper.addWidget(label_options) wrapper.addWidget(opts_tabs) self.show()
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
#!/usr/bin/env python import os import sys from PyQt4 import QtCore from PyQt4 import QtGui from PyQt4 import uic from qrangeslider import QRangeSlider app = QtGui.QApplication(sys.argv) # Example 1 rs1 = QRangeSlider() rs1.show() rs1.setWindowTitle('example 1') rs1.setRange(15, 35) rs1.setBackgroundStyle( 'background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #222, stop:1 #333);' ) rs1.setSpanStyle( 'background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #282, stop:1 #393);' ) # Example 2 rs2 = QRangeSlider() rs2.show() rs2.setWindowTitle('example 2') rs2.setFixedWidth(400) rs2.setFixedHeight(36)
def get_widget_region(self): canvas_box = QGroupBox("Selected Region") layout = QVBoxLayout() # ================================================================================ # ==================== Horizontal Layout (Matches Button + Add Entire Image Button) match_layout = QHBoxLayout() # *** Button (Find Best Match) self.btn_find_match = QPushButton("Find best matches") self.btn_find_match.clicked.connect(self.on_click_btn_find_match) self.btn_find_match.setEnabled(False) match_layout.addWidget(self.btn_find_match) self.btn_add_image = QPushButton("Add entire image") self.btn_add_image.clicked.connect(self.on_click_btn_add_image) match_layout.addWidget(self.btn_add_image) layout.addLayout(match_layout) # ==================== End Horizontal Layout (Match Layout) # ================================================================================ progress_layout = QHBoxLayout() # *** ProgressBar (Matching Completion) self.progressbar_match = QProgressBar() self.progressbar_match.setValue(0) progress_layout.addWidget(self.progressbar_match) layout.addLayout(progress_layout) # *** Label (Matching Status) self.label_match_status = QLabel( "Select a region you want to find a match for") layout.addWidget(self.label_match_status) # *** Canvas (Region Crops) self.canvas_region = Graph(self, width=5, height=5, dpi=100) self.canvas_region.is_interactive = False layout.addWidget(self.canvas_region) # *** Label (Ratio Test Distance) self.label_slider_ratio_test = QLabel("") layout.addWidget(self.label_slider_ratio_test) # *** Slider (Ratio Test Distance) self.slider_ratio_test = QSlider(Qt.Horizontal) self.slider_ratio_test.valueChanged.connect( self.on_slider_change_ratio_test) self.slider_ratio_test.setMinimum(0) self.slider_ratio_test.setMaximum(100) self.slider_ratio_test.setValue(int(config.DISTANCE_RATIO * 100)) self.slider_ratio_test.setTickPosition(QSlider.NoTicks) self.slider_ratio_test.setTickInterval(1) self.slider_ratio_test.setEnabled(False) layout.addWidget(self.slider_ratio_test) if (config.UI_ANGLE): # *** Label (Angle) self.label_angle = QLabel("Angle: 0") layout.addWidget(self.label_angle) # *** Slider (Angle) self.slider_angle = QSlider(Qt.Horizontal) self.slider_angle.valueChanged.connect(self.on_slider_change_angle) self.slider_angle.setMinimum(0) self.slider_angle.setMaximum(360) self.slider_angle.setTickPosition(QSlider.NoTicks) self.slider_angle.setTickInterval(1) self.slider_angle.setEnabled(False) layout.addWidget(self.slider_angle) if (config.UI_WARP): # *** Label (Warp Points) self.label_warp_points = QLabel("") layout.addWidget(self.label_warp_points) # *** Slider (Warp Points) self.slider_warp_points = QSlider(Qt.Horizontal) self.slider_warp_points.valueChanged.connect( self.on_slider_change_warp_points) self.slider_warp_points.setMinimum(3) self.slider_warp_points.setMaximum(50) self.slider_warp_points.setTickPosition(QSlider.NoTicks) self.slider_warp_points.setTickInterval(1) self.slider_warp_points.setValue(5) self.slider_warp_points.setEnabled(False) layout.addWidget(self.slider_warp_points) # *** Label (Warp Disp Min) self.label_warp_disp_min = QLabel("Min Displacement: ") layout.addWidget(self.label_warp_disp_min) # *** Label (Warp Disp Max) self.label_warp_disp_max = QLabel("Max Displacement: ") layout.addWidget(self.label_warp_disp_max) from qrangeslider import QRangeSlider self.slider_warp_disp = QRangeSlider() self.slider_warp_disp.setMin(0) self.slider_warp_disp.setMax(50) self.slider_warp_disp.setRange(1, 5) self.slider_warp_disp.setEnabled(False) layout.addWidget(self.slider_warp_disp) self.btn_warp = QPushButton("Warp") self.btn_warp.clicked.connect(self.on_click_btn_warp) self.btn_warp.setEnabled(False) layout.addWidget(self.btn_warp) self.btn_reset = QPushButton("Reset") self.btn_reset.clicked.connect(self.on_click_btn_reset) self.btn_reset.setEnabled(False) layout.addWidget(self.btn_reset) canvas_box.setLayout(layout) return canvas_box
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
class Objects_widget(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.ui = Ui_Form() self.ui.setupUi(self) # area range slider self.area_RS = QRangeSlider() self.area_RS.setMin(0) self.area_RS.setMax(10000) self.area_RS.setRange(10, self.area_RS.max()) self.ui.area_layout.addWidget(self.area_RS) # self.area_RS.endValueChanged.connect(self.max_area_changed_callback) # self.area_RS.startValueChanged.connect(self.min_area_changed_callback) # density range slider self.density_RS = QRangeSlider() self.density_RS.setMin(-50) self.density_RS.setMax(1000) self.density_RS.setRange(10, self.density_RS.max()) self.ui.density_layout.addWidget(self.density_RS) # def max_area_changed_callback(self, value): # print 'max area changed to ', value # # def min_area_changed(self, value): # print 'min area changed to ', value def set_area_range(self, areas): self.area_RS.setMin(min(areas)) self.area_RS.setMax(max(areas)) self.area_RS.setRange() def set_density_range(self, densities): self.density_RS.setMin(min(densities)) self.density_RS.setMax(max(densities)) self.density_RS.setRange() def keyPressEvent(self, QKeyEvent): print 'hist widget key event: ', if QKeyEvent.key() == QtCore.Qt.Key_Escape: print 'Escape' if self.ui.objects_TV.selectedIndexes(): self.ui.objects_TV.clearSelection() else: self.close()
def initUI(self): port = self.port self.create_socket(port) range_label = QtGui.QLabel('events') self.range_events = QRangeSlider() self.range_events.show() self.range_events.setFixedWidth(300) self.range_events.setFixedHeight(36) self.range_events.setMin(0) self.range_events.setMax(4) self.range_events.setRange(0, 1) self.range_events.startValueChanged.connect( lambda: self.keep_slider_min(self.range_events)) hbox_events = QtGui.QHBoxLayout() hbox_events.addWidget(range_label) hbox_events.addWidget(self.range_events) self.textbox = QtGui.QLineEdit() self.update_btn = QtGui.QPushButton("update") self.update_btn.clicked.connect(lambda: self.button_click(port)) self.update_btn.setFixedWidth(100) hbox = QtGui.QHBoxLayout() hbox.addWidget(self.update_btn) magnitude_label = QtGui.QLabel('magnitude in g/10') self.range_magnitude = QRangeSlider() self.range_magnitude.show() self.range_magnitude.setFixedWidth(300) self.range_magnitude.setFixedHeight(36) self.range_magnitude.setMin(20) self.range_magnitude.setMax(80) self.range_magnitude.setRange(20, 30) hbox_magnitude = QtGui.QHBoxLayout() hbox_magnitude.addWidget(magnitude_label) hbox_magnitude.addWidget(self.range_magnitude) self.filter_length = QRangeSlider() self.filter_length.show() self.filter_length.setFixedWidth(300) self.filter_length.setFixedHeight(36) self.filter_length.setMin(0) self.filter_length.setMax(250) self.filter_length.setRange(0, 100) self.filter_length.startValueChanged.connect( lambda: self.keep_slider_min(self.filter_length)) filter_length_label = QtGui.QLabel('filter length in samples') hbox_length = QtGui.QHBoxLayout() hbox_length.addWidget(filter_length_label) hbox_length.addWidget(self.filter_length) self.message_label = QtGui.QLabel("messages will be here") self.exit_btn = QtGui.QPushButton('exit') self.exit_btn.clicked.connect( lambda: self.exit_click(self.socket, self.context, port)) vbox = QtGui.QVBoxLayout() vbox.addStretch(1) vbox.addLayout(hbox_events) vbox.addLayout(hbox_magnitude) vbox.addLayout(hbox_length) vbox.addWidget(self.message_label) vbox.addWidget(self.update_btn) vbox.addLayout(hbox) vbox.addWidget(self.exit_btn) self.setLayout(vbox) self.setGeometry(300, 300, 300, 150) self.setWindowTitle('rangesliders') self.show()
def setPlotTabLayout(self): # Create Plot Tab --------------------### # Create Layouts self.VLayout = QVBoxLayout() self.H1layout = QHBoxLayout() self.H1layout.setSpacing(15) self.H11layout = QHBoxLayout() self.H2layout = QHBoxLayout() self.V11layout = QVBoxLayout() self.V12layout = QVBoxLayout() self.V21layout = QVBoxLayout() self.V23layout = QVBoxLayout() self.V22layout = QVBoxLayout() #------------------------------------ # Create Widgets for H1layout # Create Browser self.plotter = SniffPlot(self.snifferConfig) self.rangeslider = QRangeSlider(self) self.filterGroup = QButtonGroup() self.localFilterRadio = QRadioButton('Local',self) self.globalFilterRadio = QRadioButton('Global', self) self.configureFilterButt = QPushButton('Configure Filter') self.createPlotButt = QPushButton('Create Plot') self.exportPlotButt = QPushButton('Export Plot') # We need to sync the UI before connecting any slots in order to prevent accidental stateChanges. self.syncUiToConfig() self.configureFilterButt.clicked.connect(self.configureFilter) self.createPlotButt.clicked.connect(self.createPlot) self.exportPlotButt.clicked.connect(self.exportPlot) self.localFilterRadio.clicked.connect(self.localRadioSelected) self.globalFilterRadio.clicked.connect(self.globalRadioSelected) self.H11layout.addWidget(self.localFilterRadio) self.H11layout.addWidget(self.globalFilterRadio) self.H11layout.addWidget(self.createPlotButt) self.H11layout.addWidget(self.exportPlotButt) self.V12layout.addLayout(self.H11layout) self.V12layout.addWidget(self.configureFilterButt) self.H1layout.addLayout(self.V11layout) self.H1layout.addStretch() self.H1layout.addLayout(self.V12layout) self.plotWindowStart=QDoubleSpinBox(self) self.plotWindowEnd=QDoubleSpinBox(self) self.plotWindowResetStart=QPushButton(self) self.plotWindowResetEnd=QPushButton(self) self.plotWindowResetStart.pressed.connect(self.plotter.resetStart) self.plotWindowResetEnd.pressed.connect(self.plotter.resetEnd) self.plotWindowResetStart.setText("R") self.plotWindowResetEnd.setText("R") self.plotWindowStart.setSuffix("ms") self.plotWindowEnd.setSuffix("ms") self.plotWindowStartLabel=QLabel(self) self.plotWindowDurationLabel=QLabel(self) self.plotWindowEndLabel=QLabel(self) self.applyRange=QPushButton(None) self.applyRange.setText("Apply Range") self.H2layout.addLayout(self.V21layout) self.H2layout.addWidget(self.plotWindowResetStart) self.H2layout.addStretch() self.H2layout.addLayout(self.V22layout) self.H2layout.addStretch() self.H2layout.addWidget(self.plotWindowResetEnd) self.H2layout.addLayout(self.V23layout) self.V21layout.addWidget(self.plotWindowStart) self.V21layout.addWidget(self.plotWindowStartLabel) self.V22layout.addWidget(self.applyRange) self.V22layout.addWidget(self.plotWindowDurationLabel) self.V23layout.addWidget(self.plotWindowEnd) self.V23layout.addWidget(self.plotWindowEndLabel) #------------------------------------ self.VLayout.addLayout(self.H1layout) self.VLayout.addWidget(self.plotter) self.VLayout.addWidget(self.rangeslider) self.VLayout.addLayout(self.H2layout) self.applyRange.pressed.connect(self.plotter.applyRange) self.plotter.setScrollbar(self.rangeslider) self.plotter.setWindowSpinner(self.plotWindowStart,self.plotWindowEnd) self.plotter.setRangeLabels(self.plotWindowStartLabel,self.plotWindowEndLabel,self.plotWindowDurationLabel) self.dockContents.setLayout(self.VLayout)
class Window(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.setMinimumSize(QSize(640,480)) self.setWindowTitle("Test") c = QWidget(self) self.setCentralWidget(c) #TODO: Add a Menu that allows user to select from certain preset filters (commonly used) mainMenu = self.menuBar() fileMenu = mainMenu.addMenu("&File") importAction = QAction("&Import Settings",self) importAction.setStatusTip("Import HSV Tolerances") importAction.triggered.connect(self.importRanges) exportAction = QAction("&Export Settings",self) exportAction.setStatusTip("Export Current Tolerances") exportAction.triggered.connect(self.exportRanges) fileMenu.addAction(importAction) fileMenu.addAction(exportAction) gridLayout = QGridLayout(self) c.setLayout(gridLayout) self.frame = QLabel(self) self.frame.resize(640, 480) gridLayout.addWidget(self.frame,0,0,4,4) self.th = vidThread() self.th.changePixmap.connect(self.setImage) self.th.start() #Initialize Range Sliders self.slider1 = QRangeSlider() self.slider1.setFixedHeight(15) self.slider2 = QRangeSlider(None,1) self.slider2.setFixedHeight(15) self.slider3 = QRangeSlider(None,2) self.slider3.setFixedHeight(15) gridLayout.addLayout(self.setupSlider(self.slider1, QLabel("Hue"),self.th.updateRange),5,0) gridLayout.addLayout(self.setupSlider(self.slider2, QLabel("Saturation"),self.th.updateRange),5,1) gridLayout.addLayout(self.setupSlider(self.slider3, QLabel("Value"),self.th.updateRange),5,2) self.slider1.drawValues() def setupSlider(self,slider, label,slot): slider.setMin(0) slider.setMax(255) slider.setEnd(255) slider.startValueChanged.connect(slot) slider.endValueChanged.connect(slot) tmp = QGridLayout(self) tmp.addWidget(label,0,0) tmp.addWidget(slider,1,0) return tmp @pyqtSlot(QImage) def setImage(self, image): self.frame.setPixmap(QPixmap.fromImage(image)) def importRanges(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog filename, tmp = QFileDialog.getOpenFileName(self,"QFileDialog.getOpenFileName()", "","All Files (*);;JSON Files (*.json)", options=options) if filename != "": f = open(filename,'r') data = json.load(f) else: return try: self.slider1.setRange(int(data['lower']['h']),int(data['upper']['h'])) self.slider2.setRange(int(data['lower']['s']),int(data['upper']['s'])) self.slider3.setRange(int(data['lower']['v']),int(data['upper']['v'])) except: print("Error Parsing JSON File, Values not imported") def exportRanges(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getSaveFileName(self, "QFileDialog.getSaveFileName()","","All Files (*);;JSON Files (*.json)", options=options) if fileName != "": f = open(fileName,'w') l1,l2,l3 = self.th.lBound r1,r2,r3 = self.th.rBound jString = "{{\"lower\": {{\"h\": \"{}\", \"s\": \"{}\", \"v\": \"{}\"}}, \"upper\": {{\"h\": \"{}\", \"s\": \"{}\", \"v\": \"{}\" }}}}".format(l1,l2,l3,r1,r2,r3) f.write(jString)
time.sleep(1) # wait a bit to be sure the roscore is really launched app = QApplication(sys.argv) window = QMainWindow() ui = Ui_RhagGUI() ui.setupUi(window) # # Example 1 # rs1 = QRangeSlider() # rs1.show() # rs1.setWindowTitle('example 1') # rs1.setRange(15, 35) # rs1.setBackgroundStyle('background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #222, stop:1 #333);') # rs1.setSpanStyle('background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #282, stop:1 #393);') # rs1 = QRangeSlider() ui.trajRange=QRangeSlider(ui.tab_2) # ui.trackFly = QtGui.QCheckBox(ui.tab_2) # ui.trajRange.setGeometry(QtCore.QRect(540, 47, 111, 22)) #functions for several buttons ui.trajRange.show() # rs1.setWindowTitle('example 1') ui.trajRange.setRange(15, 35) ui.trajRange.setBackgroundStyle('background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #222, stop:1 #333);') ui.trajRange.setSpanStyle('background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #282, stop:1 #393);') #applying and loading settings, closing etc. okBtn = ui.buttonBox.button(QtGui.QDialogButtonBox.Ok)#todo: Ok needs a function okBtn.clicked.connect(lambda : saveSettings(window, jsonVR)) #okBtn.clicked.connect(ui.statusbar.showMessage('Ok has no function yet')) cancelBtn = ui.buttonBox.button(QtGui.QDialogButtonBox.Cancel)
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()