コード例 #1
0
    def __init__(self):

        QWidget.__init__(self)

        self.title = u"执行"

        # View RunDef
        self.__wid_run_def = ViewRunDef()

        # View ReportDet
        self.__wid_report_det = ViewReportDet()

        # Search condition widget
        self.__wid_search_cond = ViewSearch(def_view_run_def)
        self.__wid_search_cond.create()

        # 底部 layout
        _layout_bottom = QSplitter()
        _layout_bottom.addWidget(self.__wid_run_def)
        _layout_bottom.addWidget(self.__wid_report_det)

        # main layout
        _layout = QVBoxLayout()
        _layout.addWidget(self.__wid_search_cond)
        _layout.addWidget(_layout_bottom)

        _layout.setContentsMargins(0, 0, 0, 0)

        self.setLayout(_layout)

        self.__wid_run_def.sig_search.connect(self.search)
        self.__wid_run_def.sig_selected.connect(
            self.__wid_report_det.usr_refresh)
コード例 #2
0
    def __init__(self, parent=None):
        """Create Qt widgets, connect event handlers."""

        super(App, self).__init__(parent)
        
        self.windowTitle = 'DMD | '
        self.fileName = ''
        
        self.setWindowTitle(self.windowTitle + 'Unsaved File')
        
        exitAction = QAction('Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(self.close)
        
        openAction = QAction('Open', self)
        openAction.setShortcut('Ctrl+O')
        openAction.setStatusTip('Open Markdown File')
        openAction.triggered.connect(self.openFile)
        
        newAction = QAction('New', self)
        newAction.setShortcut('Ctrl+N')
        newAction.setStatusTip('New Markdown File')
        newAction.triggered.connect(self.newFile)

        saveAction = QAction('Save', self)
        saveAction.setShortcut('Ctrl+S')
        saveAction.setStatusTip('Save File')
        saveAction.triggered.connect(self.saveFile)
        
        self.statusBar()

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        
        fileMenu.addAction(newAction)
        fileMenu.addAction(openAction)
        fileMenu.addAction(saveAction)
        fileMenu.addAction(exitAction)

        self.setGeometry(300, 300, 1024, 768)
        
        self.show()

        self.txtInput = QTextEdit()
        self.txtInput.setTabStopWidth(20)
        self.webPreview = QWebView()
        self.webPreview.setHtml('Start typing...', baseUrl=QUrl('preview'))
        
        self.txtInput.textChanged.connect(self.loadPreview)
        
        splitter = QSplitter()
        splitter.addWidget(self.txtInput)
        splitter.addWidget(self.webPreview)


        self.setCentralWidget(splitter)
コード例 #3
0
ファイル: plotter.py プロジェクト: Yakisoba007/PyTrigno
 def setCanvas(self):
     ''' set widgets for a tab page
      - left side show image of current frame
      - right side show two plots: raw and rms
      - bot: button to edit triggers and slider to adjust 
             video-emg offset
     '''
     
     ########################
     # set matplotlib plots #
     ########################
     self.fig = Figure(dpi=70)
     self.canvas = FigureCanvas(self.fig)
     self.canvas.setParent(self.ui.mainFrame)
     self.axes = self.fig.add_subplot(211)
     self.axesRMS = self.fig.add_subplot(212)
     self.mpl_toolbar = NavigationToolbar2(self.canvas, self.ui.mainFrame)
     self.canvas.mpl_connect('draw_event', self.onDraw)
     
     ####################################
     # add button to matplotlib toolbar #
     #################################### 
     redb = QPushButton('Edit Triggers')
     redb.setCheckable(True)
     self.mpl_toolbar.addWidget(redb)
     redb.clicked[bool].connect(self.toggleEditMode)
     
     # container for current frame of video 
     layout = pq.GraphicsLayoutWidget()
     vb = layout.addViewBox()
     vb.setAspectLocked(True)
     
     self.ri = pq.ImageItem()
     vb.addItem(self.ri)
     
     # layout to organize elements
     grid = QGridLayout()
     wrapper = QWidget()        
     vbox = QVBoxLayout(wrapper)
     splitter = QSplitter()
     
     vbox.addWidget(self.canvas)
     vbox.addWidget(self.mpl_toolbar)
     wrapper.setLayout(vbox)
     
     splitter.addWidget(layout)
     splitter.addWidget(wrapper)
     
     grid.addWidget(splitter)
     
     self.ri.show()
     layout.show()
     self.ui.mainFrame.setLayout(grid)
コード例 #4
0
    def __init__(self, options, parent=None):
        QWidget.__init__(self, parent)

        # Variables
        self._options = options

        # Widgets
        self._lbl_title = QLabel("Untitled")
        font = self._lbl_title.font()
        font.setBold(True)
        font.setPointSize(14)
        self._lbl_title.setFont(font)

        self._lbl_subtitle = QLabel("")
        font = self._lbl_subtitle.font()
        font.setItalic(True)
        font.setPointSize(14)
        self._lbl_subtitle.setFont(font)

        # Layouts
        layout = QVBoxLayout()

        sublayout = QHBoxLayout()
        sublayout.addWidget(self._lbl_title)
        sublayout.addStretch()
        sublayout.addWidget(self._lbl_subtitle)
        layout.addLayout(sublayout)

        wdglayout = QVBoxLayout()
        wdglayout.addLayout(self._initUI(), 1)
        wdglayout.addWidget(self._initToolbar())

        toolbox = self._initToolbox()
        if toolbox.count() == 0:
            layout.addLayout(wdglayout)
        else:
            wdg_dummy = QWidget()
            wdg_dummy.setLayout(wdglayout)

            splitter = QSplitter()
            splitter.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
            splitter.addWidget(wdg_dummy)
            splitter.addWidget(toolbox)
            splitter.setCollapsible(0, False)
            splitter.setCollapsible(1, True)
            layout.addWidget(splitter)

        self.setLayout(layout)
コード例 #5
0
    def setup_ui(self):
        splitter = QSplitter(self)
        left = QWidget(splitter)
        left.setLayout(QVBoxLayout(left))
        left.layout().addWidget(QLabel('QTableView', left))
        tableview = QTableView(left)
        tableview.setModel(TableModel(tableview))
        left.layout().addWidget(tableview)
        splitter.addWidget(left)
        right = QWidget(splitter)
        right.setLayout(QVBoxLayout(right))
        right.layout().addWidget(QLabel('QTableWidget', right))
        # create a table widget for DATA
        tablewidget = QTableWidget(len(DATA), len(DATA[1]), right)
        right.layout().addWidget(tablewidget)
        splitter.addWidget(right)
        self.setCentralWidget(splitter)

        # add tablewidget data
        self.add_data(tablewidget)
コード例 #6
0
    def setup_ui(self):
        splitter = QSplitter(self)
        left = QWidget(splitter)
        left.setLayout(QVBoxLayout(left))
        left.layout().addWidget(QLabel('QTableView', left))
        tableview = QTableView(left)
        tableview.setModel(TableModel(tableview))
        left.layout().addWidget(tableview)
        splitter.addWidget(left)
        right = QWidget(splitter)
        right.setLayout(QVBoxLayout(right))
        right.layout().addWidget(QLabel('QTableWidget', right))
        # create a table widget for DATA
        tablewidget = QTableWidget(len(DATA), len(DATA[1]), right)
        right.layout().addWidget(tablewidget)
        splitter.addWidget(right)
        self.setCentralWidget(splitter)

        # add tablewidget data
        self.add_data(tablewidget)
コード例 #7
0
    def __init__(self, *args, **kwargs):

        super(Widget_textEdit_splitter, self).__init__(*args, **kwargs)
        self.installEventFilter(self)
        mainLayout = QVBoxLayout(self)

        w_convertButton = QWidget()
        lay_convertButton = QHBoxLayout(w_convertButton)
        label_orig = QLabel("Original")
        label_orig.setAlignment(QtCore.Qt.AlignCenter)
        label_convert = QLabel("Converted")
        label_convert.setAlignment(QtCore.Qt.AlignCenter)
        button = QPushButton(" >> ")
        lay_convertButton.addWidget(label_orig)
        lay_convertButton.addWidget(button)
        lay_convertButton.addWidget(label_convert)
        w_convertButton.setStyleSheet("font-size:13px")
        sizePolicy = QSizePolicy()
        sizePolicy.setVerticalPolicy(QSizePolicy.Fixed)
        sizePolicy.setHorizontalPolicy(QSizePolicy.Expanding)
        w_convertButton.setSizePolicy(sizePolicy)

        splitter = QSplitter()
        splitter.setStretchFactor(1, 1)

        textEdit_left = QTextEdit()
        textEdit_right = QTextEdit()
        splitter.addWidget(textEdit_left)
        splitter.addWidget(textEdit_right)

        textEdit_left.setLineWrapMode(QTextEdit.NoWrap)
        textEdit_right.setLineWrapMode(QTextEdit.NoWrap)

        mainLayout.addWidget(w_convertButton)
        mainLayout.addWidget(splitter)

        self.textEdit_left = textEdit_left
        self.textEdit_right = textEdit_right

        button.clicked.connect(self.load_convertedText)
コード例 #8
0
ファイル: samplerender.py プロジェクト: penma/dicraft
    def __init__(self):
        super(Window, self).__init__()

        self.glWidget = GLWidget()

        renderarea = QSplitter(Qt.Vertical)
        renderarea.addWidget(self.glWidget)

        self.dummy_object = QLabel("wat")

        mainlayout = QVBoxLayout()
        splitter = QSplitter()
        splitter.addWidget(renderarea)
        splitter.addWidget(self.dummy_object)
        mainlayout.addWidget(splitter)
        self.setLayout(mainlayout)

        self.setWindowTitle("Hello GL")
コード例 #9
0
ファイル: samplerender.py プロジェクト: penma/dicraft
	def __init__(self):
		super(Window, self).__init__()

		self.glWidget = GLWidget()

		renderarea = QSplitter(Qt.Vertical)
		renderarea.addWidget(self.glWidget)

		self.dummy_object = QLabel("wat")

		mainlayout = QVBoxLayout()
		splitter = QSplitter()
		splitter.addWidget(renderarea)
		splitter.addWidget(self.dummy_object)
		mainlayout.addWidget(splitter)
		self.setLayout(mainlayout)

		self.setWindowTitle("Hello GL")
コード例 #10
0
ファイル: pdfMerger.py プロジェクト: nikolap/pdfmerger
    def __init__(self):
        QMainWindow.__init__(self)
        self.resize(800, 600)
        self.setWindowTitle('PDF Merger')

        about = QAction('About', self)
        self.connect(about, SIGNAL('triggered()'), self.show_about)
        exit = QAction('Exit', self)
        exit.setShortcut('Ctrl+Q')
        self.connect(exit, SIGNAL('triggered()'), SLOT('close()'))

        self.statusBar()
        menubar = self.menuBar()
        file = menubar.addMenu('File')
        file.addAction(about)
        file.addAction(exit)

        self.main_widget = QWidget(self)
        self.setCentralWidget(self.main_widget)
        self.up_down_widget = QWidget(self)
        self.options_widget = QWidget(self)

        input_files_label = QLabel(
            "Input PDFs\nThis is the order in which the files will be merged too"
        )
        self.files_list = QListWidget()
        self.files_list.setSelectionMode(QAbstractItemView.ExtendedSelection)
        add_button = QPushButton("Add PDF(s) to merge...")
        add_button.clicked.connect(self.clicked_add)
        up_button = QPushButton("Up")
        up_button.clicked.connect(self.move_file_up)
        down_button = QPushButton("Down")
        down_button.clicked.connect(self.move_file_down)
        remove_button = QPushButton("Remove PDF")
        remove_button.clicked.connect(self.remove_file)
        select_path_label = QLabel("Output PDF")
        self.dest_path_edit = QLineEdit()
        self.dest_path_edit.setReadOnly(True)
        select_path = QPushButton("Select...")
        select_path.clicked.connect(self.select_save_path)
        start = QPushButton("Start")
        start.clicked.connect(self.merge_pdf)

        up_down_vbox = QVBoxLayout(self.up_down_widget)
        up_down_vbox.addWidget(up_button)
        up_down_vbox.addWidget(down_button)
        up_down_vbox.addWidget(remove_button)
        self.up_down_widget.setLayout(up_down_vbox)

        group_input = QGroupBox()
        grid_input = QGridLayout()
        grid_input.addWidget(add_button, 0, 0)
        grid_input.addWidget(input_files_label, 1, 0)
        grid_input.addWidget(self.files_list, 2, 0)
        grid_input.addWidget(self.up_down_widget, 2, 1)
        group_input.setLayout(grid_input)

        group_output = QGroupBox()
        grid_output = QGridLayout()
        grid_output.addWidget(select_path_label, 0, 0)
        grid_output.addWidget(self.dest_path_edit, 1, 0)
        grid_output.addWidget(select_path, 1, 1)
        group_output.setLayout(grid_output)

        vbox_options = QVBoxLayout(self.options_widget)
        vbox_options.addWidget(group_input)
        vbox_options.addWidget(group_output)
        vbox_options.addWidget(start)
        self.options_widget.setLayout(vbox_options)

        splitter_filelist = QSplitter()
        splitter_filelist.setOrientation(Qt.Vertical)
        splitter_filelist.addWidget(self.options_widget)
        vbox_main = QVBoxLayout(self.main_widget)
        vbox_main.addWidget(splitter_filelist)
        vbox_main.setContentsMargins(0, 0, 0, 0)
コード例 #11
0
    def createElements(self):
        """
		Creates the widgets and docks of which the
		main window is composed.
		"""
        self.mainWindow = QMainWindow()
        projectController = ProjectController.Instance()
        self.transformTool = None

        # Render widgets
        self.fixedDataWidget = RenderWidget()
        self.movingDataWidget = RenderWidget()
        self.multiDataWidget = MultiRenderWidget()

        self.fixedRenderController = RenderController(self.fixedDataWidget,
                                                      "fixed")
        self.movingRenderController = RenderController(self.movingDataWidget,
                                                       "moving")
        self.multiRenderController = MultiRenderController(
            self.multiDataWidget)

        # Give references of the render controllers to the project controller
        projectController.fixedRenderController = self.fixedRenderController
        projectController.movingRenderController = self.movingRenderController
        projectController.multiRenderController = self.multiRenderController

        # Render properties widgets
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(1)

        self.fixedPropWidget = RenderPropWidget(self.fixedRenderController,
                                                parent=self)
        self.fixedPropWidget.setSizePolicy(sizePolicy)
        self.fixedPropWidget.setFileChangedSignal(
            projectController.fixedFileChanged)
        self.fixedPropWidget.setLoadDataSlot(self.loadFixedDataSetFile)

        self.movingPropWidget = RenderPropWidget(self.movingRenderController,
                                                 parent=self)
        self.movingPropWidget.setSizePolicy(sizePolicy)
        self.movingPropWidget.setFileChangedSignal(
            projectController.movingFileChanged)
        self.movingPropWidget.setLoadDataSlot(self.loadMovingDataSetFile)

        self.multiPropWidget = MultiRenderPropWidget(
            self.multiRenderController, parent=self)
        self.multiPropWidget.setSizePolicy(sizePolicy)

        self.verticalSplitter = QSplitter()
        self.verticalSplitter.setOrientation(Qt.Vertical)

        # Create the layouts

        fixedDataTitleWidget = TitleWidget("Fixed volume")
        multiDataTitleWidget = TitleWidget("Fixed + Moving")
        movingDataTitleWidget = TitleWidget("Moving volume")

        fixedLayout = QGridLayout()
        fixedLayout.setSpacing(0)
        fixedLayout.setContentsMargins(0, 0, 0, 0)
        fixedLayout.addWidget(fixedDataTitleWidget)
        fixedLayout.addWidget(self.fixedDataWidget)
        fixedWidget = QWidget()
        fixedWidget.setLayout(fixedLayout)

        multiLayout = QGridLayout()
        multiLayout.setSpacing(0)
        multiLayout.setContentsMargins(0, 0, 0, 0)
        multiLayout.addWidget(multiDataTitleWidget)
        multiLayout.addWidget(self.multiDataWidget)
        multiWidget = QWidget()
        multiWidget.setLayout(multiLayout)

        movingLayout = QGridLayout()
        movingLayout.setSpacing(0)
        movingLayout.setContentsMargins(0, 0, 0, 0)
        movingLayout.addWidget(movingDataTitleWidget)
        movingLayout.addWidget(self.movingDataWidget)
        movingWidget = QWidget()
        movingWidget.setLayout(movingLayout)

        horizontalSplitter = QSplitter()
        horizontalSplitter.setOrientation(Qt.Horizontal)
        horizontalSplitter.addWidget(fixedWidget)
        horizontalSplitter.addWidget(multiWidget)
        horizontalSplitter.addWidget(movingWidget)

        propsLayout = QHBoxLayout()
        propsLayout.setSpacing(1)
        propsLayout.setContentsMargins(0, 0, 0, 0)
        propsLayout.addWidget(self.fixedPropWidget)
        propsLayout.addWidget(self.multiPropWidget)
        propsLayout.addWidget(self.movingPropWidget)

        propsWidget = QWidget()
        propsWidget.setMinimumHeight(245)
        propsWidget.setMaximumHeight(350)
        propsWidget.setLayout(propsLayout)

        self.verticalSplitter.addWidget(horizontalSplitter)
        self.verticalSplitter.addWidget(propsWidget)
        self.verticalSplitter.setStretchFactor(0, 2)
        self.verticalSplitter.setStretchFactor(1, 1)
        self.setCentralWidget(self.verticalSplitter)
コード例 #12
0
ファイル: pdfMerger.py プロジェクト: nikolap/pdfmerger
	def __init__(self):
		QMainWindow.__init__(self)
		self.resize(800,600)
		self.setWindowTitle('PDF Merger')

		about = QAction('About', self)
		self.connect(about, SIGNAL('triggered()'), self.show_about)
		exit = QAction('Exit', self)
		exit.setShortcut('Ctrl+Q')
		self.connect(exit, SIGNAL('triggered()'), SLOT('close()'))

		self.statusBar()
		menubar = self.menuBar()
		file = menubar.addMenu('File')
		file.addAction(about)
		file.addAction(exit)

		self.main_widget = QWidget(self)
		self.setCentralWidget(self.main_widget)
		self.up_down_widget = QWidget(self)
		self.options_widget = QWidget(self)
		

		input_files_label = QLabel("Input PDFs\nThis is the order in which the files will be merged too")
		self.files_list = QListWidget()
		self.files_list.setSelectionMode(QAbstractItemView.ExtendedSelection)
		add_button = QPushButton("Add PDF(s) to merge...")
		add_button.clicked.connect(self.clicked_add)
		up_button = QPushButton("Up")
		up_button.clicked.connect(self.move_file_up)
		down_button = QPushButton("Down")
		down_button.clicked.connect(self.move_file_down)
		remove_button = QPushButton("Remove PDF")
		remove_button.clicked.connect(self.remove_file)
		select_path_label = QLabel("Output PDF")
		self.dest_path_edit = QLineEdit()
		self.dest_path_edit.setReadOnly(True)
		select_path = QPushButton("Select...")
		select_path.clicked.connect(self.select_save_path)
		start = QPushButton("Start")
		start.clicked.connect(self.merge_pdf)

		up_down_vbox = QVBoxLayout(self.up_down_widget)
		up_down_vbox.addWidget(up_button)
		up_down_vbox.addWidget(down_button)
		up_down_vbox.addWidget(remove_button)
		self.up_down_widget.setLayout(up_down_vbox)

		group_input = QGroupBox()
		grid_input = QGridLayout()
		grid_input.addWidget(add_button, 0, 0)
		grid_input.addWidget(input_files_label, 1, 0)
		grid_input.addWidget(self.files_list, 2, 0)
		grid_input.addWidget(self.up_down_widget, 2, 1)
		group_input.setLayout(grid_input)

		group_output = QGroupBox()
		grid_output = QGridLayout()
		grid_output.addWidget(select_path_label, 0, 0)
		grid_output.addWidget(self.dest_path_edit, 1, 0)
		grid_output.addWidget(select_path, 1, 1)
		group_output.setLayout(grid_output)

		vbox_options = QVBoxLayout(self.options_widget)
		vbox_options.addWidget(group_input)
		vbox_options.addWidget(group_output)
		vbox_options.addWidget(start)
		self.options_widget.setLayout(vbox_options)

		splitter_filelist = QSplitter()
		splitter_filelist.setOrientation(Qt.Vertical)
		splitter_filelist.addWidget(self.options_widget)
		vbox_main = QVBoxLayout(self.main_widget)
		vbox_main.addWidget(splitter_filelist)
		vbox_main.setContentsMargins(0,0,0,0)
コード例 #13
0
class RegistrationShop(MainWindow, WindowDialog):
    """
	Main class that starts up the application.
	Creates UI and starts project/plugin managers.
	"""
    def __init__(self, args):
        """
		Sets app specific properties.
		Initializes the UI.
		"""
        super(RegistrationShop, self).__init__(args)

        self.setApplicationPath()
        # Instantiate the project controller
        ProjectController.Instance()

        # Initialize the user interface
        self.initUI()

        lastProject = RegistrationShop.settings.value("project/lastProject",
                                                      None)
        if lastProject:
            self.openProject(lastProject)

    def initialize(self):
        # Initialize the render window interactors only after calling show()
        # otherwise OpenGL errors will occur on OS X
        self.fixedDataWidget.rwi.Initialize()
        self.movingDataWidget.rwi.Initialize()
        self.multiDataWidget.rwi.Initialize()

    # UI setup methods

    def initUI(self):
        """
		Initializes the UI. Makes sure previous state of
		application is restored.
		"""
        # Create actions and elements
        self.createElements()
        self.connectElements()
        self.createActions()
        self.createMenus()
        self.createToolbar()
        self.restoreState()

        # Set some window/application properties
        self.setUnifiedTitleAndToolBarOnMac(True)
        self.setWindowTitle(APPNAME)
        self.setWindowState(Qt.WindowActive)

    def createElements(self):
        """
		Creates the widgets and docks of which the
		main window is composed.
		"""
        self.mainWindow = QMainWindow()
        projectController = ProjectController.Instance()
        self.transformTool = None

        # Render widgets
        self.fixedDataWidget = RenderWidget()
        self.movingDataWidget = RenderWidget()
        self.multiDataWidget = MultiRenderWidget()

        self.fixedRenderController = RenderController(self.fixedDataWidget,
                                                      "fixed")
        self.movingRenderController = RenderController(self.movingDataWidget,
                                                       "moving")
        self.multiRenderController = MultiRenderController(
            self.multiDataWidget)

        # Give references of the render controllers to the project controller
        projectController.fixedRenderController = self.fixedRenderController
        projectController.movingRenderController = self.movingRenderController
        projectController.multiRenderController = self.multiRenderController

        # Render properties widgets
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(1)

        self.fixedPropWidget = RenderPropWidget(self.fixedRenderController,
                                                parent=self)
        self.fixedPropWidget.setSizePolicy(sizePolicy)
        self.fixedPropWidget.setFileChangedSignal(
            projectController.fixedFileChanged)
        self.fixedPropWidget.setLoadDataSlot(self.loadFixedDataSetFile)

        self.movingPropWidget = RenderPropWidget(self.movingRenderController,
                                                 parent=self)
        self.movingPropWidget.setSizePolicy(sizePolicy)
        self.movingPropWidget.setFileChangedSignal(
            projectController.movingFileChanged)
        self.movingPropWidget.setLoadDataSlot(self.loadMovingDataSetFile)

        self.multiPropWidget = MultiRenderPropWidget(
            self.multiRenderController, parent=self)
        self.multiPropWidget.setSizePolicy(sizePolicy)

        self.verticalSplitter = QSplitter()
        self.verticalSplitter.setOrientation(Qt.Vertical)

        # Create the layouts

        fixedDataTitleWidget = TitleWidget("Fixed volume")
        multiDataTitleWidget = TitleWidget("Fixed + Moving")
        movingDataTitleWidget = TitleWidget("Moving volume")

        fixedLayout = QGridLayout()
        fixedLayout.setSpacing(0)
        fixedLayout.setContentsMargins(0, 0, 0, 0)
        fixedLayout.addWidget(fixedDataTitleWidget)
        fixedLayout.addWidget(self.fixedDataWidget)
        fixedWidget = QWidget()
        fixedWidget.setLayout(fixedLayout)

        multiLayout = QGridLayout()
        multiLayout.setSpacing(0)
        multiLayout.setContentsMargins(0, 0, 0, 0)
        multiLayout.addWidget(multiDataTitleWidget)
        multiLayout.addWidget(self.multiDataWidget)
        multiWidget = QWidget()
        multiWidget.setLayout(multiLayout)

        movingLayout = QGridLayout()
        movingLayout.setSpacing(0)
        movingLayout.setContentsMargins(0, 0, 0, 0)
        movingLayout.addWidget(movingDataTitleWidget)
        movingLayout.addWidget(self.movingDataWidget)
        movingWidget = QWidget()
        movingWidget.setLayout(movingLayout)

        horizontalSplitter = QSplitter()
        horizontalSplitter.setOrientation(Qt.Horizontal)
        horizontalSplitter.addWidget(fixedWidget)
        horizontalSplitter.addWidget(multiWidget)
        horizontalSplitter.addWidget(movingWidget)

        propsLayout = QHBoxLayout()
        propsLayout.setSpacing(1)
        propsLayout.setContentsMargins(0, 0, 0, 0)
        propsLayout.addWidget(self.fixedPropWidget)
        propsLayout.addWidget(self.multiPropWidget)
        propsLayout.addWidget(self.movingPropWidget)

        propsWidget = QWidget()
        propsWidget.setMinimumHeight(245)
        propsWidget.setMaximumHeight(350)
        propsWidget.setLayout(propsLayout)

        self.verticalSplitter.addWidget(horizontalSplitter)
        self.verticalSplitter.addWidget(propsWidget)
        self.verticalSplitter.setStretchFactor(0, 2)
        self.verticalSplitter.setStretchFactor(1, 1)
        self.setCentralWidget(self.verticalSplitter)

    def connectElements(self):
        """
		All the elements have to be connected because they are dependent
		on each other.
		There is the project controller, two render controllers and a multi render
		controller.
		Also there are two render widgets and a multi render widget. Together with some
		parameter widgets that show settings and with which the user can interact.
		"""
        projectController = ProjectController.Instance()
        projectController.fixedFileChanged.connect(
            self.fixedRenderController.setFile)
        projectController.fixedFileChanged.connect(
            self.multiRenderController.setFixedFile)
        projectController.movingFileChanged.connect(
            self.movingRenderController.setFile)
        projectController.movingFileChanged.connect(
            self.multiRenderController.setMovingFile)
        projectController.fixedSettingsChanged.connect(
            self.fixedRenderController.setRenderSettings)
        projectController.movingSettingsChanged.connect(
            self.movingRenderController.setRenderSettings)
        projectController.multiSettingsChanged.connect(
            self.multiRenderController.setRenderSettings)

        self.fixedRenderController.visualizationChanged.connect(
            self.multiRenderController.setFixedVisualization)
        self.fixedRenderController.visualizationUpdated.connect(
            self.multiRenderController.setFixedVisualization)
        self.movingRenderController.visualizationChanged.connect(
            self.multiRenderController.setMovingVisualization)
        self.movingRenderController.visualizationUpdated.connect(
            self.multiRenderController.setMovingVisualization)

        self.multiDataWidget.transformations.transformationChanged.connect(
            self.movingDataWidget.transformationsUpdated)

    def createActions(self):
        """
		Create actions that can be attached to buttons and menus.
		"""
        userTransformIconName = AppResources.imageNamed(
            'UserTransformButton.png')
        landmarkTransformIconName = AppResources.imageNamed(
            'LandmarkTransformButton.png')
        deformableTransformIconName = AppResources.imageNamed(
            'DeformableTransformButton.png')
        compareIconName = AppResources.imageNamed('CompareButton.png')
        helpIconName = AppResources.imageNamed('HelpButton.png')

        self.actionFreeTransformTool = QAction('Manual transform',
                                               self,
                                               shortcut='Ctrl+1')
        self.actionFreeTransformTool.setIcon(QIcon(userTransformIconName))
        self.actionFreeTransformTool.triggered.connect(self.addManualTransform)

        self.actionLandmarkTransformTool = QAction('Landmark transform',
                                                   self,
                                                   shortcut='Ctrl+2')
        self.actionLandmarkTransformTool.setIcon(
            QIcon(landmarkTransformIconName))
        self.actionLandmarkTransformTool.triggered.connect(
            self.addLandmarkTransform)

        self.actionDeformableTransformTool = QAction('Automatic transform',
                                                     self,
                                                     shortcut='Ctrl+3')
        self.actionDeformableTransformTool.setIcon(
            QIcon(deformableTransformIconName))
        self.actionDeformableTransformTool.triggered.connect(
            self.addDeformableTransform)

        self.actionLoadFixedData = QAction('Load fixed data',
                                           self,
                                           shortcut='Ctrl+Shift+F')
        self.actionLoadFixedData.triggered.connect(self.loadFixedDataSetFile)

        self.actionLoadMovingData = QAction('Load moving data',
                                            self,
                                            shortcut='Ctrl+Shift+M')
        self.actionLoadMovingData.triggered.connect(self.loadMovingDataSetFile)

        self.actionSaveProject = QAction('Save project',
                                         self,
                                         shortcut='Ctrl+S')
        self.actionSaveProject.triggered.connect(self.saveProject)

        self.actionSaveProjectAs = QAction('Save project as...',
                                           self,
                                           shortcut='Ctrl+Shift+S')
        self.actionSaveProjectAs.triggered.connect(self.saveProjectAs)

        self.actionExportDataAs = QAction('Export data...',
                                          self,
                                          shortcut='Ctrl+E')
        self.actionExportDataAs.triggered.connect(self.exportDataAs)

        self.actionOpenProject = QAction('Open project...',
                                         self,
                                         shortcut='Ctrl+O')
        self.actionOpenProject.triggered.connect(self.openProject)

        self.actionNewProject = QAction('New project', self, shortcut='Ctrl+N')
        self.actionNewProject.triggered.connect(self.newProject)

        self.actionCompare = QAction('Compare', self, shortcut='Ctrl+U')
        self.actionCompare.setIcon(QIcon(compareIconName))
        self.actionCompare.triggered.connect(self.startComparison)

        self.actionHelp = QAction('Help', self, shortcut='Ctrl+H')
        self.actionHelp.setIcon(QIcon(helpIconName))
        self.actionHelp.triggered.connect(self.showHelp)

    def createMenus(self):
        """
		Creates menus from actions.
		"""
        self.menuBar = self.menuBar()
        self.menuItemFile = self.menuBar.addMenu('&File')
        self.menuItemFile.addAction(self.actionNewProject)
        self.menuItemFile.addAction(self.actionOpenProject)
        # TODO: Open recent >
        self.menuItemFile.addAction(self.actionSaveProject)
        self.menuItemFile.addAction(self.actionSaveProjectAs)
        self.menuItemFile.addAction(self.actionExportDataAs)

        self.menuItemProject = self.menuBar.addMenu('&Project')
        self.menuItemProject.addAction(self.actionLoadFixedData)
        self.menuItemProject.addAction(self.actionLoadMovingData)
        self.menuItemProject.addSeparator()

    def createToolbar(self):
        """
		Creates the main toolbar and sets the toolbar buttons.
		"""
        # Add toolbar
        self.toolbar = self.addToolBar('Main tools')
        self.toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        self.toolbar.setAllowedAreas(Qt.TopToolBarArea)
        self.toolbar.setFloatable(False)
        self.toolbar.setMovable(False)

        # Create custom toolbar widget that can align items left, center and right
        self.toolbarWidget = ToolbarWidget()
        self.toolbarWidget.addActionLeft(self.actionFreeTransformTool)
        self.toolbarWidget.addActionLeft(self.actionLandmarkTransformTool)
        self.toolbarWidget.addActionLeft(self.actionDeformableTransformTool)

        statusWidget = StatusWidget.Instance()
        statusWidget.setText(
            "Welcome to RegistrationShop!\nStart your registration by loading two datasets. "
            +
            "After that you can use the transform tools to align your volume data."
        )
        self.toolbarWidget.addCenterItem(statusWidget)

        # Add help button
        self.toolbarWidget.addActionRight(self.actionCompare)
        self.toolbarWidget.addActionRight(self.actionHelp)
        self.toolbar.addWidget(self.toolbarWidget)

    # Private Functions

    def setApplicationPath(self):
        """
		Finds the path to the application. This is done so that it
		can figure out where certain resources are located.
		QCoreApplication::applicationDirPath() on OS X does not return the
		desired path to the actual application but to the python executable
		in /Library/FrameWorks. This is inconvenient because images can't be
		located that way.
		So instead os.path is used to find the location of this __file__.
		"""
        AppVars.setPath(os.path.dirname(os.path.abspath(__file__)))

    # Action callbacks
    @Slot()
    def addManualTransform(self):
        """
		What happens when manual transform is added:
		* Entry is added to the tab history
			* Translation fields
			* Rotation fields
			* Scale field(s)
		* Transform box is added to the render widget
		* Button with apply (will apply the transform to the data)

		Applying the transform to the data means:
		* Create new dataset from transformed data
		* Save this data to the project folder
		* Read in the new data and update this in the multi render widget
		* this would mean a new data model for the multi render widget
		"""
        if not self.movingDataWidget.imageData:
            statusWidget = StatusWidget.Instance()
            statusWidget.setText(
                "Please load a moving dataset before starting a manual transform."
            )
            return

        if self.transformTool is not None:
            self.transformTool.cleanUp()

        self.transformTool = UserTransformationTool()
        self.transformTool.setRenderWidgets(moving=self.movingDataWidget,
                                            multi=self.multiDataWidget)
        self.multiPropWidget.setTransformTool(self.transformTool)
        self.transformTool.toolFinished.connect(self.transformToolFinished)

    @Slot()
    def addLandmarkTransform(self):
        if not self.fixedDataWidget.imageData or not self.movingDataWidget.imageData:
            statusWidget = StatusWidget.Instance()
            statusWidget.setText(
                "Please load a fixed and a moving dataset before starting a landmark transform."
            )
            return

        # Clean up the last transform tool
        if self.transformTool is not None:
            self.transformTool.cleanUp()

        self.transformTool = LandmarkTransformationTool()
        self.transformTool.setRenderWidgets(fixed=self.fixedDataWidget,
                                            moving=self.movingDataWidget,
                                            multi=self.multiDataWidget)

        # Create a tab page under the fixed render widget
        fixedLandmarkWidget = LandmarkWidget()
        self.fixedPropWidget.addTabWidget(fixedLandmarkWidget, "Landmark")

        # Create a tab page under the moving render widget
        movingLandmarkWidget = LandmarkWidget()
        self.movingPropWidget.addTabWidget(movingLandmarkWidget, "Landmark")

        # Make sure the landmark transform tool knows of these tab widgets
        self.transformTool.setLandmarkWidgets(fixedLandmarkWidget,
                                              movingLandmarkWidget)

        # Start the transformation
        self.multiPropWidget.setTransformTool(self.transformTool)
        self.transformTool.toolFinished.connect(self.transformToolFinished)

    @Slot()
    def addDeformableTransform(self):
        if not self.fixedDataWidget.imageData or not self.movingDataWidget.imageData:
            statusWidget = StatusWidget.Instance()
            statusWidget.setText(
                "Please load a fixed and a moving dataset before starting a deformable transform."
            )
            return

        self.multiPropWidget.tabWidget.setCurrentWidget(
            self.multiPropWidget.transformParamWidget)

        if self.transformTool is not None:
            self.transformTool.cleanUp()

        statusWidget = StatusWidget.Instance()
        statusWidget.setText(
            "Choose a template for a deformable transform. After choosing "
            "a template you will be able to review and adjust the parameters.")

        dialog = ElastixMainDialog(self)
        dialog.setModal(True)
        result = dialog.exec_()
        if not result:
            return
        if not dialog.transformation:
            # load custom file
            filename, other = QFileDialog.getOpenFileName(
                self, "Open custom parameter file", "", "(*.c *.txt)")
            if len(filename) == 0:
                return
            transformation = ParameterList()
            if not transformation.loadFromFile(filename):
                transformation = None
                statusWidget = StatusWidget.Instance()
                statusWidget.setText(
                    "Warning: could not load transformation file")
        else:
            transformation = dialog.transformation

        self.transformTool = DeformableTransformationTool()
        self.transformTool.setTransformation(transformation)
        self.transformTool.startedElastix.connect(self.showProgressBar)
        self.transformTool.endedElastix.connect(self.hideProgressBar)
        self.transformTool.setRenderWidgets(fixed=self.fixedDataWidget,
                                            moving=self.movingDataWidget,
                                            multi=self.multiDataWidget)
        self.multiPropWidget.setTransformTool(self.transformTool)
        self.transformTool.toolFinished.connect(self.transformToolFinished)

    @Slot()
    def transformToolFinished(self):
        self.multiPropWidget.transformToolFinished()
        self.fixedPropWidget.removeTabWidget()
        self.movingPropWidget.removeTabWidget()

    @Slot()
    def loadFixedDataSetFile(self):
        """
		Open file dialog to search for data files. If valid data is given, it will
		pass the data file location on to the slicer and the project controller.
		"""
        dataReader = DataReader()
        extensions = dataReader.GetSupportedExtensionsAsString()
        fileName, other = QFileDialog.getOpenFileName(
            self,
            "Open fixed data set",
            "",
            "Images (" + extensions + ")",
            options=QFileDialog.Directory)
        if len(fileName) > 0:
            # If there was another dataset first, ask if the user if the
            # visualizations should be reset
            projectController = ProjectController.Instance()
            if projectController.currentProject.fixedData:
                dialog = ResetVisualizationDialog(self)
                dialog.setWindowModality(Qt.WindowModal)
                dialog.exec_()
                if dialog.result is not None:
                    projectController.loadFixedDataSet(fileName)
                    if dialog.result:
                        self.fixedRenderController.resetVisualizations()
            else:
                projectController.loadFixedDataSet(fileName)

    @Slot()
    def loadMovingDataSetFile(self):
        """
		Open file dialog to search for data files. If valid data is given, it will
		pass the data file location on to the slicer and the project controller.
		"""
        dataReader = DataReader()
        extensions = dataReader.GetSupportedExtensionsAsString()
        fileName, other = QFileDialog.getOpenFileName(
            self,
            "Open moving data set",
            "",
            "Images (" + extensions + ")",
            options=QFileDialog.Directory)
        if len(fileName) > 0:
            # If there was another dataset first, ask if the user if the
            # visualizations should be reset
            projectController = ProjectController.Instance()
            if projectController.currentProject.movingData:
                dialog = ResetVisualizationDialog(self)
                dialog.setWindowModality(Qt.WindowModal)
                dialog.exec_()
                if dialog.result is not None:
                    projectController.loadMovingDataSet(fileName)
                    if dialog.result:
                        self.movingRenderController.resetVisualizations()
            else:
                # Inserting an identity transform
                self.multiDataWidget.transformations.append(
                    Transformation(vtkTransform(), "No transform", fileName))
                projectController.loadMovingDataSet(fileName)

    @Slot()
    def saveProject(self):
        """
		Save the project to the specified name in the current project. If no name
		is specified, then 'save project as' is called.
		"""
        projCont = ProjectController.Instance()

        if projCont.currentProject.folder is not None:
            # Save that project
            saved = projCont.saveProject()
            statusWidget = StatusWidget.Instance()
            if saved:
                # Save it in the settings that this was the last opened project
                RegistrationShop.settings.setValue(
                    "project/lastProject", projCont.currentProject.folder)
                statusWidget.setText(
                    "The project was succesfully saved to disk.")
            else:
                statusWidget.setText(
                    "Something went wrong while saving the project to disk. "
                    "Please try to save the project again.")
        else:
            self.saveProjectAs()

    @Slot()
    def saveProjectAs(self):
        """
		Opens a file dialog so that the user can select a folder
		in which to save the project.
		"""
        # Open file dialog
        fileName = QFileDialog.getExistingDirectory(self,
                                                    "Select project folder",
                                                    "",
                                                    QFileDialog.ShowDirsOnly)
        if len(fileName) > 0:
            # TODO: check for existing project!

            # Set filename of project
            ProjectController.Instance().currentProject.folder = fileName
            # Call save project
            self.saveProject()

    @Slot()
    def openProject(self, folderName=None):
        """
		If no project name is supplied, it will open a file dialog so
		that the user can select a project file
		or project folder.

		:param folderName: Name of a folder with a project
		:type folderName: basestring
		"""
        fileName = ""
        if folderName:
            fileName = folderName
        else:
            fileName = QFileDialog.getExistingDirectory(
                self, "Open project", "", QFileDialog.ShowDirsOnly)

        if len(fileName) > 0:
            fullName = fileName + ProjectController.Instance().ProjectFile
            if os.path.isfile(fullName):
                self.multiDataWidget.transformations.clear()
                loaded = ProjectController.Instance().loadProject(fileName)
                if loaded:
                    RegistrationShop.settings.setValue("project/lastProject",
                                                       fileName)
                else:
                    print "Couldn't load project:", folderName
            else:
                print "Warning: Project file does not exist"
                RegistrationShop.settings.remove("project/lastProject")

    @Slot()
    def newProject(self):
        """
		Create new project by calling the project controller
		"""
        self.multiDataWidget.transformations.clear()
        ProjectController.Instance().newProject()
        # Reset the last loaded project in the settings
        RegistrationShop.settings.setValue("project/lastProject", "")

    @Slot()
    def exportDataAs(self):
        """
		Opens a file dialog so that the user can provide a filename
		for saving the transformed dataset to.
		"""
        fileType = FileTypeDialog.getFileType(self,
                                              "Choose file type for export")
        if len(fileType) == 0:
            return

        extension = "(*." + fileType + ")"
        fileName, other = QFileDialog.getSaveFileName(
            self, "Save registration result to...", "", extension)
        if len(fileName) == 0:
            return

        self.showProgressBar("Exporting data...")

        transform = self.multiDataWidget.transformations.completeTransform()
        dataReader = DataReader()
        imageData = dataReader.GetImageData(
            ProjectController.Instance().currentProject.movingData)
        transformer = DataTransformer()
        outputData = transformer.TransformImageData(imageData, transform)
        writer = DataWriter()
        writer.WriteToFile(outputData, fileName, fileType)

        self.hideProgressBar()

    @Slot()
    def startComparison(self):
        projectController = ProjectController.Instance()
        project = projectController.currentProject
        if not project or not project.fixedData or not project.movingData:
            statusWidget = StatusWidget.Instance()
            statusWidget.setText(
                "Could not start comparison. Please make a project first"
                " and make sure to load two datasets.")
            return

        if hasattr(self, "compareWidget"):
            del self.compareWidget

        transform = self.multiDataWidget.transformations.completeTransform()

        self.controller = ComparisonController()
        self.controller.setInputData(project.fixedData, project.movingData,
                                     transform)
        self.compareWidget = CompareWidget(self.controller.widgets)
        self.compareWidget.show()
        self.controller.initialize()
        self.controller.slicerChanged(self.controller.fixedImageWidget)

    @Slot()
    def showHelp(self):
        statusWidget = StatusWidget.Instance()
        statusWidget.setText("Don't panic!")
コード例 #14
0
ファイル: WTL.py プロジェクト: AlaaProg/MySQL-Control-Panel
class Window(QWidget):
    def init(self, self_mysql):
        self.ref = False
        self.ndb = False
        self.Data_Name = None
        self.table_Name = None

        self.mysql = self_mysql
        self.table = Table()
        self.tree = treeWidget(self.mysql)
        text = (
            "<center><h1 style=';color:Lightblue;'>MySQL<small style='color:#0099CC;'> Control Panel</small></h1></center>"
        )
        self.vbox = QVBoxLayout(self)
        self.split = QSplitter()
        self.tree.setHidden(True)
        self.tree.itemClicked.connect(self.setInTable)
        self.tree.itemExpanded.connect(self.expand)
        self.tree.itemCollapsed.connect(self.collaps)
        self.split.addWidget(self.tree)
        self.split.addWidget(self.table)
        self.split.setSizes([60, 400])
        self.vbox.addWidget(label(text))
        self.vbox.addWidget(self.split)
        self.vbox.setContentsMargins(-18, -18, -18, -18)

    def expand(self, it):
        if it.isExpanded():
            if not it.text(0) in self.tree.li:
                self.tree.li.append(it.text(0))

    def collaps(self, it):
        if it.text(0) in self.tree.li:
            self.tree.li.remove(it.text(0))

    # set Name 'database & table' in TreeList #
    def con(self):
        self.tree.clear()
        if self.tree.isHidden:
            self.tree.setHidden(False)
        self.tree.headerItem().setText(0, self.Data_Name)
        self.tree.add_to_tree()
        self.ref = True

    def setInTable(self, nt):
        if not str(nt).startswith('<'):
            table = nt
            self.table_Name = nt
        else:
            if nt.statusTip(0) != 'main':
                self.tree.headerItem().setText(0, nt.statusTip(0))
                self.ndb = nt.statusTip(0)
                self.Data_Name = nt.statusTip(0)
                self.table_Name = nt.text(0)
            else:
                self.tree.headerItem().setText(0, nt.text(0))
                self.Data_Name = nt.text(0)
                self.table_Name = None
        if self.ndb:
            if self.table_Name in self.mysql.getTables(self.Data_Name):
                self.setDataInTable(self.table_Name)
                self.ref = True
        else:
            pass

    # Set Data Table In TableWidget #
    def setDataInTable(self, tab):
        Icol = 0
        if self.ndb:
            data_dic = self.mysql.dataCol(self.ndb, tab)
            cols = self.mysql.getColumns(self.ndb, tab)
            self.table.setColumnCount(len(cols))
            if data_dic != None:
                self.table.setRowCount(int(data_dic[1]))
                for col in cols:
                    item = QTableWidgetItem
                    self.table.setHorizontalHeaderItem(Icol, item(col))
                    Irow = 0
                    for row in data_dic[0][col]:
                        self.item = QTableWidgetItem(str(row))
                        self.item.setFont(QFont("andalus", 12))
                        self.table.setItem(Irow, Icol, self.item)
                        Irow += 1
                    Icol += 1
コード例 #15
0
class ConsoleWidget(QMainWindow):
    def __init__(self):
        super(ConsoleWidget, self).__init__()
        self.setWindowTitle('1c query')

        self._connection = None

        self._home = os.path.expanduser('~/%s' % QApplication.applicationName())
        if not os.path.isdir(self._home):
            os.mkdir(self._home)

        self.queryToolBar = self.addToolBar('Query')
        self.queryAction = self.queryToolBar.addAction('Run', self.executeQuery)
        self.queryAction.setDisabled(True)

        uri_history = list()
        path = os.path.join(self._home, 'uri_history.txt')
        if os.path.isfile(path):
            uri_history = open(path, 'r').read().split('\n')

        self.connectionToolBar = self.addToolBar('Connection')
        self.connectionUriCombo = QComboBox(self)
        self.connectionUriCombo.setEditable(True)
        if not uri_history:
            self.connectionUriCombo.addItem('File="";usr="";pwd="";')
            self.connectionUriCombo.addItem('Srvr="{host}";Ref="{ref}";Usr="******";Pwd="{password}";')
        else:
            self.connectionUriCombo.addItems(uri_history)
            self.connectionUriCombo.setCurrentIndex(len(uri_history) - 1)
        self.connectionUriCombo.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Maximum)
        self.connectionToolBar.addWidget(self.connectionUriCombo)

        self.onesVersionCombo = QComboBox(self)
        self.onesVersionCombo.addItems(['8.3', '8.2', '8.1', '8.0'])
        self.onesVersionCombo.setCurrentIndex(0)
        self.connectionToolBar.addWidget(self.onesVersionCombo)
        self.connectAction = self.connectionToolBar.addAction('Connect', self.connectOneS)
        self.disconnectAction = self.connectionToolBar.addAction('Disconnect', self.disconnectOneS)
        self.disconnectAction.setDisabled(True)

        self.logEdit = QPlainTextEdit(self)
        self.logDock = QDockWidget('Log', self)
        self.logDock.setWidget(self.logEdit)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.logDock, Qt.Horizontal)

        self.splitter = QSplitter(Qt.Vertical, self)
        self.setCentralWidget(self.splitter)

        self.sqlEdit = QTextEdit(self)
        self.sqlEdit.setLineWrapMode(QTextEdit.NoWrap)

        path = os.path.join(self._home, 'last-sql.txt')
        if os.path.isfile(path):
            sql = open(path, 'r').read()
            self.sqlEdit.setText(sql)

        self.model = QStandardItemModel(self)
        self.tableView = QTableView(self)
        self.tableView.setModel(self.model)

        self.splitter.addWidget(self.sqlEdit)
        self.splitter.addWidget(self.tableView)
        self.splitter.setStretchFactor(0, 3)
        self.splitter.setStretchFactor(1, 2)

    def query(self, sql):
        if not self._connection:
            self.logEdit.appendPlainText('No connection')
            return None

        try:
            query = self._connection.NewObject('Query', sql)
            result = query.Execute()
        except Exception as e:
            self.logEdit.appendPlainText(str(e))
            return None

        return result

    def refresh(self, result):
        self.model.clear()

        columns = list()
        result_columns = result.Columns
        for index in range(result_columns.Count()):
            name = result_columns.Get(index).Name
            columns.append(name)

        self.model.setColumnCount(len(columns))
        for section, name in enumerate(columns):
            self.model.setHeaderData(section, Qt.Horizontal, name)

        select = result.Choose()
        self.logEdit.appendPlainText('Selected %d records' % select.Count())
        while select.Next():
            items = list()
            for index in range(len(columns)):
                value = select.Get(index)

                item = QStandardItem('')
                if isinstance(value, bool):
                    item.setText(value and 'Yes' or 'No')

                elif isinstance(value, (int, str)):
                    item.setText(str(value))

                elif isinstance(value, datetime.datetime):
                    item.setText(value.strftime('%Y.%m.%d %H:%M:%S'))

                else:
                    item.setText(str(value))
                items.append(item)

            self.model.appendRow(items)

    @Slot()
    def executeQuery(self):
        sql = self.sqlEdit.toPlainText()
        result = self.query(sql)
        if result:
            path = os.path.join(self._home, 'last-sql.txt')
            open(path, 'w').write(sql)
            self.refresh(result)

    @Slot()
    def connectOneS(self):
        uri = self.connectionUriCombo.currentText().strip()
        if not uri:
            self.logEdit.appendPlainText('Need a connection string')
            return

        version = self.onesVersionCombo.currentText()
        comName = "V%s.COMConnector" % str(version).replace('.', '')

        pythoncom.CoInitialize()
        try:
            obj = win32com.client.Dispatch(comName)
            self._connection = obj.Connect(uri)
        except Exception as e:
            self.logEdit.appendPlainText(str(e))
            return

        self.connectAction.setDisabled(True)
        self.disconnectAction.setEnabled(True)
        self.queryAction.setEnabled(True)

        uri_history = list()
        for i in range(self.connectionUriCombo.count()):
            uri_history.append(self.connectionUriCombo.itemText(i))

        if uri not in uri_history:
            self.connectionUriCombo.clearEditText()
            self.connectionUriCombo.addItem(uri)
            self.connectionUriCombo.setCurrentIndex(len(uri_history))
            uri_history.append(uri)
            path = os.path.join(self._home, 'uri_history.txt')
            open(path, 'w').write('\n'.join(uri_history))

    @Slot()
    def disconnectOneS(self):
        pythoncom.CoUninitialize()
        self._connection = None
        self.connectAction.setEnabled(True)
        self.disconnectAction.setDisabled(True)
        self.queryAction.setDisabled(True)
