class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        Ui_MainWindow.__init__(self, parent)
        self.setupUi(self)

        self.progressBar = QProgressBar()
        self.progressBar.setMaximumWidth(100)
        self.statusbar.addPermanentWidget(self.progressBar)

        self.initData()

        self.connects()

    def connects(self):
        self.checkThread.checkComplete.connect(self.updateView)
        self.checkThread.versionChecked.connect(self.progressCheck)

    #        self.actionQuit.triggered.connect(self.close)

    def initData(self):
        WowPath = os.path.normpath("D:\World of Warcraft")
        WowPath = os.path.join(WowPath, "Interface", "AddOns")

        self.addons = getAddOnList(WowPath)

        self.progressBar.setRange(0, len(self.addons))
        self.progressBar.setValue(0)
        self.progressBar.show()

        self.a = 0

        self.checkThread = QCheckThread(self.addons)
        self.checkThread.start()

        self.statusbar.showMessage("Checking for update")

    @Slot(list)
    def updateView(self, latestVersions):
        self.statusbar.showMessage("Checking complete", 30000)
        self.tableViewAddOn.setModel(AddOnModel(self.addons, latestVersions))
        self.tableViewAddOn.resizeColumnsToContents()
        self.progressBar.hide()
        self.checkThread.quit()

    @Slot()
    def progressCheck(self):
        self.progressBar.setValue(self.progressBar.value() + 1)

    @Slot()
    def closeEvent(self, *args, **kwargs):
        self.checkThread.quit()
        return QMainWindow.closeEvent(self, *args, **kwargs)
Beispiel #2
0
 def showProgressbar(self):
     if self.progressText:
         if not self.pb_widget:
             self.pb_widget = QDialog(self.parent())
             self.pb_widget.setWindowFlags(Qt.SplashScreen)
             self.pb_widget.setModal(True)
         hl = QHBoxLayout()
         pb = QProgressBar()
         pb.setRange(0, 0)
         hl.addWidget(pb)
         hl.addWidget(QLabel(self.progressText))
         self.pb_widget.setLayout(hl)
         self.pb_widget.show()
Beispiel #3
0
    def showProgressbar(self):
        if self.progressText:

            # generate widget if not given in init
            if not self.pb_widget:
                self.pb_widget = QDialog(self.parent())
                self.pb_widget.setWindowFlags(Qt.SplashScreen)
                self.pb_widget.setModal(True)

            # add button
            delete_button = QPushButton('X')
            delete_button.clicked.connect(self.exit)
            hl = QHBoxLayout()
            pb = QProgressBar()
            pb.setRange(0, 0)
            hl.addWidget(pb)
            hl.addWidget(QLabel(self.progressText))
            if self.abortButton:
                hl.addWidget(delete_button)
            self.pb_widget.setLayout(hl)
            self.pb_widget.show()
class ProgressBarService(QObject):
    """
    This service is initialized with a status bar upon which it sets
    a progress bar. Consumers of the service can then show/hide
    the progress bar and set values.

    The __new__ method is overridden to make this class a singleton.
    Every time it is instantiated somewhere in code, the same instance will be
    returned. In this way, it can serve like a static class.

    @param statusbar: The status bar on which to display progress.
    @type statusbar: QStatusBar (I think)

    @since: 2010-03-02
    """

    __author__ = "Moritz Wade"
    __contact__ = "*****@*****.**"
    __copyright__ = "Zuse Institute Berlin 2010"

    _instance = None

    def __new__(cls, *args, **kwargs): # making this a Singleton, always returns the same instance
        if not cls._instance:
            cls._instance = super(ProgressBarService, cls).__new__(cls, *args, **kwargs)
        return cls._instance
    
    def __init__(self, parent=None, statusBarService = None):
        """
        Creates a QProgressBar and adds it to the given status bar (for
        threads that can provide accurate progress information).

        Note: The status bar can either be a QStatusBar or the StatusBarService. In the default
        BioPARKIN use, it is the StatusBarService instance.

        @todo: A throbber is created and also added to the status bar (for
        threads that can only provide start/stop information).
        """
#        super(ProgressBarService, self).__init__(parent)   # done in __new__

        if statusBarService is not None:
            self.statusBarService = statusBarService
            #self.progressBar = QProgressBar(self.statusBarService) # used for showing progress
            self.progressBar = QProgressBar(None) # used for showing progress
            self.progressBarMutex = QMutex()
            self.progressBar.hide()
            self.statusBarService.addPermanentWidget(self.progressBar)
            self.progressRunning = False
    
    
            self.throbber = QLabel()
            self.throbberRunning = False
            self.throbberMutex = QMutex()
            self.statusBarService.addPermanentWidget(self.throbber)
            self.throbber.show()
            self.throbber.hide()

            throbberImage = QMovie(":/images/Spinning_wheel_throbber.gif", parent=self.throbber)
            throbberImage.setScaledSize(QSize(24, 24))
            throbberImage.setCacheMode(QMovie.CacheAll)
            throbberImage.start()
            self.throbber.setMovie(throbberImage)
            self.throbber.setFixedSize(24,24)


#    def __call__(self):
#        """
#        Quick'n'dirty way to make a Singleton out of this class.
#        """
#        return self

