def displayMetaDataSubWindow(self, tableTitle, dataset): """ Creates a subwindow that displays a DICOM image's metadata. """ try: logger.info('ViewMetaData.displayMetaDataSubWindow called.') title = "DICOM Image Metadata" widget = QWidget() widget.setLayout(QVBoxLayout()) metaDataSubWindow = QMdiSubWindow(self) metaDataSubWindow.setAttribute(Qt.WA_DeleteOnClose) metaDataSubWindow.setWidget(widget) metaDataSubWindow.setObjectName("metaData_Window") metaDataSubWindow.setWindowTitle(title) height, width = self.getMDIAreaDimensions() metaDataSubWindow.setGeometry(width * 0.4,0,width*0.6,height) lblImageName = QLabel('<H4>' + tableTitle + '</H4>') widget.layout().addWidget(lblImageName) DICOM_Metadata_Table_View = buildTableView(self, dataset) widget.layout().addWidget(DICOM_Metadata_Table_View) self.mdiArea.addSubWindow(metaDataSubWindow) metaDataSubWindow.show() except Exception as e: print('Error in : ViewMetaData.displayMetaDataSubWindow' + str(e)) logger.error('Error in : ViewMetaData.displayMetaDataSubWindow' + str(e))
def setupWindows(self): """ Set up QMdiArea parent and subwindows. Add available cameras on local system as items to list widget. """ # Create images directory if it does not already exist path = 'images' if not os.path.exists(path): os.makedirs(path) # Set up list widget that will display identified # cameras on your computer. picture_label = QLabel("Press 'Spacebar' to take pictures.") camera_label = QLabel("Available Cameras") self.camera_list_widget = QListWidget() self.camera_list_widget.setAlternatingRowColors(True) # Add availableCameras to a list to be displayed in # list widget. Use QCameraInfo() to list available cameras. self.cameras = list(QCameraInfo().availableCameras()) for camera in self.cameras: self.list_item = QListWidgetItem() self.list_item.setText(camera.deviceName()) self.camera_list_widget.addItem(self.list_item) # Create button that will allow user to select camera choose_cam_button = QPushButton("Select Camera") choose_cam_button.clicked.connect(self.selectCamera) # Create child widgets and layout for camera controls subwindow controls_gbox = QGroupBox() controls_gbox.setTitle("Camera Controls") v_box = QVBoxLayout() v_box.addWidget(picture_label, alignment=Qt.AlignCenter) v_box.addWidget(camera_label) v_box.addWidget(self.camera_list_widget) v_box.addWidget(choose_cam_button) controls_gbox.setLayout(v_box) controls_sub_window = QMdiSubWindow() controls_sub_window.setWidget(controls_gbox) controls_sub_window.setAttribute(Qt.WA_DeleteOnClose) # Create view finder subwindow self.view_finder_window = QMdiSubWindow() self.view_finder_window.setWindowTitle("Camera View") self.view_finder_window.setAttribute(Qt.WA_DeleteOnClose) # Create QMdiArea widget to manage subwindows mdi_area = QMdiArea() mdi_area.tileSubWindows() mdi_area.addSubWindow(self.view_finder_window) mdi_area.addSubWindow(controls_sub_window) # Set mdi_area widget as the central widget of main window self.setCentralWidget(mdi_area)
def onFileNew(self): newDoc = QMdiSubWindow(self) newDoc.setAttribute(Qt.WA_DeleteOnClose) newDoc.setWindowTitle('新文档 ' + str(self.newDocIndex)) self.newDocIndex += 1 newDoc.setWidget(QPlainTextEdit(newDoc)) self.mdiArea.addSubWindow(newDoc) newDoc.show()
def addWorkspaceMdiWindow(self, widget): window = QMdiSubWindow() window.setWidget(widget) window.setAttribute(Qt.WA_DeleteOnClose) window.setWindowIcon( QIcon(WorkspaceWidget.window_icons[widget._workspace_widget_type])) self.addSubWindow(window) window.show() widget.show()
def __on_open(self): window = QMdiSubWindow() window.setAttribute(Qt.WA_DeleteOnClose, True) window.setWindowTitle('Sub Window ' + str(MyMainWindow.window_index)) window.resize(300, 200) self.mdi_area.addSubWindow(window) window.show() MyMainWindow.window_index += 1
def treeItemClicked(self, item, column): tab = self.get_treeItem_tab(item.text(column)) if tab is not None: tab.setFocus() else: if item.text(column) == 'Perfmon': self.treeItemWindow_open(item) else: newDoc = QMdiSubWindow(self) newDoc.setAttribute(Qt.WA_DeleteOnClose) newDoc.setWindowTitle(item.text(column)) self.newDocIndex += 1 newDoc.setWidget(QPlainTextEdit( item.text(column) * 10, newDoc)) self.mdiArea.addSubWindow(newDoc) newDoc.show()
def treeItemWindow_open(self, item): title = item.text(0) subWind = QMdiSubWindow(self) subWind.setAttribute(Qt.WA_DeleteOnClose) subWind.setWindowTitle(title) self.newDocIndex += 1 mainWid = QWidget() l = QtWidgets.QVBoxLayout(mainWid) txtWind = QPlainTextEdit(mainWid) txtWind.setPlainText(f"perfmon.x = {item.x}, \n y = {item.y}") figWind = MyCanvas(mainWid, width=5, height=4, dpi=100, treeWidgetItem=item) l.addWidget(figWind) l.addWidget(txtWind) l.setStretch(0, 3) # 设置第一列的伸展比例为 3 l.setStretch(1, 1) # 设置第二列的伸展比例为 1, 这样2列的伸展比为3:1 subWind.setWidget(mainWid) self.mdiArea.addSubWindow(subWind) subWind.show()
class MDIWindow(QMainWindow): count = 0 def __init__(self): super().__init__() self.data_dict = {} self.mdi = QMdiArea() self.setCentralWidget(self.mdi) # self.mdi.resize(950,950) bar = self.menuBar() self.current_dir = None self.opened_wd_names = [] file = bar.addMenu("File") file.addAction("New") file.addAction("cascade") file.addAction("Tiled") file.triggered[QAction].connect(self.WindowTrig) load = bar.addMenu("Load") load.addAction("2D") load.addAction("3D") load.triggered[QAction].connect(self.dir_open) toolbar = QToolBar() self.addToolBar(toolbar) bw_button_action = QAction('base_wnd', self) bw_button_action.setStatusTip('base window button') bw_button_action.triggered.connect(self.onclicktb) toolbar.addAction(bw_button_action) self.setWindowTitle("MDI Application") self.base_wd = QMdiSubWindow() self.base_wd.setAttribute(Qt.WA_DeleteOnClose, False) self.base_wd.resize(400, 400) self.base_wd.plt_i = pg.PlotItem(labels={ 'left': ('slits', 'degrees'), 'bottom': ('Kin. Energy', 'eV') }) self.base_wd.plt_iv = pg.ImageView(view=self.base_wd.plt_i) self.base_wd.setWidget(self.base_wd.plt_iv) self.base_wd.setWindowTitle("plot window") self.mdi.addSubWindow(self.base_wd) self.base_wd.show() data_DockWidget = QDockWidget('data', self) data_DockWidget.setObjectName(('data window')) data_DockWidget.setAllowedAreas(Qt.RightDockWidgetArea) self.data_list = QListWidget() data_DockWidget.setWidget(self.data_list) self.addDockWidget(Qt.RightDockWidgetArea, data_DockWidget) self.data_list.itemClicked.connect(self.show_data) self.data_list.itemDoubleClicked.connect(self.get_data) self.mdi.subWindowActivated.connect(self.get_data) def WindowTrig(self, p): if p.text() == "New": MDIWindow.count = MDIWindow.count + 1 sub = QMdiSubWindow() sub.setWidget(QTextEdit()) sub.setWindowTitle("Sub Window" + str(MDIWindow.count)) self.mdi.addSubWindow(sub) sub.show() if p.text() == "cascade": self.mdi.cascadeSubWindows() if p.text() == "Tiled": self.mdi.tileSubWindows() def dir_open(self, p): self.current_dir = dlg.File_dlg.openDirNameDialog(self) print(self.current_dir) if p.text() == "2D": print('2D') files_ls = glob.glob(self.current_dir + '/*.ibw') fls = [f[len(self.current_dir) + 1:] for f in files_ls] print(files_ls) self.data_list.addItems(fls) if p.text() == "3D": zip_ls = glob.glob(self.current_dir + '/*.zip') zp = [f[len(self.current_dir) + 1:] for f in zip_ls] print(zp) self.data_list.addItems(zp) def show_data(self, s): print('show data') file_name = s.text() self.data_dict = ut.ibw2dict(self.current_dir + '/' + file_name) e_sc = self.data_dict['E_axis'][1] - self.data_dict['E_axis'][0] a_sc = self.data_dict['A_axis'][1] - self.data_dict['A_axis'][0] e_str = self.data_dict['E_axis'][0] a_str = self.data_dict['A_axis'][0] self.base_wd.plt_i.setRange(xRange=[self.data_dict['E_axis'][0], self.data_dict['E_axis'][-1]], \ yRange=[self.data_dict['A_axis'][0], self.data_dict['A_axis'][-1]], update=True, padding = 0) self.base_wd.plt_i.getViewBox().setLimits(xMin= e_str, xMax = self.data_dict['E_axis'][-1],\ yMin=self.data_dict['A_axis'][0], yMax=self.data_dict['A_axis'][-1]) self.base_wd.plt_iv.setImage( self.data_dict['data'], pos=[self.data_dict['E_axis'][0], self.data_dict['A_axis'][0]], scale=[e_sc, a_sc]) # self.base_wd.plt_iv.ui.histogram.hide() self.base_wd.plt_iv.ui.roiBtn.hide() self.base_wd.plt_iv.ui.menuBtn.hide() def get_data(self, s): if isinstance(s, QMdiSubWindow) and str( s.objectName()) in self.opened_wd_names: sub = self.mdi.currentSubWindow() self.data_dict = ut.ibw2dict(self.current_dir + '/' + str(s.objectName())) elif isinstance(s, QListWidgetItem): file_name = s.text() self.opened_wd_names.append(file_name) MDIWindow.count = MDIWindow.count + 1 sub = QMdiSubWindow() sub.resize(550, 550) sub.setWindowTitle(file_name) sub.setObjectName(file_name) self.data_dict = ut.ibw2dict(self.current_dir + '/' + file_name) else: print(isinstance(s, QMdiSubWindow), isinstance(s, QListWidgetItem)) print(type(s)) return e_sc = self.data_dict['E_axis'][1] - self.data_dict['E_axis'][0] a_sc = self.data_dict['A_axis'][1] - self.data_dict['A_axis'][0] e_rg = self.data_dict['E_axis'][-1] - self.data_dict['E_axis'][0] a_rg = self.data_dict['A_axis'][-1] - self.data_dict['A_axis'][0] e_str = self.data_dict['E_axis'][0] a_str = self.data_dict['A_axis'][0] e_end = self.data_dict['E_axis'][-1] a_end = self.data_dict['A_axis'][-1] print(e_str, a_str) print(e_end, a_end) print(e_rg, a_rg) print(e_sc, a_sc) gr_v = pg.GraphicsView() l = pg.GraphicsLayout() gr_v.setCentralWidget(l) sub.setWidget(gr_v) self.mdi.addSubWindow(sub) sub.show() p1 = l.addPlot(x=[1, 2], y=[1, 2], name="Plot1", title="EDC", pen="r", row=0, col=0) # label1 = pg.LabelItem(justify='right') # p1.addItem(label1) plt_i = pg.PlotItem(labels={ 'left': ('slits', 'degrees'), 'bottom': ('Kin. Energy', 'eV') }) plt_i.setRange(xRange=[e_str, e_end], yRange=[a_str, a_end], update=True, padding=0) vb = plt_i.getViewBox() vb.setLimits(xMin=e_str, xMax=e_end, yMin=a_str, yMax=a_end) vb.setMouseMode(vb.RectMode) l.addItem(plt_i, row=1, col=0) img_i = pg.ImageItem(self.data_dict['data'], border=None) qrect = vb.viewRect() img_i.setRect(qrect) vb.addItem(img_i) vb.autoRange() # vb.invertX() vb.invertY() hist = pg.HistogramLUTItem(image=img_i) l.addItem(hist, row=0, col=1) p2 = l.addPlot(x=[1, 2], y=[2, 1], name="Plot2", title="MDC", pen="g", row=1, col=1) # label2 = pg.LabelItem(justify='left') # plt_i.addItem(label2) # cross hair vLine = pg.InfiniteLine(angle=90, movable=False) hLine = pg.InfiniteLine(angle=0, movable=False) p1.addItem(vLine, ignoreBounds=False) p1.addItem(hLine, ignoreBounds=False) vb1 = p1.vb pcv = plt_i.addLine(x=e_end, pen='r') pch = plt_i.addLine(y=a_str, pen='r') # lROI = pg.ROI(((e_str+e_end)/2,a_str), size=(5*e_sc,a_rg)) # vb.addItem(lROI) # slice, coor = lROI.getArrayRegion(self.data_dict['data'], img_i ,returnMappedCoords = True) # print('slice') # sl_sum=np.sum(slice, axis=0) # print(sl_sum[0:10]) # print(type(slice), slice.shape) # print(type(coor), coor.shape) # print(coor[1,0,0:10]) # p2.invertY() # p2.setYLink(plt_i) # p2.plot(y=coor[1,0,:], x=sl_sum) def onMouseMoved(point): p = vb.mapSceneToView(point) pcv.setValue(p.x()) pch.setValue(p.y()) # print(p.x(), p.y()) hROI = pg.ROI((e_str, p.y()), size=(e_rg, 5 * a_sc)) vb.addItem(hROI) hROI.hide() sl, co = hROI.getArrayRegion(self.data_dict['data'], img_i, returnMappedCoords=True) sl_sum = np.sum(sl, axis=1) p1.setXLink(plt_i) p1.plot(x=co[0, :, 0], y=sl_sum, clear=True) vROI = pg.ROI((p.x(), a_str), size=(5 * e_sc, a_rg)) vb.addItem(vROI) vROI.hide() slc, coo = vROI.getArrayRegion(self.data_dict['data'], img_i, returnMappedCoords=True) sl_sum = np.sum(slc, axis=0) p2.invertY() p2.setYLink(plt_i) p2.plot(y=coo[1, 0, :], x=sl_sum, clear=True) # label2.setText("{}-{}".format(p.x(), p.y())) img_i.scene().sigMouseMoved.connect(onMouseMoved) def onclicktb(self): self.base_wd.plt_i = pg.PlotItem(labels={ 'left': ('slits', 'degrees'), 'bottom': ('Kin. Energy', 'eV') }) self.base_wd.plt_iv = pg.ImageView(view=self.base_wd.plt_i) self.base_wd.setWidget(self.base_wd.plt_iv) self.base_wd.show()
class Camera(QMainWindow): def __init__(self): super().__init__() self.initializeUI() def initializeUI(self): """ Initialize the window and display its contents to the screen """ self.setGeometry(100, 100, 600, 400) self.setWindowTitle('12.2 – Camera GUI') self.setupWindows() self.show() def setupWindows(self): """ Set up QMdiArea parent and subwindows. Add available cameras on local system as items to list widget. """ # Create images directory if it does not already exist path = 'images' if not os.path.exists(path): os.makedirs(path) # Set up list widget that will display identified # cameras on your computer. picture_label = QLabel("Press 'Spacebar' to take pictures.") camera_label = QLabel("Available Cameras") self.camera_list_widget = QListWidget() self.camera_list_widget.setAlternatingRowColors(True) # Add availableCameras to a list to be displayed in # list widget. Use QCameraInfo() to list available cameras. self.cameras = list(QCameraInfo().availableCameras()) for camera in self.cameras: self.list_item = QListWidgetItem() self.list_item.setText(camera.deviceName()) self.camera_list_widget.addItem(self.list_item) # Create button that will allow user to select camera choose_cam_button = QPushButton("Select Camera") choose_cam_button.clicked.connect(self.selectCamera) # Create child widgets and layout for camera controls subwindow controls_gbox = QGroupBox() controls_gbox.setTitle("Camera Controls") v_box = QVBoxLayout() v_box.addWidget(picture_label, alignment=Qt.AlignCenter) v_box.addWidget(camera_label) v_box.addWidget(self.camera_list_widget) v_box.addWidget(choose_cam_button) controls_gbox.setLayout(v_box) controls_sub_window = QMdiSubWindow() controls_sub_window.setWidget(controls_gbox) controls_sub_window.setAttribute(Qt.WA_DeleteOnClose) # Create view finder subwindow self.view_finder_window = QMdiSubWindow() self.view_finder_window.setWindowTitle("Camera View") self.view_finder_window.setAttribute(Qt.WA_DeleteOnClose) # Create QMdiArea widget to manage subwindows mdi_area = QMdiArea() mdi_area.tileSubWindows() mdi_area.addSubWindow(self.view_finder_window) mdi_area.addSubWindow(controls_sub_window) # Set mdi_area widget as the central widget of main window self.setCentralWidget(mdi_area) def setupCamera(self, cam_name): """ Create and setup camera functions. """ for camera in self.cameras: # Select camera by matching cam_name to one of the # devices in the cameras list. if camera.deviceName() == cam_name: self.cam = QCamera(camera) # Construct QCamera device # Create camera viewfinder widget and add it to the # view_finder_window. self.view_finder = QCameraViewfinder() self.view_finder_window.setWidget(self.view_finder) self.view_finder.show() # Sets the view finder to display video self.cam.setViewfinder(self.view_finder) # QCameraImageCapture() is used for taking # images or recordings. self.image_capture = QCameraImageCapture(self.cam) # Configure the camera to capture still images. self.cam.setCaptureMode(QCamera.CaptureStillImage) self.cam.start() # Slot to start the camera else: pass def selectCamera(self): """ Slot for selecting one of the available cameras displayed in list widget. """ try: if self.list_item.isSelected(): camera_name = self.list_item.text() self.setupCamera(camera_name) else: print("No camera selected.") pass except: print("No cameras detected.") def keyPressEvent(self, event): """ Handle the key press event so that the camera takes images. """ if event.key() == Qt.Key_Space: try: self.cam.searchAndLock() self.image_capture.capture("images/") self.cam.unlock() except: print("No camera in viewfinder.")
class GuiCam(QMainWindow): def __init__(self): super(GuiCam, self).__init__() self.cameras = [] self.cam_sync = True # Create Camera sub_window contents self.list_cameras = QListWidget() self.list_cameras.setAlternatingRowColors(True) self.button_select_camera = QPushButton("Select Camera") # Add availableCameras to a list to be displayed in list widget. # Use QCameraInfo() to auto detected local camera(s) and list available cameras. # cameras = QCameraInfo().availableCameras() # self.init_list(self.list_cameras, [cam.deviceName() for cam in list(cameras)]) # + list(videos)) self.init_list(self.list_cameras, ["Front Camera", "Real Camera"]) # + list(videos)) # dictionary data structure to construct camera filter functions tuning parameters self.functions = {thresholding: [["0: Disable Filter; 1:Active Filter", 1], ["0:gray; 1:Simple Thresholding; 2:Adaptive Thresholding", 0], ["Simple Thresholding: 0:BINARY; 1:BINARY_INV; 2:TRUNC; 3:TOZERO; " "4:TOZERO_INV; 5:THRESH_OTSU", 0], ["Simple Thresholding: Threshold value", 127], ["Kernel", 0]], smoothing: [["0: Disable Filter; 1:Active Filter", 1], ["0:Averaging; 1:Gaussian; 2:Median; 3: Bilateral; 4: De Noise", 0], ["", 0], ["", 0], ["Kernel", 0]], morphology: [["0: Disable Filter; 1:Active Filter", 1], ["0:Erosion; 1:Dilation; 2:Morphology; ", 0], ["Morphology Operator 0:Open;1:Close;2:GRADIENT;3:TOPHAT;4:BLACKHAT", 0], ["morph_element 0:RECT; 1:CROSS; 2:ELLIPSE", 0], ["Kernel", 0]], histograms: [["0: Disable Filter; 1:Active Filter", 1], ["0:Equalization; 1:adaptive equalization; 2:Contrast&Brightness; 3:gamma; " "4:low-light;", 0], ["alpha-contrast", 50], ["beta-brightness", 50], ["", 0]], arithmetic: [["0: Disable Filter; 1:Active Filter", 1], ["", 0], ["Scale", 0], ["alpha-contrast", 50], ["beta-brightness", 50]], transformations: [["0: Disable Filter; 1:Active Filter", 1], ["0:Scaling(select rect); 1:Perspective(by select 4 points); " "2:Affine(by select 3 points);", 0], ["Scaling factor", 0], ["", 0], ["", 0]], extraction: [["0: Disable Filter; 1:Active Filter", 1], ["", 0], ["", 0], ["", 0], ["", 0]], none: [["", 0], ["", 0], ["", 0], ["", 0], ["", 0]], } # hold camera filter functions # data struct: {function: [["description", value],,,]} self.spinbox_tip_value = [] # Camera AI parts self.models = [BarCode, Color, CascadeClassifier, Diff2frame, Diff3frame, Background, Lane, Face, HOGDescriptor, GoodFeature, Tracker, CamShift, Template, ColorShape, Feature, SimpleBlob, Caffe, Tensorflow, Yolo, GrabCut, Model, ] self.spin_boxes = [] # hold camera filter function parameters using spinbox value self.list_functions = QListWidget() self.list_functions.setAlternatingRowColors(True) self.button_select_filter = QPushButton("Select filter") self.dialog_color = QColorDialog() self.camera_contents = QWidget() self.dock_camera = QDockWidget() self.filter_contents = QWidget() self.dock_filter = QDockWidget() self.color_contents = QWidget() self.dock_color = QDockWidget() # Create Model sub_window contents # self.models = [] # hold AI models for objects detecting and tracing self.list_models = QListWidget() self.list_models.setAlternatingRowColors(True) self.button_select_model = QPushButton("Select Model") self.gbox_model = QGroupBox() self.sub_window_models = QMdiSubWindow() self.sub_window_models.setAttribute(Qt.WA_DeleteOnClose) self.sub_window_models.setWindowTitle("AI Model") # Create View sub_window contents self.label_image = QLabel() self.label_image.setAlignment(Qt.AlignTop) self.sub_window_view = QMdiSubWindow() self.sub_window_view.setAttribute(Qt.WA_DeleteOnClose) self.sub_window_view.setWindowTitle("View") # Create Menu Actions self.act_file_open = QAction(QIcon('images/open_file.png'), "Open", self) self.act_file_close = QAction(QIcon('images/close_file.png'), "Close", self) self.act_file_save = QAction(QIcon('images/save_file.png'), "Save", self) self.act_file_record = QAction(QIcon('images/record_file.png'), "Record", self) self.act_file_print = QAction(QIcon('images/print.png'), "Print", self) self.act_file_exit = QAction(QIcon('images/exit.png'), 'Exit', self) self.act_edit_image = QAction(QIcon('images/add_image.png'), "Add image", self) self.act_edit_logo = QAction(QIcon('images/add_logo.png'), "Add logo", self) self.init_ui() def init_ui(self): """ Initialize the window and display its contents to the screen """ # defines the location of the window on computer screen and its # dimensions, width and height. So the window we just started is located # at x=100,; y=100 in the window and has width=1600 and height=800 self.setGeometry(900, 100, 1600, 800) self.setWindowTitle('12.2 – Camera GUI') self.init_menu() self.init_toolbar() self.init_camera() self.init_filter() self.init_color() self.init_model() self.init_window() self.show() @staticmethod def init_list(list_widget, list_widget_items): list_widget.clear() for item_text in list_widget_items: item = QListWidgetItem() item.setText(str(item_text)) list_widget.addItem(item) def init_menu(self): """ Create menu for CVision GUI """ # Create actions for file menu self.act_file_open.setShortcut('Ctrl+O') self.act_file_open.setStatusTip('Open a new image/video') self.act_file_open.triggered.connect(self.open_file) self.act_file_close.setShortcut('Ctrl+E') self.act_file_close.setStatusTip('Close an image/video') self.act_file_close.triggered.connect(self.close_file) self.act_file_save.setShortcut('Ctrl+S') self.act_file_save.setStatusTip('Save image') self.act_file_save.triggered.connect(self.save_file) self.act_file_record.setShortcut('Ctrl+R') self.act_file_record.setStatusTip('Record video') self.act_file_record.triggered.connect(self.record_file) self.act_file_print.setShortcut('Ctrl+P') self.act_file_print.setStatusTip('Print image') self.act_file_print.triggered.connect(self.print) self.act_file_print.setEnabled(False) self.act_file_exit.setShortcut('Ctrl+Q') self.act_file_exit.setStatusTip('Quit program') self.act_file_exit.triggered.connect(self.exit) # Create actions for edit menu self.act_edit_image.setShortcut('Ctrl+A') self.act_edit_image.setStatusTip('Open a blend image') self.act_edit_image.triggered.connect(self.add_image) self.act_edit_logo.setShortcut('Ctrl+L') self.act_edit_logo.setStatusTip('Open a logo image') self.act_edit_logo.triggered.connect(self.add_logo) # Create menu_bar menu_bar = self.menuBar() menu_bar.setNativeMenuBar(False) # Create file menu and add actions file_menu = menu_bar.addMenu('File') file_menu.addAction(self.act_file_open) file_menu.addAction(self.act_file_close) file_menu.addAction(self.act_file_save) file_menu.addAction(self.act_file_record) file_menu.addSeparator() file_menu.addAction(self.act_file_print) file_menu.addSeparator() file_menu.addAction(self.act_file_exit) # Create edit menu and add actions edit_menu = menu_bar.addMenu('Edit') edit_menu.addAction(self.act_edit_image) edit_menu.addAction(self.act_edit_logo) # Create view menu and add actions view_menu = menu_bar.addMenu('View') view_menu.addAction(self.dock_camera.toggleViewAction()) view_menu.addAction(self.dock_filter.toggleViewAction()) view_menu.addAction(self.dock_color.toggleViewAction()) # Display info about shell, menu, and view in the status bar self.setStatusBar(QStatusBar(self)) def init_toolbar(self): """ Create toolbar for CVision GUI """ tool_bar = QToolBar("Photo Editor Toolbar") tool_bar.setIconSize(QSize(24, 24)) self.addToolBar(tool_bar) # Add actions to toolbar tool_bar.addAction(self.act_file_open) tool_bar.addAction(self.act_file_close) tool_bar.addAction(self.act_file_save) tool_bar.addAction(self.act_file_record) tool_bar.addAction(self.act_file_print) tool_bar.addSeparator() tool_bar.addAction(self.act_edit_image) tool_bar.addAction(self.act_edit_logo) # tool_bar.addAction(self.clear_act) tool_bar.addSeparator() tool_bar.addAction(self.act_file_exit) def open_file(self): """ Open an image file and display its contents in label widget. Display error message if image can't be opened. """ file, _ = QFileDialog.getOpenFileName(self, "Open Image", f"{CWD}//data//Sample//", "Video Files (*.mp4 *.avi );;" "JPG Files (*.jpeg *.jpg );;" "PNG Files (*.png);;" "Bitmap Files (*.bmp);;" "GIF Files (*.gif);;" "All Files (*)") if file: self.select_camera(file) else: QMessageBox.information(self, "Error", "Unable to open image.", QMessageBox.Ok) self.act_file_print.setEnabled(True) def add_image(self): """ Open an image file as back ground blending image. Display error message if image can't be opened. """ for cam in self.cameras: file, _ = QFileDialog.getOpenFileName(self, "Open Image", f"{CWD}//data//Sample//", "JPG Files (*.jpeg *.jpg );;" "PNG Files (*.png);;" "Bitmap Files (*.bmp);;" "GIF Files (*.gif)") if file: cam.image_background = cv2.imread(file) cam.register_filters(rotation, arithmetic) # add image arithmetic algorithm self.spinbox_tip_value = [["0: Disable Filter; 1:Active Filter", 1], ["", 0], ["Switch foreground/background image", 0], ["alpha", 127], ["beta", 50]] self.set_spinbox() else: QMessageBox.information(self, "Error", "Unable to add image.", QMessageBox.Ok) self.button_select_filter.setText(f"Select: Add Image") def add_logo(self): """ Open an image file as back ground blending image. Display error message if image can't be opened. """ for cam in self.cameras: file, _ = QFileDialog.getOpenFileName(self, "Open Logo", f"{CWD}//data//Sample//", "JPG Files (*.jpeg *.jpg );;" "PNG Files (*.png);;" "Bitmap Files (*.bmp);;" "GIF Files (*.gif)") if file: cam.image_logo = cv2.imread(file) # add logo icon cam.register_filters(rotation, arithmetic) # add image arithmetic algorithm self.spinbox_tip_value = [["0: Disable Filter; 1:Active Filter", 1], ["", 0], ["0:THRESH_BINARY; 1:THRESH_BINARY_INV", 0], ["threshold", 230], ["scale", 255]] self.set_spinbox() else: QMessageBox.information(self, "Error", "Unable to open logo image.", QMessageBox.Ok) self.button_select_filter.setText(f"Select: Add Logo") def close_file(self): self.stop_camera() self.cameras.clear() def save_file(self): for cam in self.cameras: cam.save_image(cam.filter_image) def record_file(self): for cam in self.cameras: cam.boolean_record = not cam.boolean_record def print(self): pass def exit(self): self.close_file() self.close() def init_camera(self): # Camera Control Dock layout_vbox_camera = QVBoxLayout() slider_spinbox_direction = SliderSpinBox("Angle", 360, self.update_angle) slider_spinbox_direction.setStatusTip("Rotate image") label_camera = QLabel("Available Cameras") # Create instances of radio buttons radio_sync = QRadioButton("Sync") radio_sync.setChecked(True) radio_sync.setStatusTip("Camera Capture in Main() thread") radio_sync.toggled.connect(lambda: self.radio_toggle(radio_sync)) radio_async = QRadioButton("Async") radio_async.setStatusTip("Camera Capture in respective thread") radio_async.toggled.connect(lambda: self.radio_toggle(radio_async)) # Set up layout and add child widgets to the layout radio_h_box = QHBoxLayout() radio_h_box.addWidget(label_camera) radio_h_box.addStretch() # used to help arrange widgets in a layout manager. radio_h_box.addWidget(radio_sync) radio_h_box.addWidget(radio_async) # Set a specific layout manager inside a parent window or widget radio_contents = QWidget() radio_contents.setLayout(radio_h_box) # Create button that will allow user to select camera self.button_select_camera.clicked.connect(self.select_camera) layout_vbox_camera.addWidget(radio_contents) layout_vbox_camera.addWidget(self.list_cameras) layout_vbox_camera.addWidget(slider_spinbox_direction) layout_vbox_camera.addWidget(self.button_select_camera) # Create child widgets and layout self.camera_contents.setLayout(layout_vbox_camera) def init_filter(self): # Camera Control Dock layout_vbox_filter = QVBoxLayout() label_filter = QLabel("Available Filters") # Set up layout and add child widgets to the layout label_h_filter = QLabel("Filter parameters") filter_h_box = QHBoxLayout() filter_h_box.addWidget(label_h_filter) # create 5 instances of QSpinBox class to hold camera filter function parameters for i in range(5): spinbox = QSpinBox() spinbox.setMaximum(255) spinbox.valueChanged.connect(self.update_filter_param) filter_h_box.addWidget(spinbox) self.spin_boxes.append(spinbox) # Set a specific layout manager inside a parent window or widget filter_contents = QWidget() filter_contents.setLayout(filter_h_box) # Create button that will allow user to select camera filter self.button_select_filter.clicked.connect(self.select_filter) self.button_select_filter.setDisabled(True) layout_vbox_filter.addWidget(label_filter) layout_vbox_filter.addWidget(self.list_functions) layout_vbox_filter.addWidget(filter_contents) # layout_vbox_camera.addWidget(slider_spinbox_filter) layout_vbox_filter.addWidget(self.button_select_filter) # Create child widgets and layout self.filter_contents.setLayout(layout_vbox_filter) def init_color(self): # Color Control Dock layout_vbox_color = QVBoxLayout() slider_spinbox_color = SliderSpinBox("Color %: ", 100, self.update_color_param) slider_spinbox_color.setStatusTip("Blend image background color") # Create instance of QColorDialog widget and pass the image as an argument to RGBSlider self.dialog_color.setOption(QColorDialog.NoButtons) self.dialog_color.currentColorChanged.connect(self.update_color) layout_vbox_color.addWidget(self.dialog_color) layout_vbox_color.addWidget(slider_spinbox_color) # Create child widgets and layout self.color_contents.setLayout(layout_vbox_color) def init_model(self): # Set up list widget that will display identified # models on your computer. label_model = QLabel("Available models") # Create button that will allow user to select model self.button_select_model.clicked.connect(self.select_models) self.button_select_model.setDisabled(True) # Create child widgets and layout for model controls sub_window layout_vbox_model = QVBoxLayout() layout_vbox_model.addWidget(label_model) layout_vbox_model.addWidget(self.list_models) layout_vbox_model.addWidget(self.button_select_model) # Create layout for model controls sub_window self.gbox_model.setTitle("Model Controls") self.gbox_model.setLayout(layout_vbox_model) def init_window(self): """ Set up QMdiArea parent and sub_windows. Add available cameras on local system as items to list widget. """ # Load image in sub_window_view self.load_image("images/chameleon.png") self.sub_window_view.setWidget(self.label_image) self.sub_window_models.setWidget(self.gbox_model) # Create QMdiArea widget to manage sub_windows mdi_area = QMdiArea() mdi_area.tileSubWindows() # mdi_area.addSubWindow(self.sub_window_camera) mdi_area.addSubWindow(self.sub_window_models) mdi_area.addSubWindow(self.sub_window_view) # Set up dock widget self.dock_camera.setWindowTitle("Camera Control") self.dock_camera.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.dock_camera.setWidget(self.camera_contents) self.dock_filter.setWindowTitle("Camera Filter") self.dock_filter.setWidget(self.filter_contents) self.dock_color.setWindowTitle("Camera Color") self.dock_color.setWidget(self.color_contents) self.dock_color.setVisible(False) # Set initial location of dock widget in main window self.addDockWidget(Qt.RightDockWidgetArea, self.dock_camera) self.addDockWidget(Qt.RightDockWidgetArea, self.dock_filter) self.addDockWidget(Qt.RightDockWidgetArea, self.dock_color) # Set mdi_area widget as the central widget of main window self.setCentralWidget(mdi_area) def load_image(self, image): try: with open(image): pixmap = QPixmap(image) self.label_image.setPixmap(pixmap) self.label_image.move(25, 40) except FileNotFoundError: print("Image not found.") def radio_toggle(self, radio): if radio.text() == "Sync" and radio.isChecked(): self.cam_sync = True else: self.cam_sync = False def select_camera(self, name=None): """ Slot for selecting one of the available cameras displayed in list widget. """ def camera(device_name): webcam = WebCam(device=device_name, sync=self.cam_sync) self.cameras.append(webcam) for webcam in self.cameras: webcam.register_filters(rotation, arithmetic, none) # srv = ('127.0.0.1', 61215, '10000000e7268f60') # webcam = WebCam(channel=0, service=srv, device=1, sync=False) # webcam.gui = self webcam.start() webcam.start_show() self.init_list(self.list_functions, [func.__name__ for func in list(self.functions.keys())]) self.button_select_filter.setEnabled(True) self.init_list(self.list_models, [model.name for model in self.models]) self.button_select_model.setEnabled(True) self.load_image("images/chenliru.jpg") try: for cam in self.cameras: cam.stop_show() # stop camera show if there is a camera instance already self.cameras.clear() if self.list_cameras.currentItem() is not None and not name: name = self.list_cameras.currentRow() camera(name) except Exception as e: print(f"No cameras detected {e}.") def stop_camera(self): for cam in self.cameras: cam.stop_show() # stop camera show if there is a camera instance already def select_models(self): """ Slot for selecting one of the available AI models displayed in list widget. """ position = self.list_models.currentRow() ai_model = self.models[position]() for cam in self.cameras: cam.register_models(ai_model) self.button_select_model.setText(f"Select: {ai_model.name}") def select_filter(self): """ Slot for selecting one of the available camera filters displayed in list widget. self.filters = ["log", "gamma", "hist", "yarcb"] """ position = self.list_functions.currentRow() funcs = [*self.functions.keys()] # get keys as list func = funcs[position] for cam in self.cameras: cam.register_filters(rotation, arithmetic, func) self.spinbox_tip_value = [*self.functions.values()][position] # get values as list self.set_spinbox() self.button_select_filter.setText(f"Select: {func.__name__}") def set_spinbox(self): tip = np.array(self.spinbox_tip_value)[:, 0] value = np.array(self.spinbox_tip_value)[:, 1] for i, spinbox in enumerate(self.spin_boxes): spinbox.setValue(int(value[i])) spinbox.setStatusTip(tip[i]) spinbox.setDisabled(True) if tip[i] == "" else spinbox.setEnabled(True) def update_filter_param(self): """ Slot for selecting one of the available camera filters parameters """ # pass for cam in self.cameras: for i in range(5): cam.filter_param[i] = self.spin_boxes[i].value() def update_angle(self, value): """ Slot for selecting one of the available camera installation direction """ for cam in self.cameras: cam.angle = value def update_color_param(self, value): """ Slot for updating camera color parameter. """ for cam in self.cameras: cam.color_param = value def update_color(self): """ Slot for selecting one of the available camera color """ for cam in self.cameras: rgb = list(self.dialog_color.currentColor().getRgb()) cam.color = rgb