Example #1
0
 def __init__(self, screenWidth = 1280, screenHeight = 1024):
   
     QtGui.QMainWindow.__init__(self)
     self.setGeometry(0, 0, screenWidth, screenHeight)
     self.countingWindow = CounterGUI()
     self.translateUi()
     self.countingWindow.setupUi(self)
     self.resize(screenWidth,screenHeight)
     self.scene = QtGui.QGraphicsScene()
     self.countingWindow.imageView.setScene(self.scene)
     
     # Reimplementation of keypress event management
     self.keyPressEvent = self.manageCounterKeyboardEvent
     
     self.setItemCount(0)
     self.countingWindow.finishButton.setEnabled(False)
     self.countingWindow.resetCounterButton.setEnabled(False)
     self.connectSignals()
Example #2
0
 def __init__(self, screenWidth = 1280, screenHeight = 1024):
   
     QtWidgets.QMainWindow.__init__(self)
     self.setGeometry(0, 0, screenWidth, screenHeight)
     self.countingWindow = CounterGUI()
     self.translateUi()
     self.countingWindow.setupUi(self)
     self.resize(screenWidth,screenHeight)
     self.scene = QtWidgets.QGraphicsScene()
     self.countingWindow.imageView.setScene(self.scene)
     
     # Reimplementation of keypress event management
     self.keyPressEvent = self.manageCounterKeyboardEvent
     
     self.setItemCount(0)
     self.countingWindow.finishButton.setEnabled(False)
     self.countingWindow.resetCounterButton.setEnabled(False)
     self.connectSignals()