#    def setStatusBar(self, statusbar):
#        """
#        Sets the internal status bar (or StatusBarService)
#        """
#        self.statusbar = statusbar
        
    def getStatusBar(self):
        """
        Gets the internal status bar (or StatusBarService)
        """
        return self.statusBarService
    
    def connect_to_thread(self, thread):
        """
        Connects standard BioParkinThreadBase SIGNALs to update methods.

        @param thread: Thread whose Signals to handle
        @type thread: BioParkinThreadBase
        """
        if thread is not None:
            self.thread = thread
            #thread.finished.connect(self.threadFinished)
            #print "in connect_to_thread"
            self.thread.startWithoutProgressSignal.connect(self.start_throbber)
            self.thread.startWithProgressSignal.connect(self.start_progress)
            self.thread.finishedSignal.connect(self.finish)
            self.thread.progressMinimumSignal.connect(self.setProgressBarMinimum)
            self.thread.progressMaximumSignal.connect(self.setProgressBarMaximum)
            self.thread.progressValueSignal.connect(self.setProgressBarValue)
            self.thread.progressTextSignal.connect(self.showMessage)
    
    #  def threadFinished(self, bool):
    #    self.hide("Action finished.")

    def setProgressBarMinimum(self, min):
        """
        Uses a QMutexLocker to set the minimum value for the progress bar.
        """
        with QMutexLocker(self.progressBarMutex):
            self.progressBar.setMinimum(min)

    def setProgressBarMaximum(self, max):
        """
        Uses a QMutexLocker to set the maximum value for the progress bar.
        """
        with QMutexLocker(self.progressBarMutex):
            self.progressBar.setMaximum(max)

    def setProgressBarValue(self, value):
        """
        Uses a QMutexLocker to set the minimum value for the progress bar.

        This also implicitely "starts" the progress, e.g. show the ProgressBar.
        """
        self.progressRunning = True
        with QMutexLocker(self.progressBarMutex):
            self.progressBar.setValue(value)
            self.progressBar.show()
    
    def update(self, value, min=None, max=None, text = None):
        """
        Updates the progress bar with the given information.

        @param value: current value
        @type value: int

        @param min: Value that represents 0%
        @type min: int

        @param max: Value that represents 100%
        @type max: int

        @param text: Text to display on status bar
        @type text: str
        """
        #
        self.progressRunning = True
        #QApplication.processEvents()
        with QMutexLocker(self.progressBarMutex):
            if min and max:
                self.progressBar.setRange(min, max)
            self.progressBar.setValue(value)
            self.progressBar.show()

        if text is not None:
            self.statusBarService.showMessage(text)
    
    
#    @Slot("QString")
    def finish(self, text = None):
        """
        This is a slot. It's called when a thread emits its "finished" Signal.

        The given text is posted to the status bar.

        @param text: Text for status bar
        @type text: str
        """
        #print "in finish()"
        #logging.info("Finishing Progress Service")
        
        if self.progressRunning:
            with QMutexLocker(self.progressBarMutex):
                self.progressBar.hide()
        if self.throbberRunning:
            with QMutexLocker(self.throbberMutex):
                self.throbber.hide()
        
        
        if text is None:
            self.statusBarService.showMessage("Finished", 1000)
        else:
            self.statusBarService.showMessage(text, 3000) # show finish message for 3 seconds
        
        
        self.thread = None  # release reference to thread
    
#    @Slot("QString")
    def start_throbber(self, text = None):
        """
        This is a slot. It starts (the progress-state-less) throbber
        animation.

        The given text is posted to the status bar.

        @param text: Text for status bar
        @type text: str
        """
        #print "Starting progress throbber...."
        #logging.info("Starting progress throbber....")
        with QMutexLocker(self.throbberMutex):
            self.throbber.show()
            self.throbberRunning = True

        if text is None:
            self.statusBarService.showMessage("Computing...")
        else:
            self.statusBarService.showMessage(text)
    
    
#    @Slot("QString")
    def start_progress(self, text = None):
        """
        This is a slot. It starts the progress animation.

        The given text is posted to the status bar.

        @param text: Text for status bar
        @type text: str
        """
        self.progressRunning = True
        with QMutexLocker(self.progressBarMutex):
            self.progressBar.show()
        
        if text is None:
            self.statusBarService.showMessage("Computing...", 1000)
        else:
            self.statusBarService.showMessage(text)

    def showMessage(self, text):
        if self.statusBarService:
            self.statusBarService.showMessage(text)