コード例 #16
0
class MainWindow(QMainWindow):
    """The application's main window
    """

    # Emitted when there are pending files to be processed
    new_pending_files = QtCore.Signal()

    def __init__(self, app):
        super(MainWindow, self).__init__()

        # Window layout - a splitter with the image on the left and controls
        # on the right
        self._image_widget = ImageLabel(self)
        self._controls = Controls(self)
        self._splitter = QSplitter()
        self._splitter.addWidget(self._image_widget)
        self._splitter.addWidget(self._controls)
        self._splitter.setSizes([1200, 600])

        # Main window layout
        self.setCentralWidget(self._splitter)

        # Connect controls to handlers
        self._controls.ok.clicked.connect(self.ok)
        self._controls.cancel.clicked.connect(self.cancel)
        self._controls.inbox.choose_directory.clicked.connect(
            self.choose_inbox)
        self._controls.processed.choose_directory.clicked.connect(
            self.choose_processed)

        # Directories
        mydocuments = QDesktopServices.storageLocation(
            QDesktopServices.DocumentsLocation)
        self._inbox = Path(QSettings().value('inbox',
                                             str(Path(mydocuments) / 'inbox')))
        self._processed = Path(QSettings().value(
            'processed', str(Path(mydocuments) / 'processed')))

        self._controls.inbox.set_link(str(self._inbox.as_uri()),
                                      self._inbox.name)
        self._controls.processed.set_link(str(self._processed.as_uri()),
                                          self._processed.name)

        # A stack of Path objects to be processed
        self._pending_files = []

        # The Path currently shown in the UI
        self._under_review = None

        # Watch the inbox directory, if it exists
        self.new_pending_files.connect(self.process_next_pending,
                                       QtCore.Qt.QueuedConnection)

        if self._inbox.is_dir():
            self._watcher = NewFileWatcher(self._inbox, IMAGE_SUFFIXES_RE)
            self._watcher.new_file.connect(self.new_image_file)
        else:
            self._watcher = None

        self.empty_controls()

        # Setup drag-drop handling
        self.setAcceptDrops(True)
        self._controls.installEventFilter(self)
        self._splitter.installEventFilter(self)

    def new_inbox_directory(self):
        """Watch the inbox directory
        """
        print('MainWindow.new_inbox_directory [{0}]'.format(self._inbox))
        if self._watcher:
            self._watcher.new_file.disconnect()

        self._watcher = NewFileWatcher(self._inbox, IMAGE_SUFFIXES_RE)
        self._watcher.new_file.connect(self.new_image_file)

    def new_image_file(self, path):
        """Slot for self._watcher.new_file
        """
        print('MainWindow.new_image_file [{0}]'.format(path))
        self._pending_files.append(path)
        self.new_pending_files.emit()

    @report_to_user
    def process_next_pending(self):
        """Loads the next pending image for review
        """
        print('MainWindow.process_next_pending: [{0}] files'.format(
            len(self._pending_files)))
        if not self._under_review:
            if self._pending_files:
                self.review_image(self._pending_files.pop())
            else:
                self.empty_controls()

    def review_image(self, path):
        """Loads path for review
        """
        print('MainWindow.review_image [{0}]'.format(path))

        # Arbitrary delay to give the capture software time to finish writing
        # the image.
        time.sleep(1)
        image = cv2.imread(str(path))
        if image is None:
            raise ValueError('Unable to read [{0}]'.format(path))
        else:
            self._under_review = path
            self.setWindowTitle('')
            self.setWindowFilePath(str(path))
            self._controls.specimen.setText(QSettings().value('specimen'))
            self._controls.location.setText(QSettings().value('location'))
            self._image_widget.set_pixmap(
                QPixmap.fromImage(qimage_of_bgr(image)))
            self._controls.image_handling.setEnabled(True)

    def empty_controls(self):
        """Clears controls
        """
        print('MainWindow.empty_controls')
        self._under_review = None
        self.setWindowTitle('Syrup')
        self.setWindowFilePath(None)
        self._image_widget.set_pixmap(None)
        self._controls.clear()
        self._controls.image_handling.setEnabled(False)

    @report_to_user
    def ok(self):
        print('MainWindow.ok')
        specimen = self._controls.specimen.text()
        location = self._controls.location.text()
        if not SPECIMEN_RE.match(specimen):
            raise ValueError(
                'Please enter nine digits for the specimen barcode')
        elif not LOCATION_RE.match(location):
            raise ValueError(
                'Please enter a letter "L" and nine digits for the '
                'location barcode')
        else:
            if not self._processed.is_dir():
                self._processed.mkdir(parents=True)
            destination = self._processed / '{0}_{1}'.format(
                specimen, location)
            destination = destination.with_suffix(self._under_review.suffix)
            move_and_rename(self._under_review, destination)
            QSettings().setValue('specimen', specimen)
            QSettings().setValue('location', location)
            self._under_review = None
            self.process_next_pending()

    @report_to_user
    def cancel(self):
        """Closes the image under review without moving the image file
        """
        print('MainWindow.cancel')
        self._under_review = None
        self.process_next_pending()

    @report_to_user
    def choose_inbox(self):
        """Prompts the user to choose the inbox directory
        """
        directory = QFileDialog.getExistingDirectory(
            self, "Choose the inbox directory", str(self._inbox))
        if directory:
            directory = Path(directory)
            if directory == self._processed:
                raise ValueError('The inbox directory cannot be the same as '
                                 'the processed directory')
            else:
                self._inbox = directory
                print('New inbox directory [{0}]'.format(self._inbox))
                self._controls.inbox.set_link(str(self._inbox.as_uri()),
                                              self._inbox.name)
                QSettings().setValue('inbox', str(self._inbox))
                self.new_inbox_directory()

    @report_to_user
    def choose_processed(self):
        """Prompts the user to choose the processed directory
        """
        directory = QFileDialog.getExistingDirectory(
            self, "Choose the processed directory", str(self._processed))
        if directory:
            directory = Path(directory)
            if directory == self._inbox:
                raise ValueError('The inbox directory cannot be the same as '
                                 'the processed directory')
            else:
                self._processed = directory
                print('New processed directory [{0}]'.format(self._processed))
                self._controls.processed.set_link(
                    str(self._processed.as_uri()), self._processed.name)
                QSettings().setValue('processed', str(self._processed))

    def write_geometry_settings(self):
        "Writes geometry to settings"
        print('MainWindow.write_geometry_settings')

        # Taken from http://stackoverflow.com/a/8736705
        # TODO LH Test on multiple display system
        s = QSettings()

        s.setValue("mainwindow/geometry", self.saveGeometry())
        s.setValue("mainwindow/pos", self.pos())
        s.setValue("mainwindow/size", self.size())

    def show_from_geometry_settings(self):
        print('MainWindow.show_from_geometry_settings')

        # TODO LH What if screen resolution, desktop config change or roaming
        # profile means that restored state is outside desktop?
        s = QSettings()

        self.restoreGeometry(
            s.value("mainwindow/geometry", self.saveGeometry()))
        if not (self.isMaximized() or self.isFullScreen()):
            self.move(s.value("mainwindow/pos", self.pos()))
            self.resize(s.value("mainwindow/size", self.size()))
        self.show()

    def closeEvent(self, event):
        """QWidget virtual
        """
        print('MainWindow.closeEvent')
        self.write_geometry_settings()
        event.accept()

    def eventFilter(self, obj, event):
        "Event filter that accepts drag-drop events"
        if event.type() in (QEvent.DragEnter, QEvent.Drop):
            return True
        else:
            return super(MainWindow, self).eventFilter(obj, event)

    def _accept_drag_drop(self, event):
        """If no image is under review and event refers to a single image file,
        returns the path. Returns None otherwise.
        """
        if self._under_review:
            return None
        else:
            urls = event.mimeData().urls() if event.mimeData() else None
            path = Path(
                urls[0].toLocalFile()) if urls and 1 == len(urls) else None
            print(path, IMAGE_SUFFIXES_RE.match(path.suffix))
            if path and IMAGE_SUFFIXES_RE.match(path.suffix):
                return urls[0].toLocalFile()
            else:
                return None

    def dragEnterEvent(self, event):
        """QWidget virtual
        """
        print('MainWindow.dragEnterEvent')
        if self._accept_drag_drop(event):
            event.acceptProposedAction()
        else:
            super(MainWindow, self).dragEnterEvent(event)

    @report_to_user
    def dropEvent(self, event):
        """QWidget virtual
        """
        print('MainWindow.dropEvent')
        res = self._accept_drag_drop(event)
        if res:
            event.acceptProposedAction()
            self.review_image(Path(res))
        else:
            super(MainWindow, self).dropEvent(event)