Example #3
0
class ItemCounter(QtGui.QMainWindow):
    """
    This class provides a Main Window with a graphic view 
    where an image with items to be counted is placed and
    counting such items can be performed using the mouse
    """
    
    # Defines the color for marker and its outline
    markerPen = QtGui.QPen(QtGui.QColor(QtCore.Qt.black))
    markerBrush = QtGui.QBrush(QtGui.QColor(QtCore.Qt.red))
    textPen = QtGui.QPen(QtGui.QColor(QtCore.Qt.yellow))
    
                
    def __init__(self, screenWidth = 1280, screenHeight = 1024):
      
        QtGui.QMainWindow.__init__(self)
        self.setGeometry(0, 0, screenWidth, screenHeight)
        self.countingWindow = CounterGUI()
        self.translateUi()
        self.countingWindow.setupUi(self)
        self.resize(screenWidth,screenHeight)
        self.scene = QtGui.QGraphicsScene()
        self.countingWindow.imageView.setScene(self.scene)
        
        # Reimplementation of keypress event management
        self.keyPressEvent = self.manageCounterKeyboardEvent
        
        self.setItemCount(0)
        self.countingWindow.finishButton.setEnabled(False)
        self.countingWindow.resetCounterButton.setEnabled(False)
        self.connectSignals()
        
        
    def translateUi(self):
        """
        This function localizates GUI and related messages
        """
        # We get the running dir and the locale
        self.running_dir = os.path.dirname(__file__)
        locale = QtCore.QLocale().name()
        
        # Generation of paths for localization files, must be inside
        # i18n folder and their name should be like:
        # theeggcounter_[LOCALE].qm
        # counter_gui_[LOCALE].qm
        # aboutdialog_[LOCALE].qm
        # WHere [LOCALE] is the name of the locale following BCP47 guidelines
        # You can create your own translations by creating new files with 
        # QtLinguist.
        
        mainTranslatorPath = os.path.join(\
            self.running_dir, 'i18n', 'theeggcounter_{0}.qm'.format(locale))
        UiTranslatorPath = os.path.join(\
            self.running_dir, 'i18n', 'counter_gui_{0}.qm'.format(locale))
        aboutTranslatorPath = os.path.join(\
            self.running_dir, 'i18n', 'aboutdialog_{0}.qm'.format(locale))
        
        print mainTranslatorPath
        
        # Localization
        self.mainTranslator = QtCore.QTranslator()
        self.UiTranslator = QtCore.QTranslator()
        self.aboutTranslator = QtCore.QTranslator()
       
        self.mainTranslator.load(mainTranslatorPath)
        self.UiTranslator.load(UiTranslatorPath)
        self.aboutTranslator.load(aboutTranslatorPath)
                
        QtCore.QCoreApplication.installTranslator(self.mainTranslator)
        QtCore.QCoreApplication.installTranslator(self.UiTranslator)
        QtCore.QCoreApplication.installTranslator(self.aboutTranslator)
        
    def connectSignals(self):
        """
        Connects GUI buttons as well as menu actions with their event handlers
        """
        self.countingWindow.loadImageButton.clicked.connect(self.loadImage)
        self.countingWindow.resetCounterButton.clicked.connect(self.resetCounter)
        self.countingWindow.finishButton.clicked.connect(self.finishCount)
        self.countingWindow.actionExit.triggered.connect(self.exitCounter)
        self.countingWindow.actionAbout.triggered.connect(self.about)
        
        
    def loadImage(self):
        """
        Loads an image from disk and displays it
        """
        filenameDialog = QtGui.QFileDialog.getOpenFileName(None,
                    self.tr("Select an image to load"),
                    './', "JPG/PNG images (*.jpg *.jpeg *.png);")
        
        self.filename = str(filenameDialog)
        
        pixmap = QtGui.QPixmap(self.filename)
        pixmap = pixmap.scaledToHeight(\
          self.countingWindow.imageView.height(),QtCore.Qt.SmoothTransformation)
        self.pixmap = QtGui.QGraphicsPixmapItem(pixmap, scene = self.scene)
        
        # Reimplementation of the mousePressEvent of the pixmap
        self.pixmap.mousePressEvent = self.manageCounterMouseEvent
                
        # We calculate the width of the pixmap and subsequently, the step
        # for scrolling the view. The view shift is calculated so visibility
        # of all the markers is guaranteed while scrolling the view
        
        self.pixmapWidth = pixmap.width()
        self.viewShift = self.pixmapWidth / ((self.pixmapWidth\
          / self.countingWindow.imageView.width()) + 1) 
        
        # Sets the scrollbar to the leftmost part of the image
        self.countingWindow.imageView.horizontalScrollBar().setValue(0)
        
        # Once loaded the file, we enable the Finish Count button
        self.countingWindow.finishButton.setEnabled(True)
        self.countingWindow.resetCounterButton.setEnabled(True)
    
    def resetCounter(self):
        """
        This function just resets the counter, so we
        remove only markers and keep the image. This is done
        by removing only those items with type() equal to 4,
        which means that is an ellipse
        """
        
        self.setItemCount(0)
        
        for item in self.scene.items():
            if item.type() == 4:
                self.scene.removeItem(item)
            
    
    def manageCounterMouseEvent(self, event):
        """
        This function manages the mouse events over the image:
        Left button adds a marker and increases the count.
        Right button removes a marker and decreases the count
        Left + Ctrl moves the view to the right
        Right + Ctrl moves the view to the left
        """
        
        keyboardModifier = event.modifiers()
        pressedMouseButton = event.button()
        
        # We must get the position of the scroll bar and.
        #viewShift = self.pixmapWidth/((self.pixmapWidth/self.countingWindow.imageView.width())+1)
        viewPosition = self.countingWindow.imageView.horizontalScrollBar().value()
        
        # Left mouse click management
        if pressedMouseButton == QtCore.Qt.LeftButton:
            if keyboardModifier == QtCore.Qt.NoModifier:
                # Adds a marker in the position of the click
                posx = event.pos().x()
                posy = event.pos().y()
                self.scene.addEllipse(posx, posy, 7, 7, self.markerPen, self.markerBrush)
                self.setItemCount(self.itemCount + 1)
                  
            elif keyboardModifier == QtCore.Qt.ControlModifier:
                # Moves view to the right
                self.countingWindow.imageView.horizontalScrollBar().setValue(viewPosition - self.viewShift)
        
        # Right mouse click management
        elif pressedMouseButton == QtCore.Qt.RightButton:
            if keyboardModifier == QtCore.Qt.NoModifier:
                # Removes the marker under the cursor  
                posx = event.pos().x()
                posy = event.pos().y()
                itemToDelete = self.scene.itemAt(posx,posy)
                if itemToDelete.type() == 4: # Means is an ellipse (marker)
                    self.scene.removeItem(itemToDelete)
                    self.setItemCount(self.itemCount - 1)
                  
            elif keyboardModifier == QtCore.Qt.ControlModifier:
                # Moves view to the left
                self.countingWindow.imageView.horizontalScrollBar().setValue(viewPosition + self.viewShift)    
      
    def manageCounterKeyboardEvent(self, event):
        """
        This function handles the keyboard events of the dialog
        """
        
        keyPressed = event.key()
        keyboardModifier = event.modifiers()
        # Shorcut for loading images        
        if (keyPressed == QtCore.Qt.Key_L and keyboardModifier == QtCore.Qt.ControlModifier):
            self.loadImage()
        
        # Shorcut for finishing the count    
        elif (keyPressed == QtCore.Qt.Key_F and keyboardModifier == QtCore.Qt.ControlModifier and self.countingWindow.finishButton.isEnabled() == True):
            self.finishCount()
        
            # Shorcut for resetting the count
        elif (keyPressed == QtCore.Qt.Key_R and keyboardModifier == QtCore.Qt.ControlModifier and self.countingWindow.resetCounterButton.isEnabled() == True):
            self.resetCounter()
        
    def finishCount(self):
        """
        This function ask for confirmation when the user has finished counting
        and wants to mark the image file as counted.
        It adds the suffix _cntd to the file and also inserts the number of items
        counted in the top right corner of the image.
        Additionally, it completely resets the view removing the markers and the pixmap
        from it.
        """
        
        # We get some info from the image file 
        fileInfo = QtCore.QFileInfo(self.filename)
        suffix = fileInfo.completeSuffix()
        basename = fileInfo.baseName()
        newFilename = basename + '_ctnd.' + suffix
        filePath = fileInfo.absolutePath()
        destinationFile = filePath + '/' + newFilename
            
        # Firstly we ask for confirmation
        confirmation = QtGui.QMessageBox(None)
        confirmation.setWindowTitle(self.tr("Confirmation Dialog"))
        confirmation.setText(QtCore.QString(self.tr(u"<center>This action will:<ol><li>Remove all markers</li><li>Unload the image</li><li>Insert the number of counted items in the image</li><li>Create file %1</li></ol><br><b>Do you want to proceed with the above?</b><center>")).arg(newFilename))
        btn1 = confirmation.addButton(self.tr(u"Accept"), QtGui.QMessageBox.YesRole)
        
        if confirmation.exec_() == 0: # User agrees
           
            # We will load again the image file, because we scaled it
            # when first loaded
            pixmap = QtGui.QPixmap(self.filename)
            
            # We create a painter on the pixmap to be able to
            # draw on it
            painter = QtGui.QPainter(pixmap)
            painter.setPen(self.textPen)
            font = QtGui.QFont("Arial", 30)
            painter.setFont(font)
            pixmapWidth = pixmap.width()
            
            countText = QtCore.QString(self.tr(u"Count: %1")).arg(self.getItemCount())
            fm = QtGui.QFontMetrics(font)
            countTextHeight = fm.boundingRect(countText).height()
                       
            painter.drawText(QtCore.QPoint(pixmapWidth / 2, countTextHeight + 5), countText )
            # End the painter is mandatory
            painter.end()
            
            # Now saves the filename appending the count marker
            pixmap.save(destinationFile)
            
            # Removing items and pixmap froom scene
            for item in self.scene.items():
                self.scene.removeItem(item)
            
            # Finally we set the count to zero and disable the finish count button
            # as well as the reset count button
            self.setItemCount(0)
            self.countingWindow.finishButton.setEnabled(False)
            self.countingWindow.resetCounterButton.setEnabled(False)
            
            
            
    def setItemCount(self, count):
        """
        Sets the count to a integer value and displays its value
        """
        self.itemCount = count
        text = QtCore.QString(self.tr(u"Counted items: %1")).arg(count)
        self.countingWindow.counterLabel.setText(text)
          
    def getItemCount(self):
        """
        Returns the number of items counted
        """
        return self.itemCount
      
    def about(self):
        """
        Shows an about dialog with license and some simple help
        """
        dialog = QtGui.QDialog()
        aboutDialog = AboutDialog()
        aboutDialog.setupUi(dialog)
        dialog.exec_()
      
    def exitCounter(self):
        """
        Function to exit the dialog, asking for confirmation
        """
        confirmation = QtGui.QMessageBox(None)
        confirmation.setWindowTitle(self.tr("Exiting TheEggCounter"))
        confirmation.setText(self.tr("""<center>Are you sure you want to exit?</b>
            </center>"""))
        btn1 = confirmation.addButton(self.tr("Accept"), QtGui.QMessageBox.YesRole)
        btn2 = confirmation.addButton(self.tr("No, thanks"), QtGui.QMessageBox.YesRole)
        if confirmation.exec_() == 0:
          self.close()