Beispiel #5
0
class ProgressDialog ( MProgressDialog, Window ):
    """ A simple progress dialog window which allows itself to be updated

        FIXME: buttons are not set up correctly yet
    """

    #-- Facet Definitions ------------------------------------------------------

    progress_bar    = Instance( QProgressBar )
    title           = Unicode
    message         = Unicode
    min             = Int
    max             = Int
    margin          = Int( 5 )
    can_cancel      = Bool( False )
    show_time       = Bool( False )
    show_percent    = Bool( False )
    _user_cancelled = Bool( False )
    dialog_size     = Instance( QRect )

    # Label for the 'cancel' button
    cancel_button_label = Unicode( 'Cancel' )

    #-- Public Methods ---------------------------------------------------------

    def open ( self ):
        super( ProgressDialog, self ).open()
        self._start_time = time.time()


    def close ( self ):
        self.progress_bar.destroy()
        self.progress_bar = None

        super( ProgressDialog, self ).close()


    def update ( self, value ):
        """
        Updates the progress bar to the desired value. If the value is >=
        the maximum and the progress bar is not contained in another panel
        the parent window will be closed

        """

        if self.progress_bar is None:
            return ( None, None )

        self.progress_bar.setValue( value )

        percent = (float( value ) - self.min) / (self.max - self.min)

        if self.show_time and (percent != 0):
            current_time = time.time()
            elapsed      = current_time - self._start_time
            estimated    = elapsed / percent
            remaining    = estimated - elapsed

            self._set_time_label( elapsed,   self._elapsed_control )
            self._set_time_label( estimated, self._estimated_control )
            self._set_time_label( remaining, self._remaining_control )
            self._message_control.setText( self.message )

        if self.show_percent:
            self._percent_control = "%3f" % ((percent * 100) % 1)

        if (value >= self.max) or self._user_cancelled:
            self.close()

        return ( not self._user_cancelled, False )


    def reject ( self, event ):
        self._user_cancelled = True
        self.close()


    def _set_time_label ( self, value, control ):
        hours   = value / 3600
        minutes = (value % 3600) / 60
        seconds = value % 60
        label   = "%1u:%02u:%02u" % ( hours, minutes, seconds )

        control.setText( control.text()[:-7] + label )


    def _create_buttons ( self, dialog, layout ):
        """ Creates the buttons.
        """
        # Create the button:
        buttons = QDialogButtonBox()

        if self.can_cancel:
            buttons.addButton( self.cancel_button_label,
                               QDialogButtonBox.RejectRole )

        buttons.addButton( QDialogButtonBox.Ok )

        # TODO: hookup the buttons to our methods, this may involve subclassing
        # from QDialog

        if self.can_cancel:
            buttons.connect( buttons, SIGNAL( 'rejected()' ), dialog,
                             SLOT( 'reject() ' ) )
        buttons.connect( buttons, SIGNAL( 'accepted()' ), dialog,
                         SLOT( 'accept()' ) )

        layout.addWidget( buttons )


    def _create_label ( self, dialog, layout, text ):
        dummy = QLabel( text, dialog )
        dummy.setAlignment( Qt.AlignTop | Qt.AlignLeft )

        label = QLabel( "unknown", dialog )
        label.setAlignment( Qt.AlignTop | Qt.AlignLeft | Qt.AlignRight )

        sub_layout = QHBoxLayout()

        sub_layout.addWidget( dummy )
        sub_layout.addWidget( label )

        layout.addLayout( sub_layout )

        return label


    def _create_gauge ( self, dialog, layout ):
        self.progress_bar = QProgressBar( dialog )
        self.progress_bar.setRange( self.min, self.max )
        layout.addWidget( self.progress_bar )


    def _create_message ( self, dialog, layout ):
        label = QLabel( self.message, dialog )
        label.setAlignment( Qt.AlignTop | Qt.AlignLeft )
        layout.addWidget( label )
        self._message_control = label


    def _create_percent ( self, dialog, layout ):
        #not an option with the QT progress bar
        return


    def _create_timer ( self, dialog, layout ):
        if not self.show_time:
            return

        self._elapsed_control   = self._create_label( dialog, layout,
                                                      "Elapsed time : " )
        self._estimated_control = self._create_label( dialog, layout,
                                                      "Estimated time : " )
        self._remaining_control = self._create_label( dialog, layout,
                                                      "Remaining time : " )


    def _create_control ( self, parent ):
        control = QDialog( parent )
        control.setWindowTitle( self.title )

        return control


    def _create ( self ):
        super( ProgressDialog, self )._create()

        contents = self._create_contents( self.control )


    def _create_contents ( self, parent ):
        dialog = parent
        layout = QVBoxLayout( dialog )

        # The 'guts' of the dialog:
        self._create_message( dialog, layout )
        self._create_gauge(   dialog, layout )
        self._create_percent( dialog, layout )
        self._create_timer(   dialog, layout )
        self._create_buttons( dialog, layout )

        parent.setLayout( layout )