コード例 #17
0
ファイル: gui05.py プロジェクト: yysynergy/pparser
class MainWindow(QMainWindow):
    def __init__(self, datta):
        QMainWindow.__init__(self)
        self.setWindowTitle('Project Parser')
        appIcon = QIcon('search.png')
        self.setWindowIcon(appIcon)
        self.viewPortBL = QDesktopWidget().availableGeometry().topLeft()
        self.viewPortTR = QDesktopWidget().availableGeometry().bottomRight()
        self.margin = int(QDesktopWidget().availableGeometry().width()*0.1/2)
        self.shirina = QDesktopWidget().availableGeometry().width() - self.margin*2
        self.visota = QDesktopWidget().availableGeometry().height() - self.margin*2
        self.setGeometry(self.viewPortBL.x() + self.margin, self.viewPortBL.y() + self.margin,
                         self.shirina, self.visota)
        # statusbar
        self.myStatusBar = QStatusBar()
        self.setStatusBar(self.myStatusBar)
        
        #lower long layout
        self.lowerLong = QFrame()
        self.detailsLabel = QLabel()
        self.skillsLabel = QLabel()
        self.urlLabel = QLabel()
        self.locationLabel = QLabel()
        self.skillsLabel.setText('skills')
        self.detailsLabel.setWordWrap(True)
        self.la = QVBoxLayout()
        self.la.addWidget(self.detailsLabel)
        self.la.addWidget(self.skillsLabel)
        self.la.addWidget(self.urlLabel)
        self.la.addWidget(self.locationLabel)
        self.lowerLong.setLayout(self.la)

        # table
        self.source_model = MyTableModel(self, datta, ['Id', 'Date', 'Title'])
        self.proxy_model = myTableProxy(self)
        self.proxy_model.setSourceModel(self.source_model)
        self.proxy_model.setDynamicSortFilter(True)
        self.table_view = QTableView()
        self.table_view.setModel(self.proxy_model)
        self.table_view.setAlternatingRowColors(True)
        self.table_view.resizeColumnsToContents()
        self.table_view.resizeRowsToContents()
        self.table_view.horizontalHeader().setStretchLastSection(True)
        self.table_view.setSortingEnabled(True)
        self.table_view.sortByColumn(2, Qt.AscendingOrder)

        # events
        self.selection = self.table_view.selectionModel()
        self.selection.selectionChanged.connect(self.handleSelectionChanged)
        #DO NOT use CreateIndex() method, use index()
        index = self.proxy_model.index(0,0)
        self.selection.select(index, QItemSelectionModel.Select)
        
        self.upperLong = self.table_view  

        # right side widgets
        self.right = QFrame()
        self.la1 = QVBoxLayout()
        self.btnDownload = QPushButton('Download data')
        self.btnDownload.clicked.connect(self.download)
        self.myButton = QPushButton('Show Skillls')
        self.myButton.clicked.connect(self.showAllSkills)
        self.btnSearchByWord = QPushButton('Search by word(s)')
        self.btnSearchByWord.clicked.connect(self.onSearchByWord)
        self.btnResetFilter= QPushButton('Discard Filter')
        self.btnResetFilter.clicked.connect(self.discardFilter)
        self.btnCopyURL = QPushButton('URL to Clipboard')
        self.btnCopyURL.clicked.connect(self.copyToClipboard)
        self.btnExit = QPushButton('Exit')
        self.btnExit.clicked.connect(lambda: sys.exit())
        self.dateTimeStamp = QLabel()
        self.la1.addWidget(self.btnDownload)
        self.la1.addSpacing(10)
        self.la1.addWidget(self.myButton)
        self.la1.addSpacing(10)
        self.la1.addWidget(self.btnSearchByWord)
        self.la1.addSpacing(10)
        self.la1.addWidget(self.btnResetFilter)
        self.la1.addSpacing(10)
        self.la1.addWidget(self.btnCopyURL)
        self.la1.addSpacing(70)
        self.la1.addWidget(self.btnExit)
        self.la1.addStretch(stretch=0)
        self.la1.addWidget(self.dateTimeStamp)
        self.right.setLayout(self.la1)
        self.right.setFrameShape(QFrame.StyledPanel)

        # splitters
        self.horiSplit = QSplitter(Qt.Vertical)
        self.horiSplit.addWidget(self.upperLong)
        self.horiSplit.addWidget(self.lowerLong)
        self.horiSplit.setSizes([self.visota/2, self.visota/2])
        self.vertiSplit = QSplitter(Qt.Horizontal)
        self.vertiSplit.addWidget(self.horiSplit)
        self.vertiSplit.addWidget(self.right)
        self.vertiSplit.setSizes([self.shirina*3/4, self.shirina*1/4])
        self.setCentralWidget(self.vertiSplit)
        
        self.settings = QSettings('elance.ini', QSettings.IniFormat)
        self.settings.beginGroup('DATE_STAMP')
        self.dateTimeStamp.setText('Data actuality: %s' % self.settings.value('date/time'))
        self.settings.endGroup()
        self.statusText = ''

    def handleSelectionChanged(self, selected, deselected):
        for index in selected.first().indexes():
            #print('Row %d is selected' % index.row())
            ind = index.model().mapToSource(index)
            desc = ind.model().mylist[ind.row()]['Description']
            self.detailsLabel.setText(desc)
            skills = ', '.join(ind.model().mylist[ind.row()]['Skills']).strip()
            self.skillsLabel.setText(skills)
            url = ind.model().mylist[ind.row()]['URL']
            self.urlLabel.setText(url)
            location = ind.model().mylist[ind.row()]['Location']
            self.locationLabel.setText(location)
    
    def showAllSkills(self):
        listSkills = []
        for elem in self.source_model.mylist:
            listSkills += elem['Skills']
        allSkills = Counter(listSkills)
        tbl = MyTableModel(self, allSkills.items(), ['Skill', 'Freq'])
        win = skillsWindow(tbl, self.table_view)
        win.exec_()
    
    def discardFilter(self):
        self.table_view.model().emit(SIGNAL("modelAboutToBeReset()"))
        self.table_view.model().criteria = {}
        self.table_view.model().emit(SIGNAL("modelReset()"))
        self.table_view.resizeRowsToContents()
        
    def download(self):
        self.btnDownload.setDisabled(True)
        self.statusLabel = QLabel('Connecting')
        self.progressBar = QProgressBar()
        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(100)
        self.myStatusBar.addWidget(self.statusLabel, 2)
        self.myStatusBar.addWidget(self.progressBar, 1)
        self.progressBar.setValue(1)
        self.settings.beginGroup('URLS')
        initialLink = self.settings.value('CategoriesDetailed/VahaSelected/InitialLink')
        pagingLink = self.settings.value('CategoriesDetailed/VahaSelected/PagingLink')
        self.settings.endGroup()
        downloader = Downloader(initialLink, pagingLink, 25, 5)
        downloader.messenger.downloadProgressChanged.connect(self.onDownloadProgressChanged)
        downloader.messenger.downloadComplete.connect(self.onDownloadComplete)
        downloader.download()
    
    def onDownloadComplete(self):
        #QMessageBox.information(self, 'Download complete', 'Download complete!', QMessageBox.Ok)
        self.table_view.model().emit(SIGNAL("modelAboutToBeReset()"))
        self.settings.beginGroup('DATE_STAMP')
        self.settings.setValue('date/time', time.strftime('%d-%b-%Y, %H:%M:%S'))
        self.dateTimeStamp.setText('Data actuality: %s' % self.settings.value('date/time'))
        self.settings.endGroup()
        with open("elance.json") as json_file:
            jobDB = json.load(json_file)
        for elem in jobDB:
            words = nltk.tokenize.regexp_tokenize(elem['Title'].lower(), r'\w+')
            elem['Tokens'] = words
            elem['Skills'] = [t.strip() for t in elem['Skills'].split(',')]
        self.source_model.mylist = jobDB
        self.table_view.model().emit(SIGNAL("modelReset()"))
        self.btnDownload.setEnabled(True)
        self.myStatusBar.removeWidget(self.statusLabel)
        self.myStatusBar.removeWidget(self.progressBar)
        self.myStatusBar.showMessage(self.statusText, timeout = 5000)
                
    
    def onDownloadProgressChanged(self, stata):
        self.progressBar.setValue(stata[2])
        #text = 'Processed records{:5d} of{:5d}'.format(percentage[0], percentage[1])
        bajtikov = '{:,}'.format(stata[5])
        self.statusText = 'Processed page{:4d} of{:4d}. \
               Job entries{:5d} of{:5d}. \
               Downloaded{:>12s} Bytes'.format(stata[3], stata[4],
                                              stata[0], stata[1],
                                              bajtikov)
        self.statusLabel.setText(self.statusText)
        
    def copyToClipboard(self):
        clipboard = QApplication.clipboard()
        clipboard.setText(self.urlLabel.text())
        self.myStatusBar.showMessage(self.urlLabel.text(), timeout = 3000)
    
    def onSearchByWord(self):
        text, ok = QInputDialog.getText(self, 'Search the base by word(s)', 'Enter your keyword/phrase to search for:')
        if ok:
            words = [t.strip() for t in nltk.tokenize.regexp_tokenize(text.lower(), r'\w+')]
            self.table_view.model().emit(SIGNAL("modelAboutToBeReset()"))
            self.table_view.model().criteria = {'Description' : words}
            self.table_view.model().emit(SIGNAL("modelReset()"))