Example #4
0
class ItemCounter(QtWidgets.QMainWindow):
    """
    This class provides a Main Window with a graphic view 
    where an image with items to be counted is placed and
    counting such items can be performed using the mouse
    """
    
    # Defines the color for marker and its outline
    markerPen = QtGui.QPen(QtGui.QColor(QtCore.Qt.black))
    markerBrush = QtGui.QBrush(QtGui.QColor(QtCore.Qt.red))
    textPen = QtGui.QPen(QtGui.QColor(QtCore.Qt.yellow))
    
                
    def __init__(self, screenWidth = 1280, screenHeight = 1024):
      
        QtWidgets.QMainWindow.__init__(self)
        self.setGeometry(0, 0, screenWidth, screenHeight)
        self.countingWindow = CounterGUI()
        self.translateUi()
        self.countingWindow.setupUi(self)
        self.resize(screenWidth,screenHeight)
        self.scene = QtWidgets.QGraphicsScene()
        self.countingWindow.imageView.setScene(self.scene)
        
        # Reimplementation of keypress event management
        self.keyPressEvent = self.manageCounterKeyboardEvent
        
        self.setItemCount(0)
        self.countingWindow.finishButton.setEnabled(False)
        self.countingWindow.resetCounterButton.setEnabled(False)
        self.connectSignals()
        
        
    def translateUi(self):
        """
        This function localizates GUI and related messages
        """
        # We get the running dir and the locale
        self.running_dir = os.path.dirname(__file__)
        locale = QtCore.QLocale().name()
        
        # Generation of paths for localization files, must be inside
        # i18n folder and their name should be like:
        # theeggcounter_[LOCALE].qm
        # counter_gui_[LOCALE].qm
        # aboutdialog_[LOCALE].qm
        # WHere [LOCALE] is the name of the locale following BCP47 guidelines
        # You can create your own translations by creating new files with 
        # QtLinguist.
        
        mainTranslatorPath = os.path.join(\
            self.running_dir, 'i18n', 'theeggcounter_{0}.qm'.format(locale))
        UiTranslatorPath = os.path.join(\
            self.running_dir, 'i18n', 'counter_gui_{0}.qm'.format(locale))
        aboutTranslatorPath = os.path.join(\
            self.running_dir, 'i18n', 'aboutdialog_{0}.qm'.format(locale))
        
        
        # Localization
        self.mainTranslator = QtCore.QTranslator()
        self.UiTranslator = QtCore.QTranslator()
        self.aboutTranslator = QtCore.QTranslator()
       
        self.mainTranslator.load(mainTranslatorPath)
        self.UiTranslator.load(UiTranslatorPath)
        self.aboutTranslator.load(aboutTranslatorPath)
                
        QtCore.QCoreApplication.installTranslator(self.mainTranslator)
        QtCore.QCoreApplication.installTranslator(self.UiTranslator)
        QtCore.QCoreApplication.installTranslator(self.aboutTranslator)
        
    def connectSignals(self):
        """
        Connects GUI buttons as well as menu actions with their event handlers
        """
        self.countingWindow.loadImageButton.clicked.connect(self.loadImage)
        self.countingWindow.resetCounterButton.clicked.connect(self.resetCounter)
        self.countingWindow.finishButton.clicked.connect(self.finishCount)
        self.countingWindow.actionExit.triggered.connect(self.exitCounter)
        self.countingWindow.actionAbout.triggered.connect(self.about)
        
        
    def loadImage(self):
        """
        Loads an image from disk and displays it
        """
        filenameDialog = QtWidgets.QFileDialog.getOpenFileName(None,
                    self.tr("Select an image to load"),
                    options=QtWidgets.QFileDialog.DontUseNativeDialog)
        
        self.filename = filenameDialog[0]

        pixmap = QtGui.QPixmap(self.filename)
        pixmap = pixmap.scaledToHeight(\
          self.countingWindow.imageView.height(),QtCore.Qt.SmoothTransformation)
        self.pixmap = QtWidgets.QGraphicsPixmapItem(pixmap)
        self.scene.addItem(self.pixmap)
        #self.pixmap = QtWidgets.QGraphicsPixmapItem(pixmap, scene = self.scene)
        
        # Reimplementation of the mousePressEvent of the pixmap
        self.pixmap.mousePressEvent = self.manageCounterMouseEvent
                
        # We calculate the width of the pixmap and subsequently, the step
        # for scrolling the view. The view shift is calculated so visibility
        # of all the markers is guaranteed while scrolling the view
        
        self.pixmapWidth = pixmap.width()
        self.viewShift = self.pixmapWidth / ((self.pixmapWidth\
          / self.countingWindow.imageView.width()) + 1) 
        
        # Sets the scrollbar to the leftmost part of the image
        self.countingWindow.imageView.horizontalScrollBar().setValue(0)
        
        # Once loaded the file, we enable the Finish Count button
        self.countingWindow.finishButton.setEnabled(True)
        self.countingWindow.resetCounterButton.setEnabled(True)
    
    def resetCounter(self):
        """
        This function just resets the counter, so we
        remove only markers and keep the image. This is done
        by removing only those items with type() equal to 4,
        which means that is an ellipse
        """
        
        self.setItemCount(0)
        
        for item in self.scene.items():
            if item.type() == 4:
                self.scene.removeItem(item)
            
    
    def manageCounterMouseEvent(self, event):
        """
        This function manages the mouse events over the image:
        Left button adds a marker and increases the count.
        Right button removes a marker and decreases the count
        Left + Ctrl moves the view to the right
        Right + Ctrl moves the view to the left
        """
        
        keyboardModifier = event.modifiers()
        pressedMouseButton = event.button()
        
        # We must get the position of the scroll bar and.
        #viewShift = self.pixmapWidth/((self.pixmapWidth/self.countingWindow.imageView.width())+1)
        viewPosition = self.countingWindow.imageView.horizontalScrollBar().value()
        
        # Left mouse click management
        if pressedMouseButton == QtCore.Qt.LeftButton:
            if keyboardModifier == QtCore.Qt.NoModifier:
                # Adds a marker in the position of the click
                # taking into account the diameter of the marker
                posx = event.pos().x()
                posy = event.pos().y()
                self.scene.addEllipse(posx-3.5, posy-3.5, 7, 7, self.markerPen, self.markerBrush)
                self.setItemCount(self.itemCount + 1)
                  
            elif keyboardModifier == QtCore.Qt.ControlModifier:
                # Moves view to the right
                self.countingWindow.imageView.horizontalScrollBar().setValue(viewPosition - self.viewShift)
        
        # Right mouse click management
        elif pressedMouseButton == QtCore.Qt.RightButton:
            if keyboardModifier == QtCore.Qt.NoModifier:
                # Removes the marker under the cursor  
                posx = event.pos().x()
                posy = event.pos().y()
                itemToDelete = self.scene.itemAt(posx,posy,QtGui.QTransform())
                if itemToDelete.type() == 4: # Means is an ellipse (marker)
                    self.scene.removeItem(itemToDelete)
                    self.setItemCount(self.itemCount - 1)
                  
            elif keyboardModifier == QtCore.Qt.ControlModifier:
                # Moves view to the left
                self.countingWindow.imageView.horizontalScrollBar().setValue(viewPosition + self.viewShift)    
      
    def manageCounterKeyboardEvent(self, event):
        """
        This function handles the keyboard events of the dialog
        """
        
        keyPressed = event.key()
        keyboardModifier = event.modifiers()
        # Shorcut for loading images        
        if (keyPressed == QtCore.Qt.Key_L and keyboardModifier == QtCore.Qt.ControlModifier):
            self.loadImage()
        
        # Shorcut for finishing the count    
        elif (keyPressed == QtCore.Qt.Key_F and keyboardModifier == QtCore.Qt.ControlModifier and self.countingWindow.finishButton.isEnabled() == True):
            self.finishCount()
        
            # Shorcut for resetting the count
        elif (keyPressed == QtCore.Qt.Key_R and keyboardModifier == QtCore.Qt.ControlModifier and self.countingWindow.resetCounterButton.isEnabled() == True):
            self.resetCounter()
        
    def finishCount(self):
        """
        This function ask for confirmation when the user has finished counting
        and wants to mark the image file as counted.
        It adds the suffix _cntd to the file and also inserts the number of items
        counted in the top right corner of the image.
        Additionally, it completely resets the view removing the markers and the pixmap
        from it.
        """
        
        # We get some info from the image file 
        fileInfo = QtCore.QFileInfo(self.filename)
        suffix = fileInfo.completeSuffix()
        basename = fileInfo.baseName()
        newFilename = basename + '_ctnd.' + suffix
        filePath = fileInfo.absolutePath()
        destinationFile = filePath + '/' + newFilename
            
        # Firstly we ask for confirmation
        confirmation = QtWidgets.QMessageBox(None)
        confirmation.setWindowTitle(self.tr("Confirmation Dialog"))
        confirmation.setText(self.tr(u"<center>This action will:<ol><li>Remove all markers</li><li>Unload the image</li><li>Insert the number of counted items in the image</li><li>Create file %s</li></ol><br><b>Do you want to proceed with the above?</b><center>") %newFilename)
        btn1 = confirmation.addButton(self.tr(u"Accept"), QtWidgets.QMessageBox.YesRole)
        
        if confirmation.exec_() == 0: # User agrees
           
            # We will load again the image file, because we scaled it
            # when first loaded
            pixmap = QtGui.QPixmap(self.filename)
            
            # We create a painter on the pixmap to be able to
            # draw on it
            painter = QtGui.QPainter(pixmap)
            painter.setPen(self.textPen)
            font = QtGui.QFont("Arial", 30)
            painter.setFont(font)
            pixmapWidth = pixmap.width()
            
            countText = self.tr(u"Count: %s") %self.getItemCount()
            fm = QtGui.QFontMetrics(font)
            countTextHeight = fm.boundingRect(countText).height()
                       
            painter.drawText(QtCore.QPoint(pixmapWidth / 2, countTextHeight + 5), countText )
            # End the painter is mandatory
            painter.end()
            
            # Now saves the filename appending the count marker
            pixmap.save(destinationFile)
            
            # Removing items and pixmap froom scene
            for item in self.scene.items():
                self.scene.removeItem(item)
            
            # Finally we set the count to zero and disable the finish count button
            # as well as the reset count button
            self.setItemCount(0)
            self.countingWindow.finishButton.setEnabled(False)
            self.countingWindow.resetCounterButton.setEnabled(False)
            
            
            
    def setItemCount(self, count):
        """
        Sets the count to a integer value and displays its value
        """
        self.itemCount = count
        text = self.tr(u"Counted items: %s") %count
        self.countingWindow.counterLabel.setText(text)
          
    def getItemCount(self):
        """
        Returns the number of items counted
        """
        return self.itemCount
      
    def about(self):
        """
        Shows an about dialog with license and some simple help
        """
        dialog = QtWidgets.QDialog()
        aboutDialog = AboutDialog()
        aboutDialog.setupUi(dialog)
        dialog.exec_()
      
    def exitCounter(self):
        """
        Function to exit the dialog, asking for confirmation
        """
        confirmation = QtWidgets.QMessageBox(None)
        confirmation.setWindowTitle(self.tr("Exiting TheEggCounter"))
        confirmation.setText(self.tr("""<center>Are you sure you want to exit?</b>
            </center>"""))
        btn1 = confirmation.addButton(self.tr("Accept"), QtWidgets.QMessageBox.YesRole)
        btn2 = confirmation.addButton(self.tr("No, thanks"), QtWidgets.QMessageBox.YesRole)
        if confirmation.exec_() == 0:
          self.close()