#-- EOF ------------------------------------------------------------------------
Beispiel #6
0
class CompareSequences(QMainWindow):
    def __init__(self):
        super(CompareSequences, self).__init__()

        self.setWindowTitle('Compare Sequences')
        self.setFixedHeight(125)

        self._ledit1 = QLineEdit()
        self._btn_pick_1 = QPushButton('...')
        self._ledit2 = QLineEdit()
        self._btn_pick_2 = QPushButton('...')
        self._btn_compare = QPushButton('Compare')
        self._progress_bar = QProgressBar(self.statusBar())

        self._setup_ui()
        self._set_connections()

    def _compare(self):
        self._toggle_ui()

        src_one = self._ledit1.text()
        src_two = self._ledit2.text()

        # TODO: put in some checks for valid sequences

        if not (src_one and src_two):
            msg = 'Please pick proper sequences.'
            print msg
            nuke.message(msg)
        else:
            read1 = nuke.createNode('Read', inpanel=False)
            read1.knob('file').fromUserText(src_one)

            read2 = nuke.createNode('Read', inpanel=False)
            read2.knob('file').fromUserText(src_two)
            read2.setXYpos(read1.xpos() + 100, read1.ypos())

            if not (read1.width() == read2.width() and read1.height() == read2.height()):
                msg = 'Sequences are not the same resolution.'
                print msg
                nuke.message(msg)
            else:
                # TODO: check for same resolution

                m = nuke.createNode('Merge2', inpanel=False)
                m.knob('operation').setValue(6)
                m.setXYpos(read1.xpos(), read2.ypos() + 100)
                m.setInput(0, read1)
                m.setInput(1, read2)

                c = nuke.createNode('CurveTool', inpanel=False)
                c.knob('operation').setValue(3)
                c.knob('ROI').fromDict(
                    {
                        'x': 0,
                        'y': 0,
                        'r': read1.width(),
                        't': read1.height()
                    }
                )

                v = nuke.createNode('Viewer')

                check = False
                frame = None

                first = read1.knob('first').value()
                last = read1.knob('last').value()

                self._progress_bar.setRange(first, last)
                for i in range(first, last + 1):
                    self._progress_bar.setValue(i)
                    nuke.execute(c, i, i)
                    data = c.knob('maxlumapixvalue').animations()
                    check = False
                    for curve in data:
                        if not curve.constant():
                            check = True
                            frame = i
                            break
                    if check:
                        break

                if not check:
                    msg = 'There is no difference.'
                else:
                    msg = 'There is a difference at frame %d.' % frame

                nuke.message(msg)

                self._progress_bar.reset()

        self._toggle_ui()

    def _pick_sequence(self):
        btn = self.sender()

        le_btn_pair = {
            self._btn_pick_1: self._ledit1,
            self._btn_pick_2: self._ledit2
        }

        clip_path = nuke.getClipname('Pick Sequence to compare')

        le_btn_pair[btn].setText(clip_path)

    def _set_connections(self):
        self._btn_pick_1.released.connect(self._pick_sequence)
        self._btn_pick_2.released.connect(self._pick_sequence)
        self._btn_compare.released.connect(self._compare)

    def _setup_ui(self):
        self._btn_pick_1.setFixedWidth(25)
        self._btn_pick_1.setToolTip('Pick first sequence.')
        self._btn_pick_2.setFixedWidth(25)
        self._btn_pick_2.setToolTip('Pick second sequence.')
        self._btn_compare.setToolTip('Compare sequences.')
        self._progress_bar.setFixedHeight(10)

        lyt_seq1 = QHBoxLayout()
        lyt_seq1.addWidget(self._ledit1)
        lyt_seq1.addWidget(self._btn_pick_1)

        lyt_seq2 = QHBoxLayout()
        lyt_seq2.addWidget(self._ledit2)
        lyt_seq2.addWidget(self._btn_pick_2)

        lyt_main = QVBoxLayout()
        lyt_main.addLayout(lyt_seq1)
        lyt_main.addLayout(lyt_seq2)
        lyt_main.addWidget(self._btn_compare)

        main_widget = QWidget()
        main_widget.setLayout(lyt_main)

        self.setCentralWidget(main_widget)

    def _toggle_ui(self):
        self._ledit1.setEnabled(not self._ledit1.isEnabled())
        self._ledit2.setEnabled(not self._ledit2.isEnabled())
        self._btn_pick_1.setEnabled(not self._btn_pick_1.isEnabled())
        self._btn_pick_2.setEnabled(not self._btn_pick_2.isEnabled())
        self._btn_compare.setEnabled(not self._btn_compare.isEnabled())