コード例 #18
0
ファイル: stepperUI.py プロジェクト: bsherin/shared_tools
class StepperWindow(QMainWindow):

    def __init__(self):
        QMainWindow.__init__(self)
        # filename = QFileDialog.getOpenFileName(self, "Open File")[0]
        # self.setWindowTitle(os.path.basename(filename))
        # self.transcript = StepperTranscript(filename)
        self.save_file_name = None
        self.explorer_table = None
        self.transcript = None
        self.setupUi(self)
        self.setAcceptDrops(True)

    def dragEnterEvent(self, event):
        event.accept()

    def dropEvent(self, event):
        for url in event.mimeData().urls():
            path = url.toLocalFile()
            self.open_transcript(fullname=path)

    def open_transcript(self, fullname=None):
        if self.transcript is not None:
            newStepperWindow = StepperWindow()
            stepper_windows.append(newStepperWindow)
            newStepperWindow.show()
            newStepperWindow.resize(1250, 1000)
            newStepperWindow.open_transcript(fullname)

        else:
            if fullname is None:
                fullname = QFileDialog.getOpenFileName(self, "Open File")[0]
            self.save_file_name = fullname
            self.setWindowTitle(os.path.basename(fullname))
            self.transcript = StepperTranscript(fullname)
            self.display_current_turn()
            self.show_transcript_in_explorer()
            if self.transcript.video_file_name != None:
                self.open_video(self.transcript.video_file_name)

    def position_transcript(self, position):
        self.transcript.move_to_position(1.0 * position / 100)
        self.display_current_turn()

    def show_transcript_in_explorer(self):
        transcript_array = self.transcript.get_transcript_as_array()
        self.click_handler = ExploreClickHandler(self)
        self.explorer_table = ExplorerTable(transcript_array, click_handler=self.click_handler)
        self.big_splitter.addWidget(self.explorer_table)
        # self.outer_layout.setStretch(2, 1)
        self.explorer_table.highlight_row(self.transcript.current_index())

    def go_to_next_turn(self):
        self.transcript.go_to_next()
        self.display_current_turn()

    def update_time(self):
        self.turn["time"] = self.time_field.value
        if self.explorer_table is not None:
            table_item = self.explorer_table.item(self.transcript.current_index(), 1)
            table_item.setText(self.time_field.value)

    def update_speaker(self):
        self.turn["speaker"] = self.speaker_field.value
        if self.explorer_table is not None:
            table_item = self.explorer_table.item(self.transcript.current_index(), 2)
            table_item.setText(self.speaker_field.value)

    def update_utterance(self):
        self.turn["utterance"] = self.utt_field.value
        if self.explorer_table is not None:
            table_item = self.explorer_table.item(self.transcript.current_index(), 3)
            table_item.setText(self.utt_field.value)

    def go_to_previous_turn(self):
        self.transcript.go_to_previous()
        self.display_current_turn()

    def go_to_row(self, the_row):
        self.transcript.go_to_index(the_row)
        self.display_current_turn()

    def display_current_turn(self):
        self.turn = self.transcript.current_turn()
        self.time_field.value = self.turn["time"]
        self.speaker_field.value = self.turn["speaker"]
        self.utt_field.value = self.turn["utterance"]
        if self.explorer_table is not None:
            self.explorer_table.highlight_row(self.transcript.current_index())
        self.utt_field.efield.setFocus()
        self.utt_field.efield.moveCursor(QTextCursor.Start, mode=QTextCursor.MoveAnchor)

    def delete_current_turn(self):
        self.transcript.delete_current()
        self.display_current_turn()

    def save_file_as(self):
        filename = QFileDialog.getSaveFileName(self, "File name for save")[0]
        self.save_file_name = filename
        self.transcript.commit_all()
        self.transcript.save_as_csv(filename)

    def save_file(self):
        if self.save_file_name is None:
            self.save_file_as()
        else:
            self.transcript.commit_all()
            self.transcript.save_as_csv(self.save_file_name)

    def revert_current_and_redisplay(self):
        self.transcript.revert_current()
        self.display_current_turn()

    def open_video(self, filename=None):
        # self.player = Player()
        # self.player.show()
        # self.player.resize(640, 480)
        self.player.OpenFile(filename)

    def play_or_pause(self):
        self.player.PlayPause()

    def slower(self):
        self.player.decrease_rate()

    def faster(self):
        self.player.increase_rate()

    def normal_speed(self):
        self.player.reset_rate()

    def fill_time_code(self):
        self.time_field.value = self.player.getCurrentTimeCode()

    def sync_video_and_play(self):
        self.sync_video()
        if not self.player.mediaplayer.is_playing():
            self.play_or_pause()

    def jump_back(self):
        self.player.jump_video_backward()

    def jump_forward(self):
        self.player.jump_video_forward()

    def sync_video(self):
        self.player.setTimeCode(self.time_field.value)

    def insert_before(self):
        new_uid = self.transcript.insert_new(self.transcript.current_uid)
        if self.explorer_table is not None:
            self.explorer_table.insert_row(self.transcript.current_index(), [new_uid, "", "", ""])
        self.display_current_turn()

    def insert_after(self):
        new_uid = self.transcript.insert_new(self.transcript.current_uid, "after")
        if self.explorer_table is not None:
            self.explorer_table.insert_row(self.transcript.current_index(), [new_uid, "", "", ""])
        self.display_current_turn()

    def closeEvent(self, event):
        msgBox = QMessageBox()
        msgBox.setText("Do you want to save before quitting?")
        msgBox.setInformativeText("Do you want to save your changes?")
        msgBox.setStandardButtons(QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel)
        msgBox.setDefaultButton(QMessageBox.Save)
        ret = msgBox.exec_()
        if ret == QMessageBox.Save:
            self.save_file()
            event.accept()
        elif ret == QMessageBox.Discard:
            event.accept()
        else:
            event.ignore()

    def commit(self):
        self.transcript.commit_current()

    def commit_all(self):
        self.transcript.commit_all()

    def go_to_next_word(self):
        c = self.utt_field.efield.textCursor()
        if c.selectedText() != "": # If nothing is selected, select the current word
            self.utt_field.efield.moveCursor(QTextCursor.NextWord, QTextCursor.MoveAnchor)
        self.utt_field.efield.moveCursor(QTextCursor.EndOfWord, QTextCursor.KeepAnchor)
        c = self.utt_field.efield.textCursor()
        if c.selectedText() == "": # this addresses the case where I'm in front of a blank space
            self.utt_field.efield.moveCursor(QTextCursor.NextWord, QTextCursor.MoveAnchor)
            self.utt_field.efield.moveCursor(QTextCursor.EndOfWord, QTextCursor.KeepAnchor)

    def go_to_previous_word(self):
        c = self.utt_field.efield.textCursor()
        pos = c.position()
        self.utt_field.efield.moveCursor(QTextCursor.StartOfWord, QTextCursor.MoveAnchor)
        self.utt_field.efield.moveCursor(QTextCursor.PreviousWord, QTextCursor.MoveAnchor)
        self.utt_field.efield.moveCursor(QTextCursor.EndOfWord, QTextCursor.KeepAnchor)
        c = self.utt_field.efield.textCursor()
        if c.position() == pos:
            self.utt_field.efield.moveCursor(QTextCursor.StartOfWord, QTextCursor.MoveAnchor)
            self.utt_field.efield.moveCursor(QTextCursor.PreviousWord, QTextCursor.MoveAnchor)
            self.utt_field.efield.moveCursor(QTextCursor.PreviousWord, QTextCursor.MoveAnchor)
            self.utt_field.efield.moveCursor(QTextCursor.EndOfWord, QTextCursor.KeepAnchor)

    def setupUi(self, stepperWindow):
        stepperWindow.setObjectName("stepperWindow")
        self.outer_widget = QtGui.QWidget(stepperWindow)
        # sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        # sizePolicy.setHorizontalStretch(0)
        # sizePolicy.setVerticalStretch(0)
        # sizePolicy.setHeightForWidth(self.outer_widget.sizePolicy().hasHeightForWidth())
        # self.outer_widget.setSizePolicy(sizePolicy)
        self.outer_widget.setObjectName("outer_widget")
        self.outer_layout = QtGui.QHBoxLayout(self.outer_widget)
        self.outer_layout.setContentsMargins(0, 0, 0, 0)
        self.outer_layout.setObjectName("outer_layout")
        self.big_splitter = QSplitter()
        self.outer_layout.addWidget(self.big_splitter)
        self.left_layout = QtGui.QVBoxLayout()
        self.left_layout.setObjectName("left_layout")
        self.left_widget = QWidget()
        self.left_widget.setLayout(self.left_layout)
        self.big_splitter.addWidget(self.left_widget)

        self.player = Player()
        self.left_layout.addWidget(self.player)
        self.left_layout.setStretch(0, 1)

        self.createDisplayFields()

        # Add all of the buttons
        self.allbuttonslayout = QtGui.QHBoxLayout()
        self.allbuttonslayout.setSizeConstraint(QtGui.QLayout.SetNoConstraint)
        self.allbuttonslayout.setObjectName("allbuttonslayout")
        self.gridbuttonlayout = QtGui.QGridLayout()
        self.gridbuttonlayout.setSizeConstraint(QtGui.QLayout.SetFixedSize)
        self.gridbuttonlayout.setVerticalSpacing(1)
        self.gridbuttonlayout.setObjectName("gridbuttonlayout")
        self.DeleteButton = QtGui.QPushButton(self.outer_widget)
        self.DeleteButton.setObjectName("DeleteButton")
        self.gridbuttonlayout.addWidget(self.DeleteButton, 0, 2, 1, 1)
        self.InsertAfterButton = QtGui.QPushButton(self.outer_widget)
        self.InsertAfterButton.setObjectName("InsertAfterButton")
        self.gridbuttonlayout.addWidget(self.InsertAfterButton, 0, 1, 1, 1)
        self.SaveAsButton = QtGui.QPushButton(self.outer_widget)
        self.SaveAsButton.setObjectName("SaveAsButton")
        self.gridbuttonlayout.addWidget(self.SaveAsButton, 1, 1, 1, 1)
        self.CommitAllButton = QtGui.QPushButton(self.outer_widget)
        self.CommitAllButton.setObjectName("CommitAllButton")
        self.gridbuttonlayout.addWidget(self.CommitAllButton, 2, 1, 1, 1)
        self.CommitButton = QtGui.QPushButton(self.outer_widget)
        self.CommitButton.setObjectName("CommitButton")
        self.gridbuttonlayout.addWidget(self.CommitButton, 2, 0, 1, 1)
        self.InsertBeforeButton = QtGui.QPushButton(self.outer_widget)
        self.InsertBeforeButton.setObjectName("InsertBeforeButton")
        self.gridbuttonlayout.addWidget(self.InsertBeforeButton, 0, 0, 1, 1)
        self.SaveButton = QtGui.QPushButton(self.outer_widget)
        self.SaveButton.setObjectName("SaveButton")
        self.gridbuttonlayout.addWidget(self.SaveButton, 1, 0, 1, 1)
        self.RevertButton = QtGui.QPushButton(self.outer_widget)
        self.RevertButton.setObjectName("RevertButton")
        self.gridbuttonlayout.addWidget(self.RevertButton, 2, 2, 1, 1)
        self.allbuttonslayout.addLayout(self.gridbuttonlayout)
        self.keypadGridLayout = QtGui.QGridLayout()
        self.keypadGridLayout.setSizeConstraint(QtGui.QLayout.SetFixedSize)
        self.keypadGridLayout.setObjectName("keypadGridLayout")
        self.SlowerButton = QtGui.QPushButton(self.outer_widget)
        self.SlowerButton.setObjectName("SlowerButton")
        self.keypadGridLayout.addWidget(self.SlowerButton, 2, 0, 1, 1)
        self.FasterButton = QtGui.QPushButton(self.outer_widget)
        self.FasterButton.setObjectName("FasterButton")
        self.keypadGridLayout.addWidget(self.FasterButton, 2, 2, 1, 1)
        self.NormalButton = QtGui.QPushButton(self.outer_widget)
        self.NormalButton.setObjectName("NormalButton")
        self.keypadGridLayout.addWidget(self.NormalButton, 2, 1, 1, 1)
        self.JumpBackButton = QtGui.QPushButton(self.outer_widget)
        self.JumpBackButton.setObjectName("JumpBackButton")
        self.keypadGridLayout.addWidget(self.JumpBackButton, 1, 0, 1, 1)
        self.NextButton = QtGui.QPushButton(self.outer_widget)
        self.NextButton.setObjectName("NextButton")
        self.keypadGridLayout.addWidget(self.NextButton, 0, 2, 1, 1)
        self.JumpForward = QtGui.QPushButton(self.outer_widget)
        self.JumpForward.setObjectName("JumpForward")
        self.keypadGridLayout.addWidget(self.JumpForward, 1, 2, 1, 1)
        self.PlayButton = QtGui.QPushButton(self.outer_widget)
        self.PlayButton.setObjectName("PlayButton")
        self.keypadGridLayout.addWidget(self.PlayButton, 1, 1, 1, 1)
        self.PreviousButton = QtGui.QPushButton(self.outer_widget)
        self.PreviousButton.setObjectName("PreviousButton")
        self.keypadGridLayout.addWidget(self.PreviousButton, 0, 0, 1, 1)
        self.GotoButton = QtGui.QPushButton(self.outer_widget)
        self.GotoButton.setObjectName("GotoButton")
        self.keypadGridLayout.addWidget(self.GotoButton, 0, 1, 1, 1)
        self.SyncButton = QtGui.QPushButton(self.outer_widget)
        self.SyncButton.setObjectName("SyncButton")
        self.keypadGridLayout.addWidget(self.SyncButton, 3, 2, 1, 1)
        self.FillButton = QtGui.QPushButton(self.outer_widget)
        self.FillButton.setObjectName("FillButton")
        self.keypadGridLayout.addWidget(self.FillButton, 3, 0, 1, 1)
        self.allbuttonslayout.addLayout(self.keypadGridLayout)

        self.ExplorerButton = QtGui.QPushButton(self.outer_widget)
        self.ExplorerButton.setObjectName("ExplorerButton")
        self.gridbuttonlayout.addWidget(self.ExplorerButton, 1, 2, 1, 1)

        # Change made by hand here

        self.left_layout.addLayout(self.allbuttonslayout)
        self.left_layout.setStretch(1, 0)
        self.left_layout.setStretch(2, 0)

        # self.splitter = QSplitter()
        # self.splitter.addWidget(self.player)
        # self.outer_layout.addWidget(self.splitter)
        # self.outer_layout.setStretch(1, 1)

        # stepperWindow.show_transcript_in_explorer()
        # if stepperWindow.transcript.video_file_name != None:
        #     self.open_video(stepperWindow.transcript.video_file_name)
        stepperWindow.setCentralWidget(self.outer_widget)

        self.menubar = QtGui.QMenuBar()
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1500, 22))
        self.menubar.setObjectName("menubar")
        stepperWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(stepperWindow)
        self.statusbar.setObjectName("statusbar")
        stepperWindow.setStatusBar(self.statusbar)

        self.retranslateUi(stepperWindow)
        QtCore.QObject.connect(self.GotoButton, QtCore.SIGNAL("clicked()"), stepperWindow.sync_video_and_play)
        QtCore.QObject.connect(self.JumpForward, QtCore.SIGNAL("clicked()"), stepperWindow.jump_forward)
        QtCore.QObject.connect(self.PlayButton, QtCore.SIGNAL("clicked()"), stepperWindow.play_or_pause)
        QtCore.QObject.connect(self.SyncButton, QtCore.SIGNAL("clicked()"), stepperWindow.sync_video)
        QtCore.QObject.connect(self.FillButton, QtCore.SIGNAL("clicked()"), stepperWindow.fill_time_code)
        QtCore.QObject.connect(self.NextButton, QtCore.SIGNAL("clicked()"), stepperWindow.go_to_next_turn)
        QtCore.QObject.connect(self.CommitButton, QtCore.SIGNAL("clicked()"), stepperWindow.commit)
        QtCore.QObject.connect(self.InsertBeforeButton, QtCore.SIGNAL("clicked()"), stepperWindow.insert_before)
        QtCore.QObject.connect(self.JumpBackButton, QtCore.SIGNAL("clicked()"), stepperWindow.jump_back)
        QtCore.QObject.connect(self.SlowerButton, QtCore.SIGNAL("clicked()"), stepperWindow.slower)
        QtCore.QObject.connect(self.FasterButton, QtCore.SIGNAL("clicked()"), stepperWindow.faster)
        QtCore.QObject.connect(self.NormalButton, QtCore.SIGNAL("clicked()"), stepperWindow.normal_speed)
        QtCore.QObject.connect(self.PreviousButton, QtCore.SIGNAL("clicked()"), stepperWindow.go_to_previous_turn)
        QtCore.QObject.connect(self.SaveButton, QtCore.SIGNAL("clicked()"), stepperWindow.save_file)
        QtCore.QObject.connect(self.SaveAsButton, QtCore.SIGNAL("clicked()"), stepperWindow.save_file_as)
        QtCore.QObject.connect(self.RevertButton, QtCore.SIGNAL("clicked()"), stepperWindow.revert_current_and_redisplay)
        QtCore.QObject.connect(self.DeleteButton, QtCore.SIGNAL("clicked()"), stepperWindow.delete_current_turn)
        QtCore.QObject.connect(self.InsertAfterButton, QtCore.SIGNAL("clicked()"), stepperWindow.insert_after)
        QtCore.QObject.connect(self.CommitAllButton, QtCore.SIGNAL("clicked()"), stepperWindow.commit_all)

        # Added this line by hand
        QtCore.QObject.connect(self.ExplorerButton, QtCore.SIGNAL("clicked()"), stepperWindow.show_transcript_in_explorer)

        QtCore.QMetaObject.connectSlotsByName(stepperWindow)

        # The following menu and shortcut stuff added by hand
        command_list = [
            [self.open_transcript, "Open Transcript", {}, "Ctrl+t"],
            [self.open_video, "Open Video", {}, "Ctrl+v"],
            [self.play_or_pause, "Play/Pause", {}, Qt.CTRL + Qt.Key_K],
            [self.save_file, "Save", {}, "Ctrl+s"],
            [self.player.jump_video_backward, "Jump Back", {}, Qt.CTRL + Qt.Key_J],
            [self.player.jump_video_forward, "Jump Forward", {}, Qt.CTRL + Qt.Key_L],
            [self.go_to_previous_turn, "Previous Turn", {}, "Ctrl+u"],
            [self.go_to_next_turn, "Next Turn", {}, "Ctrl+o"],
            [self.go_to_previous_word, "Previous Word", {}, "Ctrl+n"],
            [self.go_to_next_word, "Next Word", {}, "Ctrl+m"]
            ]

        menubar = self.menuBar()
        create_menu(self, menubar, "Stepper", command_list)

        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_0), self, self.play_or_pause)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_5), self, self.play_or_pause)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_7), self, self.go_to_previous_turn)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_9), self, self.go_to_next_turn)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_4), self, self.player.jump_video_backward)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_6), self, self.player.jump_video_forward)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_2), self, self.player.reset_rate)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_1), self, self.player.decrease_rate)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_3), self, self.player.increase_rate)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_I), self, self.sync_video_and_play)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_8), self, self.sync_video_and_play)

    def retranslateUi(self, stepperWindow):
        stepperWindow.setWindowTitle(QtGui.QApplication.translate("stepperWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
        self.DeleteButton.setText(QtGui.QApplication.translate("stepperWindow", "Delete", None, QtGui.QApplication.UnicodeUTF8))
        self.InsertAfterButton.setText(QtGui.QApplication.translate("stepperWindow", "Ins After", None, QtGui.QApplication.UnicodeUTF8))
        self.SaveAsButton.setText(QtGui.QApplication.translate("stepperWindow", "Save As ...", None, QtGui.QApplication.UnicodeUTF8))
        self.CommitAllButton.setText(QtGui.QApplication.translate("stepperWindow", "Commit all", None, QtGui.QApplication.UnicodeUTF8))
        self.CommitButton.setText(QtGui.QApplication.translate("stepperWindow", "Commit", None, QtGui.QApplication.UnicodeUTF8))
        self.InsertBeforeButton.setText(QtGui.QApplication.translate("stepperWindow", "Ins Before", None, QtGui.QApplication.UnicodeUTF8))
        self.SaveButton.setText(QtGui.QApplication.translate("stepperWindow", "Save", None, QtGui.QApplication.UnicodeUTF8))
        self.RevertButton.setText(QtGui.QApplication.translate("stepperWindow", "Revert", None, QtGui.QApplication.UnicodeUTF8))
        self.SlowerButton.setText(QtGui.QApplication.translate("stepperWindow", "Slower", None, QtGui.QApplication.UnicodeUTF8))
        self.FasterButton.setText(QtGui.QApplication.translate("stepperWindow", "Faster", None, QtGui.QApplication.UnicodeUTF8))
        self.NormalButton.setText(QtGui.QApplication.translate("stepperWindow", "Normal", None, QtGui.QApplication.UnicodeUTF8))
        self.JumpBackButton.setText(QtGui.QApplication.translate("stepperWindow", "Jump-", None, QtGui.QApplication.UnicodeUTF8))
        self.NextButton.setText(QtGui.QApplication.translate("stepperWindow", "Next", None, QtGui.QApplication.UnicodeUTF8))
        self.JumpForward.setText(QtGui.QApplication.translate("stepperWindow", "Jump+", None, QtGui.QApplication.UnicodeUTF8))
        self.PlayButton.setText(QtGui.QApplication.translate("stepperWindow", "Play", None, QtGui.QApplication.UnicodeUTF8))
        self.PreviousButton.setText(QtGui.QApplication.translate("stepperWindow", "Prev", None, QtGui.QApplication.UnicodeUTF8))
        self.GotoButton.setText(QtGui.QApplication.translate("stepperWindow", "GoTo", None, QtGui.QApplication.UnicodeUTF8))
        self.SyncButton.setText(QtGui.QApplication.translate("stepperWindow", "Sync Vid", None, QtGui.QApplication.UnicodeUTF8))
        self.FillButton.setText(QtGui.QApplication.translate("stepperWindow", "Fill Time", None, QtGui.QApplication.UnicodeUTF8))

        self.ExplorerButton.setText(QtGui.QApplication.translate("stepperWindow", "Explorer", None, QtGui.QApplication.UnicodeUTF8))

    def createDisplayFields(self):
        display_widget = QFrame()
        display_widget.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Sunken)
        self.left_layout.addWidget(display_widget)
        self.display_layout = QHBoxLayout()

        # self.turn = self.transcript.current_turn()
        self.time_field = qHotField("time", str, "00:00:00", min_size=75, max_size=75, pos="top", handler=self.update_time)
        self.display_layout.addWidget(self.time_field)
        self.speaker_field = qHotField("speaker", str, " ", min_size=75, max_size=75, pos="top", handler=self.update_speaker)
        self.display_layout.addWidget(self.speaker_field)
        self.utt_field = qHotField("utterance", str, " ", min_size=350, max_size=500, pos="top", handler=self.update_utterance, multiline=True)
        self.utt_field.setStyleSheet("font: 14pt \"Courier\";")
        # self.utt_field.efield.setFont(QFont('SansSerif', 12))
        self.display_layout.addWidget(self.utt_field)

        display_widget.setLayout(self.display_layout)
        self.display_layout.setStretchFactor(self.speaker_field, 0)
        self.display_layout.setStretchFactor(self.utt_field, 1)

        self.transcript_slider = QSlider(QtCore.Qt.Horizontal, self)
        self.display_layout.addWidget(self.transcript_slider)
        self.transcript_slider.setMaximum(100)
        self.connect(self.transcript_slider,
                     QtCore.SIGNAL("sliderMoved(int)"), self.position_transcript)
        self.left_layout.addWidget(self.transcript_slider)
コード例 #19
0
ファイル: PostView.py プロジェクト: wiz21b/koi
class PostViewWidget(HorsePanel):
    def __init__(self, parent, order_overview_widget, find_order_slot):
        global configuration

        super(PostViewWidget, self).__init__(parent)

        self.set_panel_title(_("Post overview"))
        self.bold_font = QFont(self.font())
        self.bold_font.setBold(True)
        self.nb_cols = 8  # Number of columns in the operation definition table

        self.order_overview_widget = order_overview_widget

        self.button = QPushButton(_("Refresh"), self)
        self.button.clicked.connect(self.refresh_action)
        self.sort_by_deadline_button = QRadioButton(_("By deadline"), self)
        self.sort_by_deadline_button.toggled.connect(self.sort_by_deadline)
        self.sort_by_size_button = QRadioButton(_("By hours left to do"), self)
        self.sort_by_size_button.toggled.connect(self.sort_by_size)

        # hlayout = QHBoxLayout()
        # hlayout.setObjectName("halyout")
        # hlayout.setContentsMargins(0,0,0,0)
        # hlayout.addWidget(self.sort_by_deadline_button)
        # hlayout.addWidget(self.sort_by_size_button)
        # hlayout.addWidget(self.button)
        # hlayout.addStretch()

        self.navbar = NavBar(self, [(self.sort_by_deadline_button, None),
                                    (self.sort_by_size_button, None),
                                    (self.button, None),
                                    (_("Find"), find_order_slot)])
        self.navbar.buttons[3].setObjectName("specialMenuButton")

        self.vlayout = QVBoxLayout(self)
        self.vlayout.setObjectName("Vlayout")
        self.vlayout.addWidget(
            TitleWidget(_("Posts Overview"), self, self.navbar))

        self._table_model = QStandardItemModel(1, self.nb_cols, self)
        self.table_view = QTableView(None)
        self.table_view.setModel(self._table_model)
        self.table_view.selectionModel().currentChanged.connect(
            self.operation_selected)

        self.table_view.verticalHeader().hide()
        self.table_view.horizontalHeader().hide()
        self.table_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows)

        # This forces Qt to expand layout once I fill data in
        # FIXME dirty but I really don't get why setting
        # the mini width to something smaller (that happens at
        # startup, on first refresh) doesn't work
        self.table_view.setMinimumWidth(1)
        self.table_view.setMaximumWidth(1)

        self.post_view_scene = PostViewScene(self, order_overview_widget)
        self.post_view_scene_view = QGraphicsView(self)
        self.post_view_scene_view.setScene(self.post_view_scene)
        self.post_view_scene_view.setSizePolicy(QSizePolicy.Expanding,
                                                QSizePolicy.Expanding)

        self.splitter = QSplitter(Qt.Horizontal)
        self.splitter.addWidget(
            SubFrame(_("Posts"), self.table_view, self.splitter))
        self.splitter.addWidget(
            SubFrame(_("Workload"), self.post_view_scene_view, self.splitter))
        # self.splitter.setStretchFactor(0,1)
        self.splitter.setStretchFactor(1, 1)
        self.vlayout.addWidget(self.splitter)

        # hlayout = QHBoxLayout()
        # hlayout.addWidget(SubFrame(_("Posts"),self.table_view,self))
        # hlayout.addWidget(SubFrame(_("Workload"),self.post_view_scene_view,self))
        # hlayout.setStretch(1,1)
        # self.vlayout.addLayout(hlayout)

        self.vlayout.setStretch(0, 0)
        self.vlayout.setStretch(1, 1)

        self.setLayout(self.vlayout)

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.slidePostsScene)

        self.current_view_y = 0

    def _data_load(self):
        global dao

        all_operations = dao.operation_dao.load_all_operations_ready_for_production(
        )
        operation_definitions = dao.operation_definition_dao.all_direct_frozen(
        )

        return operation_definitions, all_operations

    def _reset_operation_definitions(self, operations):
        self._table_model.setColumnCount(1)
        self._table_model.setRowCount(len(operations))

        # BUG This should be refreshed on reload() too

        row = col = 0
        first_active = None

        for opdef in operations:

            if opdef.operation_definition_id in self.post_view_scene.drawn_operations_data:
                # currently total planned time
                t = self.post_view_scene.drawn_operations_data[
                    opdef.operation_definition_id]
                ndx = self._table_model.index(row, col)
                if not first_active:
                    first_active = ndx
                self._table_model.setData(
                    ndx, u"{} {}".format(opdef.description, t), Qt.DisplayRole)
                # self._table_model.setData(ndx,self.bold_font,Qt.FontRole)

                self._table_model.setData(self._table_model.index(row, col),
                                          opdef.operation_definition_id,
                                          Qt.UserRole)
                row += 1

            else:
                pass
                # self._table_model.setData(self._table_model.index(row,col),opdef.description,Qt.DisplayRole)

            # = col + 1
            # if col == self.nb_cols:
            #     col = 0
            #     row += 1

        self._table_model.setRowCount(row)

        # self.table_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        # self.vlayout.setStretch(0,0)
        # self.vlayout.setStretch(1,10)
        # self.vlayout.setStretch(2,10000)

        # height = 0
        # for c in range(self.table_view.model().rowCount()):
        #     height += self.table_view.rowHeight(c) + 1 # +1 for cell border
        # self.table_view.setMinimumHeight(height)
        # self.table_view.setMaximumHeight(height)
        for i in range(self.nb_cols):
            self.table_view.resizeColumnToContents(i)
        self.table_view.setMaximumWidth(self.table_view.columnWidth(0))
        self.table_view.setMinimumWidth(self.table_view.columnWidth(0))
        self.table_view.setSizePolicy(QSizePolicy.Maximum,
                                      QSizePolicy.Preferred)

        self.table_view.update()
        self.splitter.update()

        return first_active

    def slide_to_operation(self, opdef_id):
        if opdef_id in self.post_view_scene.posts_offsets:
            self.slide_target_opdef_id = opdef_id
            # mainlog.debug("Target y = {}".format(self.post_view_scene.posts_offsets[self.slide_target_opdef]))
            self.timer.start(20)

    @Slot()
    def slidePostsScene(self):
        if self.slide_target_opdef_id is None:
            return

        # self.post_view_scene_view
        self.post_view_scene.set_cursor_on(
            self.slide_target_opdef_id
        )  # This done here also aviod some screen trashing

        v = self.post_view_scene_view.verticalScrollBar().value()
        # mainlog.debug( "slidePostsScene : {}".format(v))

        r = self.post_view_scene.posts_offsets[self.slide_target_opdef_id]
        target_y = r.y() + r.height() / 2
        delta = (target_y - self.current_view_y) * 0.4
        self.current_view_y = self.current_view_y + delta
        self.post_view_scene_view.centerOn(0, self.current_view_y)
        # mainlog.debug( "slidePostsScene : {} / {}".format(target_y, self.current_view_y))

        if self.post_view_scene_view.verticalScrollBar().value() == v:
            # Close enough => stop moving
            # FIXME not correct because we must stop when the view stops moving, not when the goal we set for centerOn is reached
            self.timer.stop()

    @Slot(QModelIndex, QModelIndex)
    def operation_selected(self, ndx_cur, ndx_old):
        if ndx_cur.isValid():
            opdef = self._table_model.data(ndx_cur, Qt.UserRole)
            if opdef:
                self.slide_to_operation(
                    self._table_model.data(ndx_cur, Qt.UserRole))

    @Slot()
    def refresh_action(self):
        # FIXME reload operations as well

        operation_definitions, all_operations = self._data_load()

        # mainlog.debug("reload")
        if self.sort_by_deadline_button.isChecked():
            self.post_view_scene.reload(self, operation_definitions,
                                        all_operations, 1)
        elif self.sort_by_size_button.isChecked():
            self.post_view_scene.reload(self, operation_definitions,
                                        all_operations, 2)
        else:
            self.post_view_scene.reload(self, operation_definitions,
                                        all_operations, 0)

        # mainlog.debug("reset")
        first_active = self._reset_operation_definitions(operation_definitions)
        # self.table_view.selectionModel().currentChanged.connect(self.operation_selected)
        if first_active:
            self.table_view.setCurrentIndex(first_active)

        # mainlog.debug("done reset")

    @Slot(bool)
    def sort_by_deadline(self, checked):
        if checked:
            self.refresh_action()

    @Slot(bool)
    def sort_by_size(self, checked):
        if checked:
            self.refresh_action()

    order_part_double_clicked = Signal(int)

    # Callback that will be called by HooverBar
    def set_on_order_part(self, order_part_id):
        self.order_part_double_clicked.emit(order_part_id)
コード例 #20
0
class MainWindow(QDialog):
    """monkey_linux UI"""
    def __init__(self,parent=None):
        super(MainWindow, self).__init__()
        self.init_conf()
        self.setParent(parent)
        common.Log.info("set up ui")
        self.setup_ui()
        self.findDeviceAction.triggered.connect(self.get_device_status)
        self.deleteDeviceAction.triggered.connect(self.del_device)
        # self.storeButton.clicked.connect(self.set_conf)
        self.startButton.clicked.connect(self.start)
        self.stopButton.clicked.connect(self.stop)
        self.checkLogButton.clicked.connect(self.check)
        self.monkeyButton.clicked.connect(self.checkMonkeyLog)
        self.exportButton.clicked.connect(self.exportConf)
        self.importButton.clicked.connect(self.importConf)
        self.setAbout.triggered.connect(self.about)
        self.startTime = datetime.datetime.now()
        self.secsTime = float(1) * 60 * 60



    def setup_ui(self):
        # main window width hand height
        # self.setMinimumWidth(600)
        self.setMaximumWidth(800)
        self.setMinimumHeight(600)
        # main window title
        self.setWindowTitle(static.title)
        # file menu bar
        self.menuBar = QMenuBar()
        self.menuBar.setMaximumHeight(23)
        # self.menuFile = self.menuBar.addMenu(static.menuFile)
        # self.importAction = QAction(QIcon(static.importPNG), static.importFile, self)
        # self.exportAction = QAction(QIcon(static.exportPNG), static.exportFile, self)
        # self.menuFile.addAction(self.importAction)
        # self.menuFile.addAction(self.exportAction)
        self.setEnvActioin = QAction(QIcon(static.setPNG), static.pcSet, self)
        self.menuSet = self.menuBar.addMenu(static.menuSet)
        self.menuSet.addAction(self.setEnvActioin)

        self.setAbout = QAction(QIcon(static.setPNG), static.menuAbout, self)
        self.setAbout.setStatusTip('About')  # 状态栏提示
        self.menuHelp = self.menuBar.addMenu(static.menuHelp)
        self.menuHelp.addAction(self.setAbout)



        # set all layout
        self.hbox = QHBoxLayout(self)

        # device ========
        self.topLeft = QFrame(self)
        self.topLeft.setMaximumSize(218, 300)
        self.topLeft.setMinimumSize(218, 200)
        self.topLeft.setFrameShape(QFrame.StyledPanel)
        self.topLeftLayout = QVBoxLayout(self.topLeft)
        self.toolBar = QToolBar()
        # self.androidDeviceAction = QRadioButton('Android', self)
        # self.androidDeviceAction.setFocusPolicy(Qt.NoFocus)
        # self.ipDeviceAction = QRadioButton('IP', self)
        # self.ipDeviceAction.setFocusPolicy(Qt.NoFocus)
        # self.ipDeviceAction.move(10, 10)
        # self.ipDeviceAction.toggle()
        self.findDeviceAction = QAction(QIcon(static.findDevice), static.findDeviceButton, self)
        self.deleteDeviceAction = QAction(QIcon(static.deleteDevice), static.deleteDeviceButton, self)
        # self.toolBar.addWidget(self.androidDeviceAction)
        # self.toolBar.addWidget(self.ipDeviceAction)
        self.toolBar.addAction(self.findDeviceAction)
        self.toolBar.addAction(self.deleteDeviceAction)
        self.deviceLab = QLabel(static.deviceName, self)
        self.device = QTableWidget(1, 2)
        self.device.setHorizontalHeaderLabels(['name', 'status'])
        self.device.setColumnWidth(0, 100)
        self.device.setColumnWidth(1, 80)
        self.topLeftLayout.addWidget(self.deviceLab)
        self.topLeftLayout.addWidget(self.toolBar)

        self.topLeftLayout.addWidget(self.device)


        # set button or other for running monkey or not and status of device and log ========
        self.topRight = QFrame(self)
        self.topRight.setFrameShape(QFrame.StyledPanel)
        self.topRight.setMaximumHeight(40)
        self.startButton = QPushButton(QIcon(static.startPNG), "")
        self.stopButton = QPushButton(QIcon(static.stopPNG), "")

        self.status = QLabel(static.status)
        self.statusEdit = QLineEdit(self)
        self.statusEdit.setReadOnly(True)
        self.statusEdit.setMaximumWidth(80)
        self.statusEdit.setMinimumWidth(80)
        self.statusEdit.setText("")
        # check log
        self.checkLogButton = QPushButton(static.checkLog)
        self.checkLogButton.setMaximumHeight(20)
        self.checkLogButton.setMinimumHeight(20)
        self.checkLogButton.setMaximumWidth(60)
        self.selectLog = QLabel(static.selectlog)
        self.logfile = QComboBox()
        self.dirlist = os.listdir(os.path.join(DIR, "Result"))
        for d in self.dirlist:
            if d != "AutoMonkey.log":
                self.logfile.insertItem(0, d)
        self.logfile.setMaximumWidth(150)
        self.logfile.setMaximumHeight(20)
        self.logfile.setMinimumHeight(20)
        self.topLayout = QHBoxLayout(self.topRight)
        self.topLayout.addWidget(self.startButton)
        self.topLayout.addWidget(self.stopButton)
        self.topLayout.addWidget(self.status)
        self.topLayout.addWidget(self.statusEdit)
        self.topLayout.addWidget(self.selectLog)
        self.topLayout.addWidget(self.logfile)
        self.topLayout.addWidget(self.checkLogButton)

        # set parameter for monkey =======
        self.midRight = QFrame(self)
        self.midRight.setMaximumSize(555, 200)
        self.midRight.setMinimumSize(555, 200)
        self.midRight.setFrameShape(QFrame.StyledPanel)
        self.midRightLayout = QVBoxLayout(self.midRight)
        self.subLayout0 = QVBoxLayout()
        self.subLayout1 = QVBoxLayout()
        self.subLayout2 = QHBoxLayout()
        self.subLayout3 = QVBoxLayout()
        self.subLayout4 = QVBoxLayout()
        self.subLayout5 = QHBoxLayout()
        self.subLayout6 = QHBoxLayout()
        self.toolBar = QToolBar()
        # self.storeAction = QAction(QIcon(static.storePNG), static.storeButton, self)
        self.startAction = QAction(QIcon(static.startPNG), static.startButton, self)
        self.stopAction = QAction(QIcon(static.stopPNG), static.stopButton, self)
        # self.toolBar.addAction(self.storeAction)
        self.toolBar.addAction(self.startAction)
        self.toolBar.addAction(self.stopAction)
        self.timeLongLbl = QLabel(static.timeString, self)
        self.timeLong = QLineEdit(self)
        self.timeLong.setMaximumWidth(100)
        self.timeLong.setMinimumWidth(100)
        self.timeLong.setPlaceholderText(static.timeLong)
        self.timeLongUnit = QLabel("H")
        self.etSetLbl = QLabel(static.eventTypeSet)
        self.etSet = QTableWidget(2, 2)
        self.etSet.setMaximumHeight(150)
        self.etSet.setHorizontalHeaderLabels(['option', 'value'])
        self.etSet.horizontalHeader().setStretchLastSection(True)
        self.etSet.setItem(0, 0, QTableWidgetItem("--throttle"))
        self.etSet.setItem(0, 1, QTableWidgetItem(str(static.eventType["--throttle"])))
        # set event type percent
        self.etPercentLbl = QLabel(static.eventTpyePercent, self)
        self.etPercent = QTableWidget(2, 2)
        self.etPercent.setMaximumHeight(150)
        self.etPercent.setHorizontalHeaderLabels(['option', 'value'])
        self.etPercent.horizontalHeader().setStretchLastSection(True)
        self.etPercent.setItem(0, 0, QTableWidgetItem("--pct-touch"))
        self.etPercent.setItem(0, 1, QTableWidgetItem(str(static.eventPercent["--pct-touch"])))
        self.etPercent.setItem(1, 0, QTableWidgetItem("--pct-motion"))
        self.etPercent.setItem(1, 1, QTableWidgetItem(str(static.eventPercent["--pct-motion"])))
        # self.storeButton = QPushButton(QIcon(static.storePNG), static.storeButton)
        # self.storeButton.setToolTip(static.storeButton)
        self.exportButton = QPushButton(QIcon(static.exportPNG), static.exportFile)
        self.exportButton.setToolTip(static.exportFile)
        self.importButton = QPushButton(QIcon(static.importPNG), static.importFile)
        self.importButton.setToolTip(static.importFile)
        self.subLayout2.addWidget(self.timeLongLbl)
        self.subLayout2.addWidget(self.timeLong)
        self.subLayout2.addWidget(self.timeLongUnit)
        self.subLayout2.addWidget(QLabel(" " * 300))
        # self.subLayout2.addWidget(self.storeButton)
        self.subLayout2.addWidget(self.exportButton)
        self.subLayout2.addWidget(self.importButton)

        self.subLayout0.addLayout(self.subLayout2)
        self.subLayout3.addWidget(self.etSetLbl)
        self.subLayout3.addWidget(self.etSet)
        self.subLayout4.addWidget(self.etPercentLbl)
        self.subLayout4.addWidget(self.etPercent)
        self.subLayout5.addLayout(self.subLayout0)
        self.subLayout6.addLayout(self.subLayout3)
        self.subLayout6.addLayout(self.subLayout4)
        self.midRightLayout.addLayout(self.subLayout5)
        self.midRightLayout.addLayout(self.subLayout6)

        # log ========
        self.bottom = QFrame(self)
        self.bottom.setFrameShape(QFrame.StyledPanel)
        # log information
        self.logInfo = QLabel(static.logInfo)
        # information filter
        self.logFilter = QLabel(static.logFilter)
        self.monkeyButton = QPushButton(static.openMonkeyLog)
        self.combo = QComboBox()
        for i in range(len(static.logLevel)):
            self.combo.addItem(static.logLevel[i])
        self.combo.setMaximumWidth(55)
        self.combo.setMaximumHeight(20)
        self.combo.setMinimumHeight(20)
        # information details
        self.bottomLayout = QVBoxLayout(self.bottom)
        self.subLayout = QHBoxLayout()
        self.subLayout.addWidget(self.logInfo)
        for i in range(10):
            self.subLayout.addWidget(QLabel(""))
        self.subLayout.addWidget(self.monkeyButton)
        self.subLayout.addWidget(self.logFilter)
        self.subLayout.addWidget(self.combo)
        self.bottomLayout.addLayout(self.subLayout)
        self.tabwidget = TabWidget()
        self.tabwidget.setMinimumHeight(100)
        self.bottomLayout.addWidget(self.tabwidget)

        # splitter mainWindow ++++++++++++++++++++++++++++++++++++
        self.splitter2 = QSplitter(Qt.Vertical)
        self.splitter2.addWidget(self.topRight)
        self.splitter2.addWidget(self.midRight)
        self.splitter0 = QSplitter(Qt.Horizontal)
        self.splitter0.addWidget(self.topLeft)
        self.splitter0.addWidget(self.splitter2)
        self.splitter1 = QSplitter(Qt.Vertical)
        self.splitter1.addWidget(self.menuBar)
        self.splitter1.addWidget(self.splitter0)
        self.splitter1.addWidget(self.bottom)
        self.hbox.addWidget(self.splitter1)
        self.setLayout(self.hbox)
        self.show()

    def about(self):
        common.showDialog(static.menuAbout, static.dialogAbout)

    def init_conf(self):
        common.Log.info("init monkey conf")
        with open(monkeyConfFile, "w") as f:
            f.write("deviceList = []" + "\n")
            f.write("times = " + static.times + "\n")
            f.write("--throttle = " + static.eventType["--throttle"] + "\n")
            f.write("--pct-touch = " + static.eventPercent["--pct-touch"] + "\n")
            f.write("--pct-motion = " + static.eventPercent["--pct-motion"] + "\n")

    def setup_env(self):
        pass

    def _set_eventType(self, confFile):
        try:
            option = self.etSet.item(0, 0).text()
            value = self.etSet.item(0, 1).text()
            if value > "0":
                with open(confFile, 'a+') as f:
                    f.write(option + " = " + value + "\n")
        except AttributeError, e:
            pass
