Пример #1
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)
Пример #2
0
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
Пример #3
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)
Пример #4
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 )
Пример #5
0
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()"))
Пример #6
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)