Beispiel #7
0
class Dialog(QWidget):

    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)
        self.setupUI()
        self.setupConnection()
        self.threadPool = []
        self.totalUids = 0
        self.finishedThreadNum = 0
        self.realThreadNum = 0
        self.excel = Excel()
        #self.initSearchDb()

    def setupUI(self):

        self.pushButton = QPushButton(u"Search", self)
        #self.testButton = QPushButton(u"Test", self)
        self.lineEdit = QLineEdit(self)
        self.textEdit = QTextEdit(self)
        self.comboBox = QComboBox(self)
        self.label = QLabel(u"DB:", self)
        self.progressBar = QProgressBar(self)
        self.progressBar.setRange(0,1)
        
        self.textEdit.setReadOnly(True)

        self.layout = QVBoxLayout()
        self.topLayout = QHBoxLayout()
        
        self.topLayout.addWidget(self.label)
        self.topLayout.addWidget(self.comboBox)
        self.topLayout.addWidget(self.lineEdit)
        self.topLayout.addWidget(self.pushButton)
        #self.topLayout.addWidget(self.testButton)

        #self.testButton.clicked.connect(self.onTestButtonClicked)

        self.layout.addLayout(self.topLayout)
        self.layout.addWidget(self.textEdit)
        self.layout.addWidget(self.progressBar)

        self.setLayout(self.layout)

        self.resize(600, 700)
        self.setWindowTitle(u"Search Data for NCBI")

    def setupConnection(self):
        self.pushButton.clicked.connect(self.onButtonClicked)

    def onButtonClicked(self):
        if not self.lineEdit.text() or not self.comboBox.count():
            QtGui.QMessageBox.information(self, u"Warning", u"Please Set the Search Field")
            return
        # disable button
        self.pushButton.setDisabled(True)
        dbName = self.comboBox.currentText()
        fieldName = self.lineEdit.text()
        self.log("Start searching db: %s and field: %s" % (dbName, fieldName))
        # add use history to add all uids to the history server
        handle = self.entrez.esearch(db=dbName, term=fieldName, usehistory='y')
        record = self.entrez.read(handle)
        self.log("All result count %s" % record['Count'])
        self.totalUids = int(record['Count'])
        # to get onnly data less than the MAX_COUNT
        if self.totalUids > MAX_COUNT:
            ret = QtGui.QMessageBox.question(
                    self,
                    u'Warning',
                    u'result count %s is too large, will only get the %s result \
                            continue?' % (self.totalUids, MAX_COUNT),
                            QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel
                            )
            if ret == QtGui.QMessageBox.Ok:
                self.totalUids = MAX_COUNT
            else:
                return
        #handle = self.entrez.efetch(db=dbName, id=record['IdList'], rettype='gb')
        self.finishedThreadNum = 0
        WebEnv = record['WebEnv']
        QueryKey = record['QueryKey']
        global FINISHED_COUNT
        FINISHED_COUNT = 0
        self.progressBar.setValue(0)
        self.progressBar.setMaximum(self.totalUids)
        if self.totalUids / RET_MAX_SUMMARY >= MAX_THREAD:
            self.realThreadNum = MAX_THREAD
            each_count = self.totalUids/MAX_THREAD
            startIndex = 0
            for i in range(MAX_THREAD - 1):
                thread = MyThread(startIndex, each_count, dbName, fieldName, WebEnv, QueryKey)
                thread.finished.connect(self.onThreadFinished)
                thread.finishedCountChanged.connect(self.onFinishedCountChange)
                thread.start()
                self.threadPool.append(thread)
                startIndex = startIndex + each_count
            thread = MyThread(startIndex, (self.totalUids-startIndex+1), dbName, fieldName, WebEnv, QueryKey)
            thread.finished.connect(self.onThreadFinished)
            thread.finishedCountChanged.connect(self.onFinishedCountChange)
            self.threadPool.append(thread)
            thread.start()
        else:
            if self.totalUids == RET_MAX_SUMMARY:
                self.realThreadNum = 1
            else:
                self.realThreadNum = self.totalUids/RET_MAX_SUMMARY + 1
            startIndex = 0
            for i in range(self.realThreadNum):
                thread = MyThread(startIndex, RET_MAX_SUMMARY, dbName, fieldName, WebEnv, QueryKey)
                thread.finished.connect(self.onThreadFinished)
                thread.finishedCountChanged.connect(self.onFinishedCountChange)
                self.threadPool.append(thread)
                thread.start()
                startIndex = startIndex + RET_MAX_SUMMARY
        self.log("thread num: %s" % self.realThreadNum)
        self.log('reading data')
        self.filename = '%s_%s_output.xls' % (dbName, fieldName)
        self.excel.setFilename(self.filename)

    def log(self, context):
        self.textEdit.append(context)

    def initSearchDb(self):
        self.entrez = Entrez 
        self.entrez.email = email
        self.log("Connect to NCBI")
        try:
            handle = self.entrez.einfo()
        except:
            QtGui.QMessageBox.warning(self, u"Error", u"Error Connect the WebSite")
            self.close()
        record = self.entrez.read(handle)
        self.log("Get NCBI DataBases:")
        for name in record['DbList']:
            self.log('DBName:\t%s' % name)
        self.comboBox.addItems(record['DbList'])

    def onThreadFinished(self):
        self.finishedThreadNum = self.finishedThreadNum + 1
        self.log('finished thread %s ' % self.finishedThreadNum)
        if(self.finishedThreadNum == self.realThreadNum):
            global all_output
            heads = all_output[0][0].keys()
            self.excel.setHead(heads)
            for values in all_output:
                for value in values:
                    self.excel.addValues(value)
            self.excel.save()
            self.progressBar.setValue(int(self.totalUids))
            # clear all thread
            self.threadPool = []
            all_output = []
            self.excel.clearValues()
            self.pushButton.setDisabled(False)
            self.log("output to file: %s" % self.filename)

    def onFinishedCountChange(self, num):
        self.progressBar.setValue(num)

    def onTestButtonClicked(self):
        self.finishedThreadNum = 0
        self.realThreadNum = 1
        self.thread = MyThread(0, 10,"abd","123")
        self.thread.finished.connect(self.onThreadFinished)
        self.thread.startIndex()