コード例 #21
0
ファイル: FilterBox.py プロジェクト: LLNL/boxfish
class FilterTab(QWidget):
    """This class is the GUI for creating filters for the FilterBox
       module. This GUI will be added as a tab to the ModuleFrame
       tab dialog.
    """

    applySignal = Signal(Clause)

    def __init__(self, parent, mframe, existing_filters):
        """Create a FilterTab with the given parent TabDialog, logical
           parent ModuleFrame mframe, and existing_filters list of Clause
           objects.
        """
        super(FilterTab, self).__init__(parent)

        self.mframe = mframe
        self.parent = parent
        self.attributes = self.mframe.agent.datatree.generateAttributeList()

        self.clause_list = list()
        self.clause_dict = dict()
        # Right now we only look at the first passed in filter.
        # TODO: At GUI to switch between existing filters
        if existing_filters is not None and len(existing_filters) > 0:
            for clause in existing_filters[0].conditions.clauses:
                self.clause_list.append(str(clause))
                self.clause_dict[str(clause)] = clause

        self.clause_model = QStringListModel(self.clause_list)

        layout = QVBoxLayout(self)
        self.sidesplitter = QSplitter(Qt.Horizontal)

        # You can only select one attribute at a time to build the 
        # filter clauses
        self.data_view = QTreeView(self)
        self.data_view.setModel(self.mframe.agent.datatree)
        self.data_view.setDragEnabled(True)
        self.data_view.setDropIndicatorShown(True)
        self.data_view.expandAll()
        self.sidesplitter.addWidget(self.data_view)
        self.sidesplitter.setStretchFactor(1,1)

        self.filter_widget = self.buildFilterWidget()
        self.sidesplitter.addWidget(self.filter_widget)
        self.sidesplitter.setStretchFactor(1,0)

        layout.addWidget(self.sidesplitter)

        # Apply buttons
        buttonWidget = QWidget()
        buttonLayout = QHBoxLayout(buttonWidget)
        self.applyButton = QPushButton("Apply")
        self.applyButton.clicked.connect(self.applyFilter)
        self.closeButton = QPushButton("Apply & Close")
        self.closeButton.clicked.connect(self.applyCloseFilter)
        buttonLayout.addWidget(self.applyButton)
        buttonLayout.addWidget(self.closeButton)
        buttonWidget.setLayout(buttonLayout)

        layout.addWidget(buttonWidget)
        self.setLayout(layout)

    def applyFilter(self):
        """Emits the applySignal with the Clause object currently
           represented by this FilterTab.
        """
        num_clauses = len(self.clause_list)
        if num_clauses == 0:
            self.applySignal.emit(None)
        else:
            self.applySignal.emit(Clause("and", *self.clause_dict.values()))

    def applyCloseFilter(self):
        """Calls applyFilter and then closes the containing TabDialog."""
        self.applyFilter()
        self.parent.close()

    def buildFilterWidget(self):
        """Creates the filter portion of the widget by laying out
           the subwidgets for relations, workspace and existing
           clauses.
        """
        filter_widget = QWidget()
        filter_layout = QVBoxLayout(filter_widget)

        filter_layout.addWidget(self.buildRelationsWidget())
        filter_layout.addItem(QSpacerItem(5,5))
        filter_layout.addWidget(self.buildWorkFrame())
        filter_layout.addItem(QSpacerItem(5,5))
        filter_layout.addWidget(self.buildFilterListView())

        filter_widget.setLayout(filter_layout)
        return filter_widget

    def buildFilterListView(self):
        """Creates the QListView that contains all of the basic Clause
           objects.
        """
        groupBox = QGroupBox("Clauses")
        layout = QVBoxLayout(groupBox)

        self.list_view = QListView(groupBox)
        self.list_view.setModel(self.clause_model)
        layout.addWidget(self.list_view)

        layout.addItem(QSpacerItem(5,5))
        self.delButton = QPushButton("Remove Selected Clause")
        self.delButton.clicked.connect(self.deleteClause)
        layout.addWidget(self.delButton)

        groupBox.setLayout(layout)
        return groupBox

    def buildWorkFrame(self):
        """Creates the grouped set of widgets that allow users to build
           basic Clause objects.
        """
        groupBox = QGroupBox("Clause Workspace")
        layout = QHBoxLayout(groupBox)

        attributeCompleter = QCompleter(self.attributes)
        attributeCompleter.setCompletionMode(QCompleter.InlineCompletion)
        self.dropAttribute = DropLineEdit(self, self.mframe.agent.datatree, "",
            attributeCompleter)
        self.dropRelation = DropTextLabel("__")
        self.dropValue = FilterValueLineEdit(groupBox,
            self.mframe.agent.datatree, self.dropAttribute)

        # Clear dropValue when dropAttribute changes
        self.dropAttribute.textChanged.connect(self.dropValue.clear)

        # Enter in dropValue works like addButton
        self.dropValue.returnPressed.connect(self.addClause)

        self.addButton = QPushButton("Add", groupBox)
        self.addButton.clicked.connect(self.addClause)
        layout.addWidget(self.dropAttribute)
        layout.addItem(QSpacerItem(5,5))
        layout.addWidget(self.dropRelation)
        layout.addItem(QSpacerItem(5,5))
        layout.addWidget(self.dropValue)
        layout.addItem(QSpacerItem(5,5))
        layout.addWidget(self.addButton)

        groupBox.setLayout(layout)
        return groupBox

    def buildRelationsWidget(self):
        """Creates the set of draggable relations. These relations are
           whatever is available in the relations dict of Table.
        """
        relations_widget = QWidget()
        layout = QHBoxLayout(relations_widget)

        for relation in Table.relations:
            layout.addWidget(DragTextLabel(relation))

        relations_widget.setLayout(layout)
        return relations_widget

    def addClause(self):
        """Adds a basic Clause to the current filter."""
        if self.dropRelation.text() in Table.relations \
            and len(self.dropValue.text()) > 0 \
            and len(self.dropAttribute.text()) > 0:

            clause = Clause(self.dropRelation.text(),
                TableAttribute(self.dropAttribute.text()),
                self.dropValue.text())

            # Guard double add
            if str(clause) not in self.clause_dict:
                self.clause_list.append(str(clause))
                self.clause_dict[str(clause)] = clause
                self.clause_model.setStringList(self.clause_list)

    def deleteClause(self):
        """Removes the selected basic Clause objects from the current
           filter.
        """
        clause = self.clause_model.data(
            self.list_view.selectedIndexes()[0], Qt.DisplayRole)
        if clause is not None and clause in self.clause_list:
            self.clause_list.remove(clause)
            del self.clause_dict[clause]
            self.clause_model.setStringList(self.clause_list)