Beispiel #8
0
class ProgressBarService(QObject):
    """
    This service is initialized with a status bar upon which it sets
    a progress bar. Consumers of the service can then show/hide
    the progress bar and set values.

    The __new__ method is overridden to make this class a singleton.
    Every time it is instantiated somewhere in code, the same instance will be
    returned. In this way, it can serve like a static class.

    @param statusbar: The status bar on which to display progress.
    @type statusbar: QStatusBar (I think)

    @since: 2010-03-02
    """

    __author__ = "Moritz Wade"
    __contact__ = "*****@*****.**"
    __copyright__ = "Zuse Institute Berlin 2010"

    _instance = None

    def __new__(cls, *args, **kwargs
                ):  # making this a Singleton, always returns the same instance
        if not cls._instance:
            cls._instance = super(ProgressBarService,
                                  cls).__new__(cls, *args, **kwargs)
        return cls._instance

    def __init__(self, parent=None, statusBarService=None):
        """
        Creates a QProgressBar and adds it to the given status bar (for
        threads that can provide accurate progress information).

        Note: The status bar can either be a QStatusBar or the StatusBarService. In the default
        BioPARKIN use, it is the StatusBarService instance.

        @todo: A throbber is created and also added to the status bar (for
        threads that can only provide start/stop information).
        """
        #        super(ProgressBarService, self).__init__(parent)   # done in __new__

        if statusBarService is not None:
            self.statusBarService = statusBarService
            self.progressBar = QProgressBar(None)  # used for showing progress
            self.progressBarMutex = QMutex()
            self.progressBar.hide()
            self.statusBarService.addPermanentWidget(self.progressBar)
            self.progressRunning = False

            self.throbber = QLabel()
            self.throbberRunning = False
            self.throbberMutex = QMutex()
            self.statusBarService.addPermanentWidget(self.throbber)
            self.throbber.show()
            self.throbber.hide()

            throbberImage = QMovie(":/images/Spinning_wheel_throbber.gif",
                                   parent=self.throbber)
            throbberImage.setScaledSize(QSize(24, 24))
            throbberImage.setCacheMode(QMovie.CacheAll)
            throbberImage.start()
            self.throbber.setMovie(throbberImage)
            self.throbber.setFixedSize(24, 24)

    def getStatusBar(self):
        """
        Gets the internal status bar (or StatusBarService)
        """
        return self.statusBarService

    def connect_to_thread(self, thread):
        """
        Connects standard BioParkinThreadBase SIGNALs to update methods.

        @param thread: Thread whose Signals to handle
        @type thread: BioParkinThreadBase
        """
        if thread is not None:
            self.thread = thread
            self.thread.startWithoutProgressSignal.connect(self.start_throbber)
            self.thread.startWithProgressSignal.connect(self.start_progress)
            self.thread.finishedSignal.connect(self.finish)
            self.thread.progressMinimumSignal.connect(
                self.setProgressBarMinimum)
            self.thread.progressMaximumSignal.connect(
                self.setProgressBarMaximum)
            self.thread.progressValueSignal.connect(self.setProgressBarValue)
            self.thread.progressTextSignal.connect(self.showMessage)

    def setProgressBarMinimum(self, min):
        """
        Uses a QMutexLocker to set the minimum value for the progress bar.
        """
        with QMutexLocker(self.progressBarMutex):
            self.progressBar.setMinimum(min)

    def setProgressBarMaximum(self, max):
        """
        Uses a QMutexLocker to set the maximum value for the progress bar.
        """
        with QMutexLocker(self.progressBarMutex):
            self.progressBar.setMaximum(max)

    def setProgressBarValue(self, value):
        """
        Uses a QMutexLocker to set the minimum value for the progress bar.

        This also implicitely "starts" the progress, e.g. show the ProgressBar.
        """
        self.progressRunning = True
        with QMutexLocker(self.progressBarMutex):
            self.progressBar.setValue(value)
            self.progressBar.show()

    def update(self, value, min=None, max=None, text=None):
        """
        Updates the progress bar with the given information.

        @param value: current value
        @type value: int

        @param min: Value that represents 0%
        @type min: int

        @param max: Value that represents 100%
        @type max: int

        @param text: Text to display on status bar
        @type text: str
        """
        #
        self.progressRunning = True
        with QMutexLocker(self.progressBarMutex):
            if min and max:
                self.progressBar.setRange(min, max)
            self.progressBar.setValue(value)
            self.progressBar.show()

        if text is not None:
            self.statusBarService.showMessage(text)

#    @Slot("QString")

    def finish(self, text=None):
        """
        This is a slot. It's called when a thread emits its "finished" Signal.

        The given text is posted to the status bar.

        @param text: Text for status bar
        @type text: str
        """
        if self.progressRunning:
            with QMutexLocker(self.progressBarMutex):
                self.progressBar.hide()
        if self.throbberRunning:
            with QMutexLocker(self.throbberMutex):
                self.throbber.hide()

        if text is None:
            self.statusBarService.showMessage("Finished", 1000)
        else:
            self.statusBarService.showMessage(
                text, 3000)  # show finish message for 3 seconds

        self.thread = None  # release reference to thread

    def start_throbber(self, text=None):
        """
        This is a slot. It starts (the progress-state-less) throbber
        animation.

        The given text is posted to the status bar.

        @param text: Text for status bar
        @type text: str
        """
        with QMutexLocker(self.throbberMutex):
            self.throbber.show()
            self.throbberRunning = True

        if text is None:
            self.statusBarService.showMessage("Computing...")
        else:
            self.statusBarService.showMessage(text)


#    @Slot("QString")

    def start_progress(self, text=None):
        """
        This is a slot. It starts the progress animation.

        The given text is posted to the status bar.

        @param text: Text for status bar
        @type text: str
        """
        self.progressRunning = True
        with QMutexLocker(self.progressBarMutex):
            self.progressBar.show()

        if text is None:
            self.statusBarService.showMessage("Computing...", 1000)
        else:
            self.statusBarService.showMessage(text)

    def showMessage(self, text):
        if self.statusBarService:
            self.statusBarService.showMessage(text)