コード例 #22
0
class RobocompDslGui(QMainWindow):
    def __init__(self, parent=None):
        super(RobocompDslGui, self).__init__(parent)
        self.setWindowTitle("Create new component")
        # self._idsl_paths = []
        self._communications = {
            "implements": [],
            "requires": [],
            "subscribesTo": [],
            "publishes": []
        }
        self._interfaces = {}
        self._cdsl_doc = CDSLDocument()
        self._command_process = QProcess()

        self._main_widget = QWidget()
        self._main_layout = QVBoxLayout()
        self.setCentralWidget(self._main_widget)

        self._name_layout = QHBoxLayout()
        self._name_line_edit = QLineEdit()
        self._name_line_edit.textEdited.connect(self.update_component_name)
        self._name_line_edit.setPlaceholderText("New component name")
        self._name_layout.addWidget(self._name_line_edit)
        self._name_layout.addStretch()

        # DIRECTORY SELECTION
        self._dir_line_edit = QLineEdit()
        # self._dir_line_edit.textEdited.connect(self.update_completer)
        self._dir_completer = QCompleter()
        self._dir_completer_model = QFileSystemModel()
        if os.path.isdir(ROBOCOMP_COMP_DIR):
            self._dir_line_edit.setText(ROBOCOMP_COMP_DIR)
            self._dir_completer_model.setRootPath(ROBOCOMP_COMP_DIR)
        self._dir_completer.setModel(self._dir_completer_model)
        self._dir_line_edit.setCompleter(self._dir_completer)

        self._dir_button = QPushButton("Select directory")
        self._dir_button.clicked.connect(self.set_output_directory)
        self._dir_layout = QHBoxLayout()
        self._dir_layout.addWidget(self._dir_line_edit)
        self._dir_layout.addWidget(self._dir_button)

        # LIST OF ROBOCOMP INTERFACES
        self._interface_list = QListWidget()
        self._interface_list.setSelectionMode(
            QAbstractItemView.ExtendedSelection)
        self._interface_list.itemSelectionChanged.connect(
            self.set_comunication)

        # LIST OF CONNECTION TyPES
        self._type_combo_box = QComboBox()
        self._type_combo_box.addItems(
            ["publishes", "implements", "subscribesTo", "requires"])
        self._type_combo_box.currentIndexChanged.connect(
            self.reselect_existing)

        # BUTTON TO ADD A NEW CONNECTION
        # self._add_connection_button = QPushButton("Add")
        # self._add_connection_button.clicked.connect(self.add_new_comunication)
        self._add_connection_layout = QHBoxLayout()
        # self._add_connection_layout.addWidget(self._add_connection_button)
        self._language_combo_box = QComboBox()
        self._language_combo_box.addItems(["Python", "Cpp", "Cpp11"])
        self._language_combo_box.currentIndexChanged.connect(
            self.update_language)
        self._add_connection_layout.addWidget(self._language_combo_box)
        self._add_connection_layout.addStretch()
        self._gui_check_box = QCheckBox()
        self._gui_check_box.stateChanged.connect(self.update_gui_selection)
        self._gui_label = QLabel("Use Qt GUI")
        self._add_connection_layout.addWidget(self._gui_label)
        self._add_connection_layout.addWidget(self._gui_check_box)

        # WIDGET CONTAINING INTERFACES AND TYPES
        self._selection_layout = QVBoxLayout()
        self._selection_layout.addWidget(self._type_combo_box)
        self._selection_layout.addWidget(self._interface_list)
        self._selection_layout.addLayout(self._add_connection_layout)
        self._selection_widget = QWidget()
        self._selection_widget.setLayout(self._selection_layout)

        # TEXT EDITOR WITH THE RESULTING CDSL CODE
        self._editor = QTextEdit(self)
        self._editor.setHtml("")

        self._document = self._editor.document()
        self._component_directory = None

        # SPLITTER WITH THE SELECTION AND THE CODE
        self._body_splitter = QSplitter(Qt.Horizontal)
        self._body_splitter.addWidget(self._selection_widget)
        self._body_splitter.addWidget(self._editor)
        self._body_splitter.setStretchFactor(0, 2)
        self._body_splitter.setStretchFactor(1, 9)

        # CREATION BUTTONS
        self._create_button = QPushButton("Create .cdsl")
        self._create_button.clicked.connect(self.write_cdsl_file)
        self._creation_layout = QHBoxLayout()
        self._creation_layout.addStretch()
        self._creation_layout.addWidget(self._create_button)

        self._console = QConsole()
        self._command_process.readyReadStandardOutput.connect(
            self._console.standard_output)
        self._command_process.readyReadStandardError.connect(
            self._console.error_output)

        # ADDING WIDGETS TO MAIN LAYOUT
        self._main_widget.setLayout(self._main_layout)
        self._main_layout.addLayout(self._name_layout)
        self._main_layout.addLayout(self._dir_layout)
        self._main_layout.addWidget(self._body_splitter)
        self._main_layout.addLayout(self._creation_layout)
        self._main_layout.addWidget(self._console)
        self.setMinimumSize(800, 500)
        self._editor.setText(self._cdsl_doc.generate_doc())

    # self.editor->show();

    # def update_completer(self, path):
    # 	print "update_completer %s"%path
    # 	info = QFileInfo(path)
    # 	if info.exists() and info.isDir():
    # 			if not path.endswith(os.path.pathsep):
    # 				new_path = os.path.join(path, os.sep)
    # 				# self._dir_line_edit.setText(new_path)
    # 			all_dirs_output = [dI for dI in os.listdir(path) if os.path.isdir(os.path.join(path, dI))]
    # 			print all_dirs_output
    # 			self._dir_completer.complete()

    def load_idsl_files(self, fullpath=None):
        if fullpath is None:
            fullpath = ROBOCOMP_INTERFACES
        idsls_dir = os.path.join(ROBOCOMP_INTERFACES, "IDSLs")
        if os.path.isdir(idsls_dir):
            for full_filename in os.listdir(idsls_dir):
                file_name, file_extension = os.path.splitext(full_filename)
                if "idsl" in file_extension.lower():
                    full_idsl_path = os.path.join(idsls_dir, full_filename)
                    # self._idsl_paths.append(os.path.join(idsls_dir,full_filename))
                    self.parse_idsl_file(full_idsl_path)
        self._interface_list.addItems(self._interfaces.keys())

    def parse_idsl_file(self, fullpath):

        with open(fullpath, 'r') as fin:
            interface_name = None
            for line in fin:
                result = re.findall(r'^\s*interface\s+(\w+)\s*\{?\s*$',
                                    line,
                                    flags=re.MULTILINE)
                if len(result) > 0:
                    interface_name = result[0]
            print("%s for idsl %s" % (interface_name, fullpath))
            if interface_name is not None:
                self._interfaces[interface_name] = fullpath

    def add_new_comunication(self):
        interface_names = self._interface_list.selectedItems()
        com_type = str(self._type_combo_box.currentText())
        for iface_name_item in interface_names:
            iface_name = str(iface_name_item.text())
            self._communications[com_type].append(iface_name)
            idsl_full_path = self._interfaces[iface_name]
            idsl_full_filename = os.path.basename(idsl_full_path)
            self._cdsl_doc.add_comunication(com_type, iface_name)
            self._cdsl_doc.add_import(idsl_full_filename)
        self.update_editor()

    def set_comunication(self):
        interface_names = self._interface_list.selectedItems()
        com_type = str(self._type_combo_box.currentText())
        self._communications[com_type] = []
        self._cdsl_doc.clear_comunication(com_type)
        for iface_name_item in interface_names:
            iface_name = str(iface_name_item.text())
            self._communications[com_type].append(iface_name)
            self._cdsl_doc.add_comunication(com_type, iface_name)
        self.update_imports()
        self.update_editor()

    def update_imports(self):
        self._cdsl_doc.clear_imports()
        for com_type in self._communications:
            for iface_name in self._communications[com_type]:
                idsl_full_path = self._interfaces[iface_name]
                idsl_full_filename = os.path.basename(idsl_full_path)
                self._cdsl_doc.add_import(idsl_full_filename)

    def update_language(self):
        language = self._language_combo_box.currentText()
        self._cdsl_doc.set_language(str(language))
        self.update_editor()

    def update_gui_selection(self):
        checked = self._gui_check_box.isChecked()
        if checked:
            self._cdsl_doc.set_qui(True)
        else:
            self._cdsl_doc.set_qui(False)
        self.update_editor()

    def update_component_name(self, name):
        self._cdsl_doc.set_name(name)
        self.update_editor()

    def update_editor(self):
        self._editor.setText(self._cdsl_doc.generate_doc())

    def set_output_directory(self):
        dir_set = False
        while not dir_set:
            dir = QFileDialog.getExistingDirectory(
                self, "Select Directory", ROBOCOMP_COMP_DIR,
                QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)
            if self.check_dir_is_empty(str(dir)):
                self._dir_line_edit.setText(dir)
                dir_set = True

    def write_cdsl_file(self):
        component_dir = str(self._dir_line_edit.text())
        text = self._cdsl_doc.generate_doc()
        if not self._name_line_edit.text():
            component_name, ok = QInputDialog.getText(self,
                                                      'No component name set',
                                                      'Enter component name:')
            if ok:
                self.update_component_name(component_name)
                self._name_line_edit.setText(component_name)
            else:
                return False

        if not os.path.exists(component_dir):
            if QMessageBox.Yes == QMessageBox.question(
                    self, "Directory doesn't exist.",
                    "Do you want create the directory %s?" % component_dir,
                    QMessageBox.Yes | QMessageBox.No):
                os.makedirs(component_dir)
            else:
                QMessageBox.question(
                    self, "Directory not exist",
                    "Can't create a component witout a valid directory")
                return False

        file_path = os.path.join(component_dir,
                                 str(self._name_line_edit.text()) + ".cdsl")
        if os.path.exists(file_path):
            if QMessageBox.No == QMessageBox.question(
                    self, "File already exists", "Do you want to overwrite?",
                    QMessageBox.Yes | QMessageBox.No):
                return False

        with open(file_path, 'w') as the_file:
            the_file.write(text)
        self.execute_robocomp_cdsl()
        return True

    def execute_robocomp_cdsl(self):
        cdsl_file_path = os.path.join(
            str(self._dir_line_edit.text()),
            str(self._name_line_edit.text()) + ".cdsl")
        command = "python -u %s/robocompdsl.py %s %s" % (
            ROBOCOMPDSL_DIR, cdsl_file_path,
            os.path.join(str(self._dir_line_edit.text())))
        self._console.append_custom_text("%s\n" % command)
        self._command_process.start(command,
                                    QProcess.Unbuffered | QProcess.ReadWrite)

    def reselect_existing(self):
        com_type = self._type_combo_box.currentText()
        selected = self._communications[com_type]
        self._interface_list.clearSelection()
        for iface in selected:
            items = self._interface_list.findItems(iface,
                                                   Qt.MatchFlag.MatchExactly)
            if len(items) > 0:
                item = items[0]
                item.setSelected(True)

    def check_dir_is_empty(self, dir_path):
        if len(os.listdir(dir_path)) > 0:
            msgBox = QMessageBox()
            msgBox.setWindowTitle("Directory not empty")
            msgBox.setText(
                "The selected directory is not empty.\n"
                "For a new Component you usually want a new directory.\n"
                "Do you want to use this directory anyway?")
            msgBox.setStandardButtons(QMessageBox.Yes)
            msgBox.addButton(QMessageBox.No)
            msgBox.setDefaultButton(QMessageBox.No)
            if msgBox.exec_() == QMessageBox.Yes:
                return True
            else:
                return False
        else:
            return True
コード例 #23
0
ファイル: mainwindow.py プロジェクト: chemikadze/QUcsmBrowser
class BrowserWindow(QMainWindow):

    MO_ROLE = Qt.UserRole+1

    def __init__(self, conn):
        super(BrowserWindow, self).__init__()
        self._conn = conn
        self._resolver = AsyncResolver()
        self._resolver.object_resolved.connect(self._data_resolved)
        self._resolver.start()
        self._init_models()
        self._init_gui()
        self._init_data()
        self._init_connections()

    def __del__(self):
        self._resolver.stop_work()
        self._resolver.terminate()

    def _init_models(self):
        self._hierarchy_model = QStandardItemModel()
        self._hierarchy_model.setColumnCount(2)
        self._hierarchy_model.setHorizontalHeaderLabels(['class', 'dn'])
        self._details_model = QStandardItemModel()
        self._details_model.setColumnCount(2)
        self._details_model.setHorizontalHeaderLabels(['Property', 'Value'])

    def _init_gui(self):
        self._widget = QSplitter(self, Qt.Horizontal)
        self._hierarchy_view = QTreeView(self._widget)
        self._details_view = QTableView(self._widget)

        self._widget.addWidget(self._hierarchy_view)
        self._widget.addWidget(self._details_view)
        self._widget.setStretchFactor(0, 2)
        self._widget.setStretchFactor(1, 1)
        self.setCentralWidget(self._widget)

        self._hierarchy_view.setModel(self._hierarchy_model)
        self._details_view.setModel(self._details_model)

        self._hierarchy_view.expanded.connect(self._mo_item_expand)

    def _init_data(self):
        item = self._row_for_mo(self._conn.resolve_dn(''))
        self._hierarchy_model.insertRow(0, item)

    def _init_connections(self):
        self.connect(self._resolver,
                        SIGNAL('object_resolved(QVariant)'),
                     self,
                        SLOT('_data_resolved(QVariant)'))
        self._hierarchy_view.activated.connect(self._item_activated)
        #self.connect(self._hierarchy_view.selectionModel(),
        #                SIGNAL('currentChanged(QModelIndex,QModelIndex)'),
        #             self,
        #                SLOT('_current_changed(QModelIndex, QModelIndex)'))
        self.connect(self._hierarchy_view.selectionModel(),
                        SIGNAL('activated(QModelIndex)'),
                     self,
                        SLOT('_item_activated(QModelIndex)'))


    def _row_for_mo(self, mo):
        row = [QStandardItem(mo.ucs_class), QStandardItem(mo.dn)]
        for item in row:
            item.setEditable(False)
        row[0].appendColumn([QStandardItem('Loading...')])
        row[0].setData(mo, self.MO_ROLE)
        return row

    def _add_mo_in_tree(self, mo, index=QtCore.QModelIndex()):
        item = None
        if index.isValid():
            item = self._hierarchy_model.itemFromIndex(index)
        else:
            item = self._get_item_for_dn(self._parent_dn(mo.dn))
        if item:
            item.appendColumn([self._row_for_mo(mo)[0]])
        self.auto_width()

    def _add_mos_in_tree(self, mos, index=QtCore.QModelIndex()):
        item = None
        if index.isValid():
            item = self._hierarchy_model.itemFromIndex(index)
        else:
            if not mos:
                return
            item = self._get_item_for_dn(self._parent_dn(mos[0].dn))
        while item.columnCount():
            item.removeColumn(0)
        items = map(self._row_for_mo, mos)
        if items:
            for x in xrange(len(items[0])):
                item.appendColumn([row[x] for row in items])
        self.auto_width()

    @staticmethod
    def _parent_dn(dn):
        parent_dn, _, rn = dn.rpartition('/')
        return parent_dn

    def _get_item_for_dn(self, dn):
        parent_dn = dn
        items = self._hierarchy_model.findItems(parent_dn, column=1)
        if items:
            return self._hierarchy_model.item(items[0].row())
        return None

    @QtCore.Slot('_data_resolved(QVariant)')
    def _data_resolved(self, datav):
        print 'Data resolved: ', datav
        index, data = datav
        if isinstance(data, UcsmObject):
            self._add_mo_in_tree(data, index=index)
        else:
            self._add_mos_in_tree(data, index=index)

    @QtCore.Slot('_current_changed(QModelIndex,QModelIndex)')
    def _current_changed(self, curr, prev):
        self._item_activated(curr)

    @QtCore.Slot('_item_activated(QModelIndex)')
    def _item_activated(self, index):
        print 'Activated: %s data %s' % (index, index.data(self.MO_ROLE))
        if index.sibling(0, 0).isValid():
            index = index.sibling(0, 0)
            data = index.data(self.MO_ROLE)
            self.set_detail_object(data)

    def _mo_item_expand(self, index):
        obj = index.data(self.MO_ROLE)
        print 'Expanded object: %s' % obj
        try:
            self._resolver.add_task(lambda: (index,
                                        self._conn.resolve_children(obj.dn)))
        except (KeyError, AttributeError):
            QtGui.QMessageBox.critical(0, 'Error', 'Object does not have dn')

    def auto_width(self):
        for view in [self._hierarchy_view, self._details_view]:
            for col in xrange(view.model().columnCount()):
                view.resizeColumnToContents(col)

    def set_detail_object(self, object):
        self._details_model.removeRows(0, self._details_model.rowCount())
        for k, v in object.attributes.iteritems():
            row = [QStandardItem(k), QStandardItem(v)]
            for item in row:
                item.setEditable(False)
            self._details_model.appendRow(row)
        self.auto_width()
コード例 #24
0
    def __init__(self, *args, **kwargs ):
        
        QMainWindow.__init__( self, *args, **kwargs )
        self.installEventFilter( self )
        #self.setWindowFlags( QtCore.Qt.Drawer )
        self.setWindowTitle( Window_global.title )

        verticalSplitter = QSplitter(QtCore.Qt.Vertical)
        self.setCentralWidget( verticalSplitter )
        
        horizonSplitter1 = QSplitter(QtCore.Qt.Horizontal)
        horizonSplitter2 = QSplitter(QtCore.Qt.Horizontal)
        
        verticalSplitter.addWidget( horizonSplitter1 )
        verticalSplitter.addWidget( horizonSplitter2 )
        
        widgetSelArea  = QWidget()
        layoutSelArea  = QVBoxLayout(widgetSelArea)
        labelSelTextList = QLabel( 'Images from Selection' )
        selTextureList = QListWidget()
        selTextureList.setSelectionMode( QAbstractItemView.ExtendedSelection )
        layoutSelArea.addWidget( labelSelTextList )
        layoutSelArea.addWidget( selTextureList )
        imageBaseSelArea = ImageBase()
        
        horizonSplitter1.addWidget( widgetSelArea )
        horizonSplitter1.addWidget( imageBaseSelArea )        
        
        widgetPathArea = QWidget()
        layoutPathArea = QVBoxLayout( widgetPathArea )
        layoutAddTab = QHBoxLayout()
        removeTabButton = QPushButton( 'Remove Tab' )
        addTabButton = QPushButton( 'Add Tab' )
        self.tabWidget = Tab()
        buttonLayout = QHBoxLayout()
        getImageButton = QPushButton( 'Get Image' )
        removeImageButton   = QPushButton( 'Remove Image' )
        layoutPathArea.addLayout( layoutAddTab )
        layoutPathArea.addWidget( self.tabWidget )
        layoutPathArea.addLayout( buttonLayout )
        imageBasePathArea = ImageBase()
        layoutAddTab.addWidget( removeTabButton )
        layoutAddTab.addWidget( addTabButton )
        buttonLayout.addWidget( getImageButton )
        buttonLayout.addWidget( removeImageButton )
        
        horizonSplitter2.addWidget( widgetPathArea )
        horizonSplitter2.addWidget( imageBasePathArea )        
        
        Window_global.selTextureList  = selTextureList
        Window_global.imageBaseSelArea = imageBaseSelArea
        Window_global.imageBasePathArea = imageBasePathArea
        Window_global.verticalSplitter = verticalSplitter
        Window_global.horizonSplitter1 = horizonSplitter1
        Window_global.horizonSplitter2 = horizonSplitter2
        Window_global.getImageButton = getImageButton
        Window_global.removeImageButton = removeImageButton
        Window_global.tabWidget = self.tabWidget
        Window_global.tabWidget.addTab( 'newTab' )
        
        verticalSplitter.setSizes( [100,100] )
        horizonSplitter1.setSizes( [100,100] )
        horizonSplitter2.setSizes( [100,100] )
        
        Window_global.loadInfo()
        try:Window_global.loadInfo2()
        except:pass
        Functions.updateSelTextureList()
        
        QtCore.QObject.connect( addTabButton,    QtCore.SIGNAL( 'clicked()' ), self.addTab )
        QtCore.QObject.connect( removeTabButton, QtCore.SIGNAL( 'clicked()' ), self.removeTab )
        QtCore.QObject.connect( Window_global.selTextureList, QtCore.SIGNAL( 'itemSelectionChanged()' ),  Functions.loadImageSelArea )
        QtCore.QObject.connect( Window_global.horizonSplitter1, QtCore.SIGNAL( 'splitterMoved(int,int)' ),  Functions.splitterMoved1 )
        QtCore.QObject.connect( Window_global.horizonSplitter2, QtCore.SIGNAL( 'splitterMoved(int,int)' ),  Functions.splitterMoved2 )
        QtCore.QObject.connect( getImageButton,  QtCore.SIGNAL( 'clicked()' ),  Functions.getImage  )
        QtCore.QObject.connect( removeImageButton,  QtCore.SIGNAL( 'clicked()' ),  Functions.removeImage  )
        
        imageBaseSelArea.clear()
        imageBasePathArea.clear()
        
        getImageButton.setEnabled( False )
        removeImageButton.setEnabled( False )
コード例 #25
0
    def __init__(self, *args, **kwargs):

        QMainWindow.__init__(self, *args, **kwargs)
        self.installEventFilter(self)
        #self.setWindowFlags( QtCore.Qt.Drawer )
        self.setWindowTitle(Window_global.title)

        verticalSplitter = QSplitter(QtCore.Qt.Vertical)
        self.setCentralWidget(verticalSplitter)

        horizonSplitter1 = QSplitter(QtCore.Qt.Horizontal)
        horizonSplitter2 = QSplitter(QtCore.Qt.Horizontal)

        verticalSplitter.addWidget(horizonSplitter1)
        verticalSplitter.addWidget(horizonSplitter2)

        widgetSelArea = QWidget()
        layoutSelArea = QVBoxLayout(widgetSelArea)
        labelSelTextList = QLabel('Images from Selection')
        selTextureList = QListWidget()
        selTextureList.setSelectionMode(QAbstractItemView.ExtendedSelection)
        layoutSelArea.addWidget(labelSelTextList)
        layoutSelArea.addWidget(selTextureList)
        imageBaseSelArea = ImageBase()

        horizonSplitter1.addWidget(widgetSelArea)
        horizonSplitter1.addWidget(imageBaseSelArea)

        widgetPathArea = QWidget()
        layoutPathArea = QVBoxLayout(widgetPathArea)
        layoutAddTab = QHBoxLayout()
        removeTabButton = QPushButton('Remove Tab')
        addTabButton = QPushButton('Add Tab')
        self.tabWidget = Tab()
        buttonLayout = QHBoxLayout()
        getImageButton = QPushButton('Get Image')
        removeImageButton = QPushButton('Remove Image')
        layoutPathArea.addLayout(layoutAddTab)
        layoutPathArea.addWidget(self.tabWidget)
        layoutPathArea.addLayout(buttonLayout)
        imageBasePathArea = ImageBase()
        layoutAddTab.addWidget(removeTabButton)
        layoutAddTab.addWidget(addTabButton)
        buttonLayout.addWidget(getImageButton)
        buttonLayout.addWidget(removeImageButton)

        horizonSplitter2.addWidget(widgetPathArea)
        horizonSplitter2.addWidget(imageBasePathArea)

        Window_global.selTextureList = selTextureList
        Window_global.imageBaseSelArea = imageBaseSelArea
        Window_global.imageBasePathArea = imageBasePathArea
        Window_global.verticalSplitter = verticalSplitter
        Window_global.horizonSplitter1 = horizonSplitter1
        Window_global.horizonSplitter2 = horizonSplitter2
        Window_global.getImageButton = getImageButton
        Window_global.removeImageButton = removeImageButton
        Window_global.tabWidget = self.tabWidget
        Window_global.tabWidget.addTab('newTab')

        verticalSplitter.setSizes([100, 100])
        horizonSplitter1.setSizes([100, 100])
        horizonSplitter2.setSizes([100, 100])

        Window_global.loadInfo()
        try:
            Window_global.loadInfo2()
        except:
            pass
        Functions.updateSelTextureList()

        QtCore.QObject.connect(addTabButton, QtCore.SIGNAL('clicked()'),
                               self.addTab)
        QtCore.QObject.connect(removeTabButton, QtCore.SIGNAL('clicked()'),
                               self.removeTab)
        QtCore.QObject.connect(Window_global.selTextureList,
                               QtCore.SIGNAL('itemSelectionChanged()'),
                               Functions.loadImageSelArea)
        QtCore.QObject.connect(Window_global.horizonSplitter1,
                               QtCore.SIGNAL('splitterMoved(int,int)'),
                               Functions.splitterMoved1)
        QtCore.QObject.connect(Window_global.horizonSplitter2,
                               QtCore.SIGNAL('splitterMoved(int,int)'),
                               Functions.splitterMoved2)
        QtCore.QObject.connect(getImageButton, QtCore.SIGNAL('clicked()'),
                               Functions.getImage)
        QtCore.QObject.connect(removeImageButton, QtCore.SIGNAL('clicked()'),
                               Functions.removeImage)

        imageBaseSelArea.clear()
        imageBasePathArea.clear()

        getImageButton.setEnabled(False)
        removeImageButton.setEnabled(False)
コード例 #26
0
class MainWindow(QMainWindow):
    """The application's main window
    """

    # Emitted when there are pending files to be processed
    new_pending_files = QtCore.Signal()

    def __init__(self, app):
        super(MainWindow, self).__init__()

        # Window layout - a splitter with the image on the left and controls
        # on the right
        self._image_widget = ImageLabel(self)
        self._controls = Controls(self)
        self._splitter = QSplitter()
        self._splitter.addWidget(self._image_widget)
        self._splitter.addWidget(self._controls)
        self._splitter.setSizes([1200, 600])

        # Main window layout
        self.setCentralWidget(self._splitter)

        # Connect controls to handlers
        self._controls.ok.clicked.connect(self.ok)
        self._controls.cancel.clicked.connect(self.cancel)
        self._controls.inbox.choose_directory.clicked.connect(self.choose_inbox)
        self._controls.processed.choose_directory.clicked.connect(self.choose_processed)

        # Directories
        mydocuments = QDesktopServices.storageLocation(
            QDesktopServices.DocumentsLocation)
        self._inbox = Path(QSettings().value('inbox',
            str(Path(mydocuments) / 'inbox')))
        self._processed = Path(QSettings().value('processed',
            str(Path(mydocuments) / 'processed')))

        self._controls.inbox.set_link(str(self._inbox.as_uri()), self._inbox.name)
        self._controls.processed.set_link(str(self._processed.as_uri()), self._processed.name)

        # A stack of Path objects to be processed
        self._pending_files = []

        # The Path currently shown in the UI
        self._under_review = None

        # Watch the inbox directory, if it exists
        self.new_pending_files.connect(self.process_next_pending,
            QtCore.Qt.QueuedConnection)

        if self._inbox.is_dir():
            self._watcher = NewFileWatcher(self._inbox, IMAGE_SUFFIXES_RE)
            self._watcher.new_file.connect(self.new_image_file)
        else:
            self._watcher = None

        self.empty_controls()

        # Setup drag-drop handling
        self.setAcceptDrops(True)
        self._controls.installEventFilter(self)
        self._splitter.installEventFilter(self)

    def new_inbox_directory(self):
        """Watch the inbox directory
        """
        print('MainWindow.new_inbox_directory [{0}]'.format(self._inbox))
        if self._watcher:
            self._watcher.new_file.disconnect()

        self._watcher = NewFileWatcher(self._inbox, IMAGE_SUFFIXES_RE)
        self._watcher.new_file.connect(self.new_image_file)

    def new_image_file(self, path):
        """Slot for self._watcher.new_file
        """
        print('MainWindow.new_image_file [{0}]'.format(path))
        self._pending_files.append(path)
        self.new_pending_files.emit()

    @report_to_user
    def process_next_pending(self):
        """Loads the next pending image for review
        """
        print('MainWindow.process_next_pending: [{0}] files'.format(
            len(self._pending_files)))
        if not self._under_review:
            if self._pending_files:
                self.review_image(self._pending_files.pop())
            else:
                self.empty_controls()

    def review_image(self, path):
        """Loads path for review
        """
        print('MainWindow.review_image [{0}]'.format(path))

        # Arbitrary delay to give the capture software time to finish writing
        # the image.
        time.sleep(1)
        image = cv2.imread(str(path))
        if image is None:
            raise ValueError('Unable to read [{0}]'.format(path))
        else:
            self._under_review = path
            self.setWindowTitle('')
            self.setWindowFilePath(str(path))
            self._controls.specimen.setText(QSettings().value('specimen'))
            self._controls.location.setText(QSettings().value('location'))
            self._image_widget.set_pixmap(QPixmap.fromImage(qimage_of_bgr(image)))
            self._controls.image_handling.setEnabled(True)

    def empty_controls(self):
        """Clears controls
        """
        print('MainWindow.empty_controls')
        self._under_review = None
        self.setWindowTitle('Syrup')
        self.setWindowFilePath(None)
        self._image_widget.set_pixmap(None)
        self._controls.clear()
        self._controls.image_handling.setEnabled(False)

    @report_to_user
    def ok(self):
        print('MainWindow.ok')
        specimen = self._controls.specimen.text()
        location = self._controls.location.text()
        if not SPECIMEN_RE.match(specimen):
            raise ValueError('Please enter nine digits for the specimen barcode')
        elif not LOCATION_RE.match(location):
            raise ValueError('Please enter a letter "L" and nine digits for the '
                             'location barcode')
        else:
            if not self._processed.is_dir():
                self._processed.mkdir(parents=True)
            destination = self._processed / '{0}_{1}'.format(specimen, location)
            destination = destination.with_suffix(self._under_review.suffix)
            move_and_rename(self._under_review, destination)
            QSettings().setValue('specimen', specimen)
            QSettings().setValue('location', location)
            self._under_review = None
            self.process_next_pending()

    @report_to_user
    def cancel(self):
        """Closes the image under review without moving the image file
        """
        print('MainWindow.cancel')
        self._under_review = None
        self.process_next_pending()

    @report_to_user
    def choose_inbox(self):
        """Prompts the user to choose the inbox directory
        """
        directory = QFileDialog.getExistingDirectory(self,
            "Choose the inbox directory", str(self._inbox))
        if directory:
            directory = Path(directory)
            if directory == self._processed:
                raise ValueError('The inbox directory cannot be the same as '
                                 'the processed directory')
            else:
                self._inbox = directory
                print('New inbox directory [{0}]'.format(self._inbox))
                self._controls.inbox.set_link(str(self._inbox.as_uri()),
                    self._inbox.name)
                QSettings().setValue('inbox', str(self._inbox))
                self.new_inbox_directory()

    @report_to_user
    def choose_processed(self):
        """Prompts the user to choose the processed directory
        """
        directory = QFileDialog.getExistingDirectory(self,
            "Choose the processed directory", str(self._processed))
        if directory:
            directory = Path(directory)
            if directory == self._inbox:
                raise ValueError('The inbox directory cannot be the same as '
                                 'the processed directory')
            else:
                self._processed = directory
                print('New processed directory [{0}]'.format(self._processed))
                self._controls.processed.set_link(str(self._processed.as_uri()),
                    self._processed.name)
                QSettings().setValue('processed', str(self._processed))

    def write_geometry_settings(self):
        "Writes geometry to settings"
        print('MainWindow.write_geometry_settings')

        # Taken from http://stackoverflow.com/a/8736705
        # TODO LH Test on multiple display system
        s = QSettings()

        s.setValue("mainwindow/geometry", self.saveGeometry())
        s.setValue("mainwindow/pos", self.pos())
        s.setValue("mainwindow/size", self.size())

    def show_from_geometry_settings(self):
        print('MainWindow.show_from_geometry_settings')

        # TODO LH What if screen resolution, desktop config change or roaming
        # profile means that restored state is outside desktop?
        s = QSettings()

        self.restoreGeometry(s.value("mainwindow/geometry", self.saveGeometry()))
        if not (self.isMaximized() or self.isFullScreen()):
            self.move(s.value("mainwindow/pos", self.pos()))
            self.resize(s.value("mainwindow/size", self.size()))
        self.show()

    def closeEvent(self, event):
        """QWidget virtual
        """
        print('MainWindow.closeEvent')
        self.write_geometry_settings()
        event.accept()

    def eventFilter(self, obj, event):
        "Event filter that accepts drag-drop events"
        if event.type() in (QEvent.DragEnter, QEvent.Drop):
            return True
        else:
            return super(MainWindow, self).eventFilter(obj, event)

    def _accept_drag_drop(self, event):
        """If no image is under review and event refers to a single image file,
        returns the path. Returns None otherwise.
        """
        if self._under_review:
            return None
        else:
            urls = event.mimeData().urls() if event.mimeData() else None
            path = Path(urls[0].toLocalFile()) if urls and 1 == len(urls) else None
            print(path, IMAGE_SUFFIXES_RE.match(path.suffix))
            if path and IMAGE_SUFFIXES_RE.match(path.suffix):
                return urls[0].toLocalFile()
            else:
                return None

    def dragEnterEvent(self, event):
        """QWidget virtual
        """
        print('MainWindow.dragEnterEvent')
        if self._accept_drag_drop(event):
            event.acceptProposedAction()
        else:
            super(MainWindow, self).dragEnterEvent(event)

    @report_to_user
    def dropEvent(self, event):
        """QWidget virtual
        """
        print('MainWindow.dropEvent')
        res = self._accept_drag_drop(event)
        if res:
            event.acceptProposedAction()
            self.review_image(Path(res))
        else:
            super(MainWindow, self).dropEvent(event)