class HighwaySimulatorGui(QMainWindow):
    def __init__(self):
        super(HighwaySimulatorGui, self).__init__()
        centralTab = QTabWidget()
        mainWidget = QWidget()
        self.resultsWidget = HighwayAnalyzeWidget()
        centralTab.addTab(mainWidget, 'Run')
        centralTab.addTab(self.resultsWidget, 'Analyze')
        self.setCentralWidget(centralTab)
        centralLayout = QVBoxLayout()
        #centralLayout.setSpacing(0)
        centralLayout.setAlignment(Qt.AlignTop)
        gridWidget = QWidget()
        gridLayout = QGridLayout()
        gridLayout.setSpacing(0)
        gridWidget.setLayout(gridLayout)
        mainWidget.setLayout(centralLayout)
        self.options = dict()
        # GENERAL
        generalGroup = QGroupBox('General Settings')
        generalGroup.setLayout(QVBoxLayout())
        generalGroup.layout().setSpacing(0)
        self.pathOption = SimpleOption('path','Output Path','/home/thomas/Dropbox/Keio/research/results/')
        generalGroup.layout().addWidget(self.pathOption)
        self.scenarioOption = SimpleComboboxOption('scenario','Scenario',1, False, 'vanet-highway-test-thomas','vanet-highway-scenario2')
        self.scenarioOption.combo.currentIndexChanged[int].connect(self.scenarioChanged)
        generalGroup.layout().addWidget(self.scenarioOption)
        self.options['time'] = SimpleSpinOption('time','Simulation Time (sec.)',1500,True)
        self.options['time'].setRange(0,3000)
        self.options['mix'] = SimpleSpinOption('mix','Percentage of cars compare to trucks (%)',80,True)
        self.options['mix'].setRange(0,100)
        self.options['gap'] = SimpleSpinOption('gap','Average Gap (m.)',5)
        self.options['gap'].setRange(1,2000)
        self.options['lane'] = SimpleSpinOption('lane','Number of Lanes',2,True)
        self.options['lane'].setRange(2,4)
        self.options['spl'] = SimpleSpinOption('spl','Speed Limit (km/h)',130,True)
        self.options['spl'].setRange(1,200)
        for widget in ('time','mix','gap','lane','spl'):
            generalGroup.layout().addWidget(self.options[widget])
        gridLayout.addWidget(generalGroup,0,0)
        # TRAFFIC
        trafficGroup = QGroupBox('Traffic Settings')
        trafficGroup.setLayout(QVBoxLayout())
        trafficGroup.layout().setSpacing(0)
        # m/s = (km/h)*1000/3600
        self.options['vel1'] = SimpleSpinOption('vel1','Average Speed (km/h)',105,True)
        self.options['vel1'].setRange(5,150)
        self.options['dis'] = SimpleComboboxOption('dis','Speed Distribution Model',3, False, 'Uniform','Exponential','Normal','Log Normal')
        self.options['spstd'] = SimpleSpinOption('spstd','Speed Distribution Variance',1.0)
        self.options['spstd'].setRange(0,50)
        self.options['flow1'] = SimpleSpinOption('flow1','Traffic Flow Mean (veh/s)',1.0)
        self.options['flow1'].setRange(0.1,50.0)
        self.options['std1'] = SimpleSpinOption('std1','Traffic Flow Variance',0.8)
        self.options['std1'].setRange(0.1,50.0)
        self.options['maxflow'] = SimpleSpinOption('maxflow','Traffic Maximum Flow (veh/s)',5)
        self.options['maxflow'].setRange(0.1,50.0)
        # Scenar 2
        self.options['avgdist'] = SimpleSpinOption('avgdist','Average Distance (m)',100)
        self.options['avgdist'].setRange(1,10000)
        self.options['avgspeed'] = SimpleSpinOption('avgspeed','Average Speed (km/h)',105)
        self.options['avgspeed'].setRange(1,10000)
        self.options['despeed'] = SimpleSpinOption('despeed','Desired Speed (km/h)',130)
        self.options['despeed'].setRange(1,10000)
        self.options['ambumaxspeed'] = SimpleSpinOption('ambumaxspeed','Ambu Max Speed (km/h)',165)
        self.options['ambumaxspeed'].setRange(1,10000)
        self.options['ambuinitspeed'] = SimpleSpinOption('ambuinitspeed','Ambu Initial Speed (km/h)',130)
        self.options['ambuinitspeed'].setRange(1,10000)
        for widget in ('vel1','dis','spstd','flow1','std1','maxflow',
                       'avgdist', 'avgspeed', 'despeed', 'ambumaxspeed', 'ambuinitspeed'):
            trafficGroup.layout().addWidget(self.options[widget])
        self.scenarioChanged(self.scenarioOption.combo.currentIndex())
        gridLayout.addWidget(trafficGroup,0,1)
        # VANET
        vanetGroup = QGroupBox('VANET Settings')
        vanetGroup.setLayout(QVBoxLayout())
        vanetGroup.layout().setSpacing(0)
#        self.options['prate'] = SimpleSpinOption('prate','Penetration Rate of VANET (%)',100,True)
#        self.options['prate'].setRange(0,100)
        self.options['prate'] = 0 # start with 0
        self.options['pw'] = SimpleSpinOption('pw','Transmission Power (dBm)',21.5)
        self.options['pw'].setRange(10,50)
        #for widget in ('prate','pw'):
        for widget in ('pw',):
            vanetGroup.layout().addWidget(self.options[widget])
        gridLayout.addWidget(vanetGroup,1,0)
        # BATCH SETTINGS
        batchGroup = QGroupBox("Batch Settings")
        batchGroup.setLayout(QVBoxLayout())
        self.gapPrateOption = SimpleSpinOption('gapPrate', 'VANET percentage rate gap', 10, integer=True)
        self.sameSimuTimesOption = SimpleSpinOption('sameSimuTimes', 'How many times the same simulation', 100, integer=True)
        batchGroup.layout().setSpacing(0)
        batchGroup.layout().addWidget(self.gapPrateOption)
        batchGroup.layout().addWidget(self.sameSimuTimesOption)
        gridLayout.addWidget(batchGroup,1,1)
        # START SIMU
        centralLayout.addWidget(gridWidget)
        self.startButton = QPushButton('START')
        self.startButton.clicked.connect(self.startSimu)
        centralLayout.addWidget(self.startButton)
        self.progressBar    = QProgressBar()
        centralLayout.addWidget(self.progressBar)
        self.shutdownWhenDone = QCheckBox('Shutdown when done')
        self.actionWhenDone = QComboBox()
        self.actionWhenDone.addItems(['When finished... do nothing', 'When finished... shutdown the computer', 'When finished... Re-run the simulations!'])
        self.actionWhenDone.setCurrentIndex(int(QSettings().value('actionWhenDone', 0)))
        centralLayout.addWidget(self.actionWhenDone)
        self.infoLabel = QLabel()
        centralLayout.addWidget(self.infoLabel)
        # LOG
        self.logText = QTextBrowser()
        self.logText.setFont(QFont('Century Gothic', 7))
        centralLayout.addWidget(self.logText)
        self.setWindowTitle('Nishimura Lab | Highway Simulation')
        #self.resize(520,len(self.options)*60+100)
        #self.resultFile = open('/home/thomas/Dropbox/Keio/research/results/summary.txt', 'a')
        #self.resultFile = os.path.join(self.pathOption.getValue(), 'summary.txt')
        self.logFile = os.path.join(self.pathOption.getValue(), 'results_'+os.uname()[1]+'.log')
    @Slot(int)
    def scenarioChanged(self, index):
        #print index
        scenar1options = ['gap', 'vel1', 'dis', 'flow1', 'std1','spstd', 'maxflow']
        scenar2options = ['avgdist', 'avgspeed', 'despeed', 'ambumaxspeed', 'ambuinitspeed']
        if index==0: # first scenario
            scenar1 = True
            scenar2 = False
        else:
            scenar1 = False
            scenar2 = True
        for option in scenar1options:
            self.options[option].setVisible(scenar1)
        for option in scenar2options:
            self.options[option].setVisible(scenar2)
    def log(self, txt):
        toLog = '%s | %s' % (datetime.now(), txt)
        with open(self.logFile, 'a') as logFile:
            logFile.write(toLog+'\n')
        self.logText.append(toLog)
    def blockUi(self):
        self.startButton.setEnabled(False)
        self.scenarioOption.setEnabled(False)
        for option in self.options:
            if option!='prate':
                self.options[option].setEnabled(False)
    def releaseUi(self):
        self.startButton.setEnabled(True)
        self.scenarioOption.setEnabled(True)
        self.startButton.setText('START')
        for option in self.options:
            if option!='prate':
                self.options[option].setEnabled(True)
    def startSimu(self):
        self.log("=== SIMULATIONS START ===")
        self.logText.clear()
        self.startTime = datetime.now()
        self.simulations = []
        #self.nextPrate = 0
        self.gapPrate  = self.gapPrateOption.getValue()
        self.sameSimuTimes = self.sameSimuTimesOption.getValue()
        #self.nextSimu   = 0
        self.blockUi()
        self.simulationsDone = 0
        #output = self.pathOption.getValue() + dateToFilename(d) + '_results.txt'
        pRate = 0
        self.simulationsTotal = 0
#        print 'sameSimuTimes: %d'%self.sameSimuTimes
#        print 'gapPrate: %d'%self.gapPrate
        while pRate <= 100:
            simu = 0
            self.options['prate'] = pRate
            while simu<self.sameSimuTimes:
                waf = WafThread(self.options, self.pathOption.getValue(), self.scenarioOption.getName())
                waf.setAutoDelete(True)
                waf.simuDone.connect(self.wafDone)
                self.simulations.append(waf)
                QThreadPool.globalInstance().start(waf)
                self.simulationsTotal += 1
                simu += 1
            pRate += self.gapPrate
        runningSimulations = 'Running %d Simulations...' % self.simulationsTotal
        self.startButton.setText(runningSimulations)
        self.log(runningSimulations)
        self.progressBar.setRange(0,self.simulationsTotal)
        self.progressBar.setValue(0)
        # 300 seconds per task average
        roughTime = self.simulationsTotal*self.resultsWidget.averageSimulationTime/QThreadPool.globalInstance().maxThreadCount()
        self.infoLabel.setText('Rough time estimation: %s' % formatTimeLeft(roughTime))
    @Slot(str)
    def wafDone(self, outputPath):
        #print 'thread done!\nReceived:'
        self.simulationsDone += 1
        simulationsLeft = self.simulationsTotal-self.simulationsDone
        with open(outputPath,'r') as out:
            r = json.loads(out.read())
            out.close()
            if 'timeToReachDest' in r['results']:
                try:
                    result = "%3.3d\t%f" % (int(r['settings']['prate']),float(r['results']['timeToReachDest']))
                except TypeError, e:
                    result = 'PYTHON ERROR: %s | File: %s' % (e, outputPath)
                    print result
                    print r
            else: