Esempio n. 1
0
class DialogComputeScores(QDialog):
    """Dialog to set the parameters to compute scores automatically.

    Example (replace `parent` by the parent widget):

    dialog = DialogComputeScores(parent)
    max_score, penalize = dialog.exec_()

    """
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle(_('Compute default scores'))
        layout = QFormLayout()
        self.setLayout(layout)
        self.score = widgets.InputScore(parent=self)
        self.penalize = QCheckBox(_('Penalize incorrect answers'), self)
        buttons = QDialogButtonBox((QDialogButtonBox.Ok
                                    | QDialogButtonBox.Cancel))
        layout.addRow(_('Maximum score'), self.score)
        layout.addRow(_('Penalizations'), self.penalize)
        layout.addRow(buttons)
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)

    def exec_(self):
        """Shows the dialog and waits until it is closed.

        Returns the tuple (max_score, penalize) or (None, None) if the
        user cancels.

        """
        success = False
        score = None
        penalize = None
        while not success:
            result = super().exec_()
            if result == QDialog.Accepted:
                if self.score.text():
                    score = self.score.value()
                    if score is not None and score > 0:
                        penalize = self.penalize.checkState() == Qt.Checked
                        success = True
                if not success:
                    QMessageBox.critical(self, _('Error'),
                                         _('Enter a valid score.'))
            else:
                score, penalize = None, None
                success = True
        return (score, penalize)
Esempio n. 2
0
    def initUI(self):
        StoryTypeLayer = FlowLayout()
        for key in WdStoryType.keys():
            widget = QCheckBox(WdStoryType[key][1] if WdStoryType[key][1] != "" else WdStoryType[key][0])
            widget.setObjectName("WdStoryType." + str(key))
            widget.setCheckState(WdStoryType[key][2])
            widget.setEnabled(widget.checkState() != 1)
            widget.setMinimumWidth(230)
            StoryTypeLayer.addWidget(widget)
            self.StoryTypeWdgList.append(widget)
        self.apply()
        hbox = QVBoxLayout()
        hbox.addLayout(StoryTypeLayer)

        btnGrp = QDialogButtonBox()
        btnClose = QPushButton("Закрыть")
        btnGrp.addButton(btnClose, QDialogButtonBox.ActionRole)
        hbox.addWidget(btnGrp)
        btnClose.clicked.connect(self.close)
        self.setLayout(hbox)
        self.setGeometry(500, 100, 500, 400)
        self.setWindowTitle("Опции")
        self.setWindowFlags(Qt.Dialog | Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
Esempio n. 3
0
class MikochikuAlarm(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.search_ch_id = "UC-hM6YJuNYVAmUWxeIr9FeA"
        self.old_video_id_list = []
        self.initUI()

    def initUI(self):

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.check_live)
        self.timer.setInterval(40000)
        self.timer.start()

        label = QLabel(self)
        label.setPixmap(QPixmap(resource_path("icon.ico")))
        label.move(60, 70)

        self.alarm_cb = QCheckBox('配信が始まったらアラームを鳴らす', self)
        self.alarm_cb.move(20, 20)
        self.alarm_cb.toggle()

        # self.loop_cb = QCheckBox('アラームをループ再生する', self)
        # self.loop_cb.move(20, 40)
        # self.loop_cb.toggle()

        self.webbrowser_cb = QCheckBox('配信が始まったら自動でブラウザを開く', self)
        self.webbrowser_cb.move(20, 40)
        self.webbrowser_cb.toggle()

        self.alarm_stop = QPushButton("待機中", self)
        # self.alarm_stop.setCheckable(True)
        # self.alarm_stop.setEnabled(False)
        self.alarm_stop.move(80, 80)
        self.alarm_stop.clicked[bool].connect(self.stop_alarm)

        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('みこ畜アラーム')

        self.show()

    def check_live(self):
        buff_video_id_set = self.get_live_video_id(self.search_ch_id)
        print("buff_video_id_set", buff_video_id_set)
        print("self.old_video_id_list", self.old_video_id_list)
        if buff_video_id_set:
            for getting_video_id in buff_video_id_set:
                if not getting_video_id == "" and not getting_video_id is None:
                    if not getting_video_id in self.old_video_id_list:
                        self.old_video_id_list.append(getting_video_id)
                        if len(self.old_video_id_list) > 30:
                            self.old_video_id_list = self.old_video_id_list[1:]
                        print("")
                        print("配信が始まりました")
                        # self.alarm_stop.setEnabled(False)
                        self.alarm_stop.click()
                        self.alarm_stop.setText("ストップ")
                        if self.webbrowser_cb.checkState():
                            webbrowser.open(
                                "https://www.youtube.com/watch?v=" +
                                getting_video_id)
                        if self.alarm_cb.checkState():
                            self.alarm_sound()

    def stop_alarm(self):
        pygame.mixer.music.stop()
        self.alarm_stop.setEnabled(True)
        self.alarm_stop.setText("待機中")

    def alarm_sound(self):
        # loop = 1
        # if self.loop_cb.checkState():
        loop_count = 5
        pygame.mixer.music.play(loop_count)
        pygame.mixer.music.play(loop_count)

    def get_live_video_id(self, search_ch_id):
        dict_str = ""
        video_id_set = set()
        try:
            session = requests.Session()
            headers = {
                'user-agent':
                'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
            }
            html = session.get("https://www.youtube.com/channel/" +
                               search_ch_id,
                               headers=headers,
                               timeout=10)
            soup = BeautifulSoup(html.text, 'html.parser')

            for scrp in soup.find_all('script'):
                if 'window["ytInitialData"]' in scrp.text:
                    dict_str = scrp.text.split(' = ', 1)[1]

            dict_str = dict_str.replace('false', 'False')
            dict_str = dict_str.replace('true', 'True')

            index = dict_str.find("\n")
            dict_str = dict_str[:index - 1]
            dics = eval(dict_str)
            for section in dics.get("contents", {}).get(
                    "twoColumnBrowseResultsRenderer",
                {}).get("tabs",
                        {})[0].get("tabRenderer",
                                   {}).get("content",
                                           {}).get("sectionListRenderer",
                                                   {}).get("contents", {}):
                for itemsection in section.get("itemSectionRenderer",
                                               {}).get("contents", {}):
                    items = {}
                    if "shelfRenderer" in itemsection:
                        for items in itemsection.get("shelfRenderer",
                                                     {}).get("content",
                                                             {}).values():
                            for item in items.get("items", {}):
                                for videoRenderer in item.values():
                                    for badge in videoRenderer.get(
                                            "badges", {}):
                                        if badge.get(
                                                "metadataBadgeRenderer",
                                            {}).get(
                                                "style", {}
                                            ) == "BADGE_STYLE_TYPE_LIVE_NOW":
                                            video_id_set.add(
                                                videoRenderer.get(
                                                    "videoId", ""))
                    elif "channelFeaturedContentRenderer" in itemsection:
                        for item in itemsection.get(
                                "channelFeaturedContentRenderer",
                            {}).get("items", {}):
                            for badge in item.get("videoRenderer",
                                                  {}).get("badges", {}):
                                if badge.get("metadataBadgeRenderer", {}).get(
                                        "style",
                                        "") == "BADGE_STYLE_TYPE_LIVE_NOW":
                                    video_id_set.add(
                                        item.get("videoRenderer",
                                                 {}).get("videoId", ""))
        except:
            return video_id_set

        return video_id_set
class Tab(QTabWidget):
    def __init__(self):
        super(Tab, self).__init__()
        self.initGUI()

    def initGUI(self):

        self.setGeometry(500, 300, 800, 650)
        self.setWindowTitle("CollegeBoard")

        self.tab1 = QWidget()
        self.tab2 = QWidget()
        self.tab3 = QWidget()
        self.tab4 = QWidget()
        self.tab5 = QWidget()

        self.addTab(self.tab1, "Personal information")
        self.addTab(self.tab2, "Choose a major")
        self.addTab(self.tab3, "Personal statement")
        self.addTab(self.tab4, "Register for a test")
        self.addTab(self.tab5, "Registration completed!")


        self.tab_1()
        self.tab_2()
        self.tab_3()
        self.tab_4()
        self.tab_5()

        self.setTabsClosable(True)
        self.tabCloseRequested.connect(self.closeTab)

        self.show()



    def closeTab(self, currentIndex):
        currentQWidget = self.widget(currentIndex)
        currentQWidget.deleteLater()
        self.removeTab(currentIndex)

    def tab_1(self):
        layout = QFormLayout()
        self.tab1.setLayout(layout)

        self.progressbar = QProgressBar(self)
        self.progressbar.setValue(0)
        layout.addRow(self.progressbar)

        self.btn1 = QPushButton('Next Page', self)
        self.btn1.clicked.connect(self.nextPage)
        self.btn1.move(650,600)

        self.txt1 = QLineEdit(self)
        self.txt1.setPlaceholderText("Cici")
        layout.addRow("First name", self.txt1)
        self.txt2 = QLineEdit(self)
        self.txt2.setPlaceholderText("Chen")
        layout.addRow("Last name", self.txt2)
        self.txt3 = QLineEdit(self)
        self.txt3.setPlaceholderText("")
        layout.addRow("Address", self.txt3)
        self.txt4 = QLineEdit(self)
        self.txt4.setPlaceholderText("")
        layout.addRow("Phone number", self.txt4)
        layout.addWidget(QLabel("Gender"))
        layout.addWidget(QCheckBox("Male"))
        layout.addWidget(QCheckBox("Female"))
        self.txt5 = QLineEdit(self)
        self.txt5.setPlaceholderText("")
        layout.addRow("Student ID", self.txt5)
        self.txt6 = QLineEdit(self)
        self.txt6.setPlaceholderText("mm/dd/yyyy")
        layout.addRow("Birthday", self.txt6)
        self.txt7 = QLineEdit(self)
        self.txt7.setPlaceholderText("Pacific American School")
        layout.addRow("High School", self.txt7)

        self.comboBox1 = QComboBox(self)
        self.comboBox1.addItem("January")
        self.comboBox1.addItem("February")
        self.comboBox1.addItem("March")
        self.comboBox1.addItem("April")
        self.comboBox1.addItem("May")
        self.comboBox1.addItem("June")
        self.comboBox1.addItem("July")
        self.comboBox1.addItem("August")
        self.comboBox1.addItem("September")
        self.comboBox1.addItem("October")
        self.comboBox1.addItem("November")
        self.comboBox1.addItem("December")
        layout.addRow("Graduation month", self.comboBox1)
        self.comboBox2 = QComboBox(self)
        self.comboBox2.addItem("2016")
        self.comboBox2.addItem("2017")
        self.comboBox2.addItem("2018")
        self.comboBox2.addItem("2019")
        self.comboBox2.addItem("2020")
        self.comboBox2.addItem("2021")
        self.comboBox2.addItem("2022")
        layout.addRow("Graduation year", self.comboBox2)

        self.btn2 = QPushButton('Change a photo', self)
        layout.addRow("", self.btn2)
        self.label1 = QLabel(self)
        layout.addRow(self.label1)
        self.label1.move(300, 60)
        self.label1.setPixmap(QPixmap('picture.jpg'))
        self.label1.resize(430, 60)



    def tab_2(self):
        layout = QFormLayout()
        self.tab2.setLayout(layout)

        self.btn1 = QPushButton('Next Page', self)
        self.btn1.clicked.connect(self.nextPage)
        self.btn1.move(650,600)

        self.progressbar = QProgressBar(self)
        self.progressbar.setValue(25)
        layout.addRow(self.progressbar)

        # -- add a checkbox
        self.check = QCheckBox('Biology', self)
        self.check.setTristate(True) # allowing tristate
        layout.addRow(self.check)
        self.check = QCheckBox('Chemistry', self)
        self.check.setTristate(True) # allowing tristate
        layout.addRow(self.check)
        self.check = QCheckBox('Computer science', self)
        self.check.setTristate(True) # allowing tristate
        layout.addRow(self.check)
        self.check = QCheckBox('Engineering', self)
        self.check.setTristate(True) # allowing tristate
        layout.addRow(self.check)
        self.check = QCheckBox('Arts & design', self)
        self.check.setTristate(True) # allowing tristate
        layout.addRow(self.check)
        self.check = QCheckBox('Literature', self)
        self.check.setTristate(True) # allowing tristate
        layout.addRow(self.check)
        self.check = QCheckBox('History', self)
        self.check.setTristate(True) # allowing tristate
        layout.addRow(self.check)
        self.check = QCheckBox('Language', self)
        self.check.setTristate(True) # allowing tristate
        layout.addRow(self.check)
        self.check = QCheckBox('Media', self)
        self.check.setTristate(True) # allowing tristate
        layout.addRow(self.check)
        self.check = QCheckBox('Philosophy', self)
        self.check.setTristate(True) # allowing tristate
        self.check.stateChanged.connect(self.dosth)
        layout.addRow(self.check)


    def dosth(self):
        state = self.check.checkState()
        if state == 0:
            self.setWindowTitle('You have deselected this major')
        elif state == 1:
            self.setWindowTitle('You are unsure of this major')
        elif state == 2:
            self.setWindowTitle('You have selected this major')


    def tab_3(self):
        layout = QFormLayout()
        self.tab3.setLayout(layout)

        self.btn1 = QPushButton('Next Page', self)
        self.btn1.clicked.connect(self.nextPage)
        self.btn1.move(650,600)

        self.progressbar = QProgressBar(self)
        self.progressbar.setValue(50)
        layout.addRow(self.progressbar)

        self.txt1 = QLineEdit('', self)
        self.txt2 = QLineEdit('', self)
        self.txt3 = QLineEdit('', self)
        self.txt4 = QLineEdit('', self)
        self.txt5 = QLineEdit('', self)

        self.dock1 = QDockWidget('Personal statement', self)
        self.dock1.move(20, 20)
        self.dock1.setWidget(self.txt1)

        self.dock1.setFloating(False)
        self.dock1.setFeatures(self.dock1.DockWidgetMovable)

        layout.addRow(self.dock1)
        layout.addRow('Please write a short statement about yourself.', self.txt1)
        layout.addRow(self.txt1)
        layout.addRow('What is your hobby?', self.txt2)
        layout.addRow(self.txt2)
        layout.addRow('What characteristics do you have that differs from others?', self.txt3)
        layout.addRow(self.txt3)
        layout.addRow('Which college do you want to go to and why?', self.txt4)
        layout.addRow(self.txt4)
        layout.addRow('Which after school activities did you attend in high school?', self.txt5)
        layout.addRow(self.txt5)



    def tab_4(self):
        layout = QFormLayout()
        self.tab4.setLayout(layout)

        self.btn1 = QPushButton('Next Page', self)
        self.btn1.clicked.connect(self.nextPage)
        self.btn1.move(650,600)

        self.progressbar = QProgressBar(self)
        self.progressbar.setValue(75)
        layout.addRow(self.progressbar)

        self.cal = QCalendarWidget(self)
        self.cal.setWindowTitle('Calendar')
        self.cal.setGridVisible(True) #one of the function
        self.cal.move(20, 100)
        self.cal.clicked[QDate].connect(self.showDate)
        self.label = QLabel(self)
        self.date = self.cal.selectedDate() #another function
        self.label.setText(self.date.toString())
        self.label.move(100, 500)
        layout.addRow(self.cal)
        layout.addRow(self.label)


        # -- add a checkbox
        self.check1 = QCheckBox('SAT w/ essay', self)
        layout.addRow(self.check1)
        self.check2 = QCheckBox('Chinese w/ listening', self)
        layout.addRow(self.check2)
        self.check3 = QCheckBox('Physics', self)
        layout.addRow(self.check3)
        self.check4 = QCheckBox('Math I', self)
        layout.addRow(self.check4)
        self.check5 = QCheckBox('Math II', self)
        layout.addRow(self.check5)
        self.check6 = QCheckBox('Biology', self)
        layout.addRow(self.check6)
        self.check7 = QCheckBox('US History', self)
        layout.addRow(self.check7)
        self.check8 = QCheckBox('Literature', self)
        layout.addRow(self.check8)
        self.check9 = QCheckBox('Spanish', self)
        layout.addRow(self.check9)
        self.check10 = QCheckBox('French', self)
        layout.addRow(self.check10)

        # add a button
        self.btn1 = QPushButton('Reset', self)
        self.btn1.setToolTip('This button resets the checkbox!')
        self.btn1.resize(250, 90)
        self.btn1.move(100, 100)
        self.btn1.clicked.connect(self.reset)
        layout.addRow(self.btn1)




    def reset(self):
        self.check1.setChecked(False)
        self.check2.setChecked(False)
        self.check3.setChecked(False)
        self.check4.setChecked(False)
        self.check5.setChecked(False)
        self.check6.setChecked(False)
        self.check7.setChecked(False)
        self.check8.setChecked(False)
        self.check9.setChecked(False)
        self.check10.setChecked(False)



    def tab_5(self):
        layout = QFormLayout()
        self.tab5.setLayout(layout)

        self.label1 = QLabel(self)
        layout.addRow("Your registration have been successfully recorded. ☑️", self.label1)

    def showDate(self, date):
        self.label.setText(date.toString())

    def nextPage(self):
        self.setCurrentIndex(self.currentIndex() + 1)
Esempio n. 5
0
class Dice_Roller(QWidget):
    '''
    widget for dice rolls
    '''
    def __init__(self, parent):
        '''
        Initialises with rote and quiet mode to false, dice to 0 and again to 10
        '''
        super().__init__()
        self.initUI()
        self.parent = parent
        self.rote = False
        self.quiet = False
        self.again = 10
        self.dice = 0

    def initUI(self):
        '''
        UI for dice roller
        '''

        grid = QGridLayout()
        self.setLayout(grid)
        #inner grid for the dice roll selecter + its label
        innergrid = QGridLayout()

        #dice_pool_selecter
        #inner grid for the dice roll selecter + its label
        innergrid = QGridLayout()

        #Spinner for selecting pool number
        self.num = QSpinBox()
        self.num.setMaximumSize(QSize(35, 20))
        innergrid.addWidget(self.num, 0, 0)

        #labe; for spinner
        label = QLabel()
        label.setText("Enter Dice Pool")
        innergrid.addWidget(label, 0, 1)

        #add inner grid to normal grid
        grid.addLayout(innergrid, 0, 0)

        #roll button
        roll_button = QPushButton("Roll Dice Pool")
        roll_button.setStyleSheet(
            "QPushButton:pressed { background-color: white }")
        roll_button.clicked.connect(self.roll_handler)
        grid.addWidget(roll_button, 2, 2)

        #chance roll button
        chance_button = QPushButton("Roll Chance Die")
        chance_button.setStyleSheet(
            "QPushButton:pressed { background-color: white }")
        chance_button.clicked.connect(self.chance_handler)
        grid.addWidget(chance_button, 1, 2)

        #rote check
        self.rote_sel = QCheckBox()
        self.rote_sel.setText("Rote")
        grid.addWidget(self.rote_sel, 1, 0)

        #quiet check
        self.quiet_sel = QCheckBox()
        self.quiet_sel.setText("Quiet Mode")
        grid.addWidget(self.quiet_sel, 2, 0)

        #again buttons
        #10 is selected on initiation
        #Might look into making this an explicit button group instead
        again10 = QRadioButton()
        again10.setText("10 Again")
        again10.setChecked(True)
        again10.toggled.connect(lambda: self.change_again(again10))
        grid.addWidget(again10, 0, 1)

        again9 = QRadioButton()
        again9.setText("9 Again")
        again9.toggled.connect(lambda: self.change_again(again9))
        grid.addWidget(again9, 1, 1)

        again8 = QRadioButton()
        again8.setText("8 Again")
        again8.toggled.connect(lambda: self.change_again(again8))
        grid.addWidget(again8, 2, 1)

    def change_again(self, button):
        '''
        Method that runs whenever an again radio button is clicked
        '''

        #dict showing value for each button
        agains = {'10 Again': 10, '9 Again': 9, '8 Again': 8}

        #uses text of pushed button as key, sets value of self.again
        self.again = agains[button.text()]

    def roll_handler(self):
        '''
        handler for when roll button pushed
        '''
        #Check if details entered yet
        if char.stats['webhook'] == "" or char.stats['user id'] == "":
            #Tell user something is missing and then stop
            self.parent.status_update("User Details Missing.")
            return

        self.parent.status_update("Rolling dice.")

        #reads UI elements to get other values
        dice = self.num.value()
        if dice == 0:
            self.parent.status_update("Please select at least 1 die.")
            return

        #Qt checkboxes are tri-state, return 2 if checked.
        rote = self.rote_sel.checkState() == 2
        quiet = self.quiet_sel.checkState() == 2

        #call roll_set method on character object
        #this returns a list of strings of each die result follwoed by total successes
        #if quiet mode selected, returns a single element list stating total successes
        messages = char.roll_set(dice, rote, self.again, quiet)

        for message in messages:
            self.send(message, char.stats['webhook'])
            time.sleep(1)

        #Updates status with final element in list, which will be total successes
        self.parent.status_update(messages[-1].replace(
            " for " + char.stats['user id'], ""))

    def chance_handler(self):
        '''
        Handler for chance roll button.
        '''

        self.parent.status_update("Rolling chance die.")

        #Check if details entered yet
        if char.stats['webhook'] == "" or char.stats['user id'] == "":
            #Tell user something is missing
            self.parent.status_update("User Details Missing.")
            return

        #use roll_chance method for character object
        #returns a list of strings, first states die value and second states its result
        messages = char.roll_chance()

        for message in messages:
            self.send(message, char.stats['webhook'])
            time.sleep(1)

        #Prints final result to client console
        self.parent.status_update(messages[-1].replace(char.stats['user id'],
                                                       "You"))

    def send(self, message, webhook):
        '''
        Sends message to webhook
        '''

        #create connection
        #If expanding to other services further changes will be required here
        conn = http.client.HTTPSConnection("discordapp.com")

        #input sanitation: the seperator for each element is replaced by a space if found in message
        sep = "--11BOUND11"
        message = message.replace(sep, " ")

        #This payload will make a Discord webhook send message to its associated channel
        #If expanding to other services further changes may be required here
        payload = sep + "\r\nContent-Disposition: form-data; name=\"content\"\r\n\r\n" + message + "\r\n" + sep + "--"

        #headers for the connection
        #If expanding to other services further changes may be required here
        headers = {
            'content-type': "multipart/form-data; boundary=" + sep[2:],
            'cache-control': "no-cache",
        }

        #sends a POST command to the webhook with the payload and headers defined above
        conn.request("POST", webhook, payload, headers)

        #get response
        res = conn.getresponse()

        #warning messages
        text = res.read()
        text = text.decode("utf-8")

        #first check if there was a warning message
        #For discord, the data will be blank unless error occures sending webhook
        #Usually a rate limit hit
        #For expansion to other services this may need to be updated

        if text != "":
            if "rate limited" in text:
                #confirms that is is a rate limit on Discord
                #Discord will helpfully tell the user how long they need to wait until the next retry
                index1 = text.find('"retry_after"')
                chop = text[index1 + 13:]
                wait = ''
                for character in chop:
                    #find the wait time requested
                    #given in miliseconds usually
                    if character in '0123456789':
                        wait += character
                    if character == '\n':
                        break

                #wait will given in miliseconds, convert to seconds and add 0.5 just in case
                wait = int(wait) / 1000 + 0.5

                #update status, should always have at least 3 significant digits
                self.parent.status_update(
                    "Rate limit hit. Will try again in " + str(wait)[:4] +
                    " seconds.")

                #try again after wait
                time.sleep(wait)
                send(message, webhook)

            if "400 Bad Request" in text:
                #Likely bad bad URL
                #look into making a pop up dialogue instead
                self.parent.status_update(
                    "400 Bad Request - Double check URL.")
                return

            else:
                #Unexpected problem - Result printed to client console
                #goes as a temp message so it won't be overwritten by success message
                #user can still find results in last roll display
                #might look into making this a pop up dialogue instead
                index1 = text.find('"message"')
                index2 = text.find('\n', index1)
                chop = text[index1:index2]
                self.parent.statusBar.showMessage(chop)
                return
            #end of if statement for warning message

            #now include some rate limit protection
            remaining = int(res.getheader('X-RateLimit-Remaining'))
            reset = int(res.getheader('X-RateLimit-Reset')) - int(time.time())

            #reset should be the number of seconds until rate limit refreshed
            #In my experience it will reset faster than this
            #For now, it will add delays to messages if remaining message count is less than or equal to 2

            if remaining <= 2:
                self.parent.status_update(
                    "Rate Limit approaching. Next message delay is 2 seconds.")
                #already a 1 second delay between messages, so extra secound added here
                time.sleep(1)
Esempio n. 6
0
class QTrainingInfoBox(
        QWidget,
        QObserver,
        qobservables={
            # FIXME[hack]: check what we are really interested in ...
            Trainer: Trainer.Change.all()
        }):
    """

    Attributes
    ----------
    range: numpy.ndarray

    trainingLoss: numpy.ndarray

    validationLoss: numpy.ndarray

    rangeIndex: int
    """

    _trainer: Trainer = None

    def __init__(self, trainer: Optional[Trainer] = None, **kwargs):
        """Initialization of the QTrainingBox.
        """
        super().__init__(**kwargs)

        self._initUI()
        self._layoutComponents()

        self._range = np.arange(100, dtype=np.float32)
        self._rangeIndex = 0
        self._trainingLoss = np.zeros(100, dtype=np.float32)
        self._validationLoss = np.zeros(100, dtype=np.float32)

        self.setTrainer(trainer)

    def _initUI(self):
        def slot(checked: bool):
            if self._trainer.ready:
                self._trainer.start()
            elif self._trainer.running:
                self._trainer.stop()

        self._buttonTrainModel = QPushButton("Train")
        self._buttonTrainModel.clicked.connect(slot)

        self._plotLoss = QMatplotlib()
        self._checkboxPlot = QCheckBox()

        self._progressEpoch = QProgressBar()
        self._progressEpoch.setFormat("%v/%m")
        self._progressBatch = QProgressBar()
        self._progressBatch.setFormat("%v (%p%)")

        self._labelBatch = QLabel()
        self._labelEpoch = QLabel()
        self._labelLoss = QLabel()
        self._labelAccuracy = QLabel()
        self._labelDuration = QLabel()

        self._lblTrainee = QLabel()

        def slot(value: int):
            self._trainer.epochs = value

        self._spinboxEpochs = QSpinBox()
        self._spinboxEpochs.valueChanged.connect(slot)

        def slot(value: int):
            self._trainer.batch_size = value

        self._spinboxBatchSize = QSpinBox()
        self._spinboxBatchSize.valueChanged.connect(slot)

    def _layoutComponents(self):
        form = QFormLayout()
        form.addRow("Trainee:", self._lblTrainee)
        form.addRow("Batch:", self._labelBatch)
        form.addRow("Epoch:", self._labelEpoch)
        form.addRow("Loss:", self._labelLoss)
        form.addRow("Accuracy:", self._labelAccuracy)
        form.addRow("Duration:", self._labelDuration)
        form.addRow("Plot:", self._checkboxPlot)

        layout = QVBoxLayout()
        layout.addWidget(self._plotLoss)
        layout.addLayout(form)
        layout.addWidget(self._progressBatch)
        layout.addWidget(self._progressEpoch)
        layout.addWidget(self._buttonTrainModel)
        layout.addWidget(self._spinboxEpochs)
        layout.addWidget(self._spinboxBatchSize)
        self.setLayout(layout)

    def _enableComponents(self):
        enabled = (self._trainer is not None and self._trainer.ready)
        self._buttonTrainModel.setEnabled(enabled)
        enabled = enabled and not self._trainer.running
        self._spinboxEpochs.setEnabled(enabled)
        self._spinboxBatchSize.setEnabled(enabled)

    def setTrainer(self, trainer: Trainer) -> None:
        self._enableComponents()

    def trainer_changed(self, trainer, change):
        self._enableComponents()
        return

        if 'trainee_changed' in change:
            self._lblTrainee.setText(str(trainer.trainee))
            self._enableComponents()

        if 'training_changed' in change:
            if self._trainer.epochs:
                self._progressEpoch.setRange(0, self._trainer.epochs)
            if self._trainer.batches:
                self._progressBatch.setRange(0, self._trainer.batches)

            if self._trainer is not None:
                if self._trainer.running:
                    self._buttonTrainModel.setText("Stop")
                else:
                    self._buttonTrainModel.setText("Train")
            self._enableComponents()

        if 'epoch_changed' in change:
            if self._trainer.epoch is None:
                self._labelEpoch.setText("")
                self._progressEpoch.setValue(0)
            else:
                self._labelEpoch.setText(str(self._trainer.epoch))
                self._progressEpoch.setValue(self._trainer.epoch + 1)

        if 'batch_changed' in change:
            if self._trainer.batch is not None:
                self._labelBatch.setText(f"{self._trainer.batch}/"
                                         f"{self._trainer.batches}")
                self._labelDuration.setText(str(self._trainer.batch_duration))
                self._progressBatch.setValue(self._trainer.batch)

        if 'parameter_changed' in change:
            self._spinboxEpochs.setRange(*self._trainer.epochs_range)
            self._spinboxEpochs.setValue(self._trainer.epochs)
            self._spinboxBatchSize.setRange(*self._trainer.batch_size_range)
            self._spinboxBatchSize.setValue(self._trainer.batch_size)

        if self._trainer.loss is not None:
            self._labelLoss.setText(str(self._trainer.loss))
            self._trainerLoss[self._rangeIndex] = self._trainer.loss
            if self._checkboxPlot.checkState():
                self._plotLoss.plot(self._range, self._trainerLoss)
            # self._plotLoss.plot(self._validationLoss)

        if self._trainer.accuracy is not None:
            self._labelAccuracy.setText(str(self._trainer.accuracy))

        self._rangeIndex = (self._rangeIndex + 1) % len(self._range)
Esempio n. 7
0
class mainWindow(QtWidgets.QWidget):
	def __init__(self):
		super(mainWindow , self).__init__()
		self.__initWidget()
		self.__initSignalSlot()
		self.__initUser()
		
	def __initWidget(self):
		self.resize(300,200)
		self.xhLabel = QLabel('学号')
		self.mmLabel = QLabel('密码')
		self.authLabel = QLabel('验证码')
		self.imageLabel = QLabel()
		
		self.xhLine = QLineEdit()
		self.mmLine = QLineEdit()
		self.mmLine.setEchoMode(QLineEdit.Password)
		self.authLine = QLineEdit()
		#self.authImageScene = QGraphicsScene
		self.authButton = QPushButton('获取验证码')
		self.okButton = QPushButton('登陆')
		self.chBox = QCheckBox('记住密码')
		self.chBox.setCheckState(Qt.Checked)

		self.displayScoreButton = QPushButton('显示成绩')
		self.okButton.setEnabled(False)
		self.displayScoreButton.setEnabled(False)
		self.tips = QLabel('正在登录 ...')
		self.tipsOk = QLabel('登陆成功!')
		
		self.gridLayout = QGridLayout()
		self.gridLayout.addWidget(self.xhLabel , 0 , 0 , 1 , 1)
		self.gridLayout.addWidget(self.mmLabel , 1 , 0 , 1 , 1)
		self.gridLayout.addWidget(self.authLabel , 2 , 0 , 1 , 1)
		self.gridLayout.addWidget(self.xhLine , 0 , 1 , 1 , 1)
		self.gridLayout.addWidget(self.mmLine , 1 , 1 , 1 , 1)
		self.gridLayout.addWidget(self.authLine , 2 , 1 , 1 , 1)
		self.gridLayout.addWidget(self.imageLabel , 3 , 1 , 1 , 1)
		self.gridLayout.addWidget(self.tipsOk , 4 , 1 , 2 , 1)
		self.gridLayout.addWidget(self.tips , 4 , 1 , 2 , 1)
		
		self.tips.hide()
		self.tipsOk.hide()
		
		self.hLayout = QHBoxLayout()
		self.hLayout.addWidget(self.authButton)
		self.hLayout.addWidget(self.okButton)
		self.hLayout.addStretch(3)
		self.hLayout.addWidget(self.chBox)
		
		self.vLayout = QVBoxLayout()
		self.vLayout.addStretch(10)
		self.vLayout.addLayout(self.hLayout)
		self.vLayout.addStretch(10)
		self.vLayout.addWidget(self.displayScoreButton)
		
		self.mainLayout = QVBoxLayout()
		self.mainLayout.addLayout(self.gridLayout)
		self.mainLayout.addLayout(self.vLayout)
		self.setLayout(self.mainLayout)
	
	def __initSignalSlot(self):
		self.okButton.clicked.connect(self.__logClicked)
		self.authButton.clicked.connect(self.__getAuthCode)
		self.displayScoreButton.clicked.connect(self.__showScore)
		#self.chBox.stateChanged.connect(self.__chBoxChange)
	
	def __initUser(self):
		self.user = []
		try:
			with open('user.txt' , 'r') as file:
				lines = file.readlines()
				for line in lines:
					self.user.append(line.strip('\n'))
		except :
			self.user.extend(['',''])
		self.xhLine.setText(self.user[0])
		if len(self.user) > 1:
			self.mmLine.setText(self.user[1])
			
	def __getAuthCode(self):
		self.tips.hide()
		
		# get authcode
		self.login = CSpiderSchoolWeb()
		self.login.getAuthCode()
		
		image = QImage()
		image.load('image.gif')
		self.imageLabel.setPixmap(QPixmap.fromImage(image))
		
		self.tipsOk.hide()
		self.okButton.setEnabled(True)
		self.displayScoreButton.setEnabled(False)
		
	def __logClicked(self):

		self.tips.show()
		xh = self.xhLine.text()
		mm = self.mmLine.text()
		auth = self.authLine.text()
		
		with open('user.txt','w') as file:
			file.write(xh + '\n')
			if self.chBox.checkState() == Qt.Checked:
				file.write(mm + '\n')
		# login
		self.login.loginSchoolWeb(xh , mm , auth)
		
		self.displayScoreButton.setEnabled(True)
		self.okButton.setEnabled(False)
		
		self.tips.hide()
		self.tipsOk.show()	

	def __showScore(self):
		# remember use self.XXX , otherwise the windows exit imidatelt
		self.scoreWin = CScoreWindow()
		self.scoreWin.setAll( self.login.getStudentGradeAndSem() )
		#self.scoreWin.setAll( (['2014-2015','2013-2014'] , ['2']) )
		self.scoreWin.show()
Esempio n. 8
0
class RepeaterWidget(QWidget):
    def __init__(self, client):
        QWidget.__init__(self)
        self.client = client
        self.history = []
        self.history_pos = 0

        self.setLayout(QVBoxLayout())
        self.layout().setSpacing(0)
        self.layout().setContentsMargins(0, 0, 0, 0)
        buttons = QHBoxLayout()
        buttons.setContentsMargins(0, 0, 0, 0)
        buttons.setSpacing(8)

        submitButton = QPushButton("Submit")
        submitButton.clicked.connect(self.submit)
        self.dest_host_input = QLineEdit()
        self.dest_port_input = QLineEdit()
        self.dest_port_input.setMaxLength(5)
        self.dest_port_input.setSizePolicy(QSizePolicy.Minimum,
                                           QSizePolicy.Preferred)
        self.dest_usetls_input = QCheckBox()

        self.back_button = QToolButton()
        self.back_button.setText("<")
        self.back_button.clicked.connect(self.back)
        self.forward_button = QToolButton()
        self.forward_button.setText(">")
        self.forward_button.clicked.connect(self.forward)

        buttons.addWidget(self.back_button)
        buttons.addWidget(self.forward_button)
        buttons.addWidget(submitButton)
        buttons.addWidget(QLabel("Host:"))
        buttons.addWidget(self.dest_host_input)
        buttons.addWidget(QLabel("Port:"))
        buttons.addWidget(self.dest_port_input)
        buttons.addWidget(QLabel("Use TLS:"))
        buttons.addWidget(self.dest_usetls_input)
        buttons.addStretch()

        self.reqview = ReqViewWidget(tag_tab=True)
        self.reqview.set_read_only(False)
        self.reqview.set_tags_read_only(False)
        self.layout().addLayout(buttons)
        self.layout().addWidget(self.reqview)

        self.req = None
        self.dest_host = ""
        self.dest_port = 80
        self.use_tls = False
        self._update_buttons()

    def _set_host(self, host):
        self.dest_host_input.setText(host)

    def _set_port(self, port):
        if port is None or port <= 0:
            self.dest_port_input.setText("")
        else:
            self.dest_port_input.setText(str(port))

    def _set_usetls(self, usetls):
        if usetls:
            self.dest_usetls_input.setCheckState(2)
        else:
            self.dest_usetls_input.setCheckState(0)

    def _set_dest_info(self, host, port, usetls):
        self._set_host(host)
        self._set_port(port)
        self._set_usetls(usetls)

    def _get_dest_info(self):
        host = self.dest_host_input.text()
        try:
            port = int(self.dest_port_input.text())
        except:
            port = -1
        if self.dest_usetls_input.checkState() == 0:
            usetls = False
        else:
            usetls = True
        return (host, port, usetls)

    def set_request(self, req, update_history=True):
        self._set_dest_info("", -1, False)
        if update_history:
            self.history.append(req)
            self.history_pos = len(self.history) - 1
            self._update_buttons()
        if req:
            self.req = req
            self.req.tags = set(["repeater"])
            self._set_dest_info(req.dest_host, req.dest_port, req.use_tls)
        self.reqview.set_request(self.req)

    @pyqtSlot(set)
    def update_req_tags(self, tags):
        if self.req:
            self.req.tags = tags

    @pyqtSlot()
    def submit(self):
        try:
            req = self.reqview.get_request()
            if not req:
                display_error_box("Could not parse request")
                return
        except:
            display_error_box("Could not parse request")
            return
        req.tags.add("repeater")
        host, port, usetls = self._get_dest_info()
        if port is None:
            display_error_box("Invalid port")
            return
        req.dest_host = host
        req.dest_port = port
        req.dest_usetls = usetls
        self.client.submit(req, save=True)
        self.req = req
        self.set_request(req)

    @pyqtSlot()
    def back(self):
        if self.history_pos > 0:
            self.history_pos -= 1
            self.set_request(self.history[self.history_pos],
                             update_history=False)
        self._update_buttons()

    @pyqtSlot()
    def forward(self):
        if self.history_pos < len(self.history) - 1:
            self.history_pos += 1
            self.set_request(self.history[self.history_pos],
                             update_history=False)
        self._update_buttons()

    def _update_buttons(self):
        self.forward_button.setEnabled(True)
        self.back_button.setEnabled(True)
        if len(self.history) == 0 or self.history_pos == len(self.history) - 1:
            self.forward_button.setEnabled(False)
        if self.history_pos == 0:
            self.back_button.setEnabled(False)
Esempio n. 9
0
class QuickInstructions(QWidget):
    """
    Implementation of the quick instructions.
    """
    def __init__(self, parent=None):
        super(QuickInstructions, self).__init__(parent)
        # self.setAttribute(Qt.WA_DeleteOnClose) # Deletes instance on window close
        self.setWindowTitle('pyIMD :: Quick instructions')
        self.display_on_startup = 2
        self.resize(400, 370)
        self.setWindowIcon(
            QtGui.QIcon(
                resource_path(
                    os.path.join(
                        os.path.join("ui", "icons", "pyIMD_logo_icon.ico")))))
        grid = QGridLayout()
        grid.setContentsMargins(5, 5, 5, 5)
        ok = QPushButton('Ok')
        ok.setIcon(QApplication.style().standardIcon(
            QStyle.SP_DialogApplyButton))
        ok.setMaximumWidth(100)
        ok.clicked.connect(self.close)
        self.chk = QCheckBox('Display quick instructions at startup')
        self.chk.setFont(QFont('Arial', 9, QFont.Bold))
        self.chk.setChecked(1)
        self.chk.clicked.connect(self.on_display_qi)

        self.quick_instructions = QTextEdit(self)
        self.quick_instructions.setText(
            '<h3>Quick Instructions</h3> '
            'Edit the settings first according to your experimental setup. Second select '
            'the directory containing your experimental data and determine the file name '
            'to measurement relationship as well as the measurement mode the data was '
            'recorded with.'
            '<br><br>Controls:'
            '<ul>'
            '<li><b>Ctrl+N (Cmd+N):</b> Create a new pyIMD project.'
            '</li>'
            '<li><b>Ctrl+O (Cmd+O):</b> Open an existing pyIMD project'
            '</li>'
            '<li><b>Ctrl+S (Cmd+S):</b> Save the current pyIMD project'
            '</li>'
            '<li><b>Ctrl+P (Cmd+P):</b> Open the settings dialog to change the project '
            'parameters</li></ul>'
            'Hints:'
            '<ul><li>Create a pyIMD project for all your experiments first and save '
            'the pyIMD projects before running them individually. The projects can then '
            'be run sequentially using the batch mode (Batch processing tab).'
            '</li>'
            '<li>Select multiple data files holding the Ctrl button during selection after'
            'clicking on <i>Select directory</i> or Ctrl+N.</li><'
            '</ul>'
            'You can open this window any time from the Help menu.</ul>')
        self.quick_instructions.setReadOnly(1)
        self.quick_instructions.setFont(QFont('Arial', 9))
        grid.addWidget(self.quick_instructions, 0, 0, 1, 0)
        grid.addWidget(ok, 1, 1)
        grid.addWidget(self.chk, 1, 0)
        self.setLayout(grid)

    def on_display_qi(self):
        self.display_on_startup = self.chk.checkState()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Escape:
            self.close()
class MediaCueGeneral(CueGeneral):

    Name = 'Cue Settings'

    def __init__(self, size, cue=None, parent=None):
        super().__init__(size, cue=cue, parent=parent)

        # Start at
        self.startGroup = QGroupBox(self)
        self.startGroup.setLayout(QHBoxLayout())

        self.startEdit = QTimeEdit(self.startGroup)
        self.startEdit.setDisplayFormat('HH.mm.ss.zzz')
        self.startGroup.layout().addWidget(self.startEdit)

        self.startLabel = QLabel(self.startGroup)
        self.startLabel.setAlignment(QtCore.Qt.AlignCenter)
        self.startGroup.layout().addWidget(self.startLabel)

        self.layout().addWidget(self.startGroup)

        # Loop
        self.loopGroup = QGroupBox(self)
        self.loopGroup.setLayout(QHBoxLayout())

        self.spinLoop = QSpinBox(self.loopGroup)
        self.spinLoop.setRange(-1, 1000000)
        self.loopGroup.layout().addWidget(self.spinLoop)

        self.loopLabel = QLabel(self.loopGroup)
        self.loopLabel.setAlignment(QtCore.Qt.AlignCenter)
        self.loopGroup.layout().addWidget(self.loopLabel)

        self.layout().addWidget(self.loopGroup)

        # Checks
        self.checkPause = QCheckBox(self)
        self.layout().addWidget(self.checkPause)

        self.retranslateUi()

    def retranslateUi(self):
        self.startGroup.setTitle('Start time')
        self.startLabel.setText('Amount of skip time')
        self.loopGroup.setTitle("Loop")
        self.loopLabel.setText("Repetition after first play (-1 = infinite)")
        self.checkPause.setText("Enable Pause")

    def get_configuration(self):
        conf = super().get_configuration()
        conf['media'] = {}

        checkable = self.startGroup.isCheckable()

        if not (checkable and not self.startGroup.isChecked()):
            time = self.startEdit.time().msecsSinceStartOfDay()
            conf['media']['start_at'] = time
        if not (checkable and not self.loopGroup.isChecked()):
            conf['media']['loop'] = self.spinLoop.value()
        if self.checkPause.checkState() != QtCore.Qt.PartiallyChecked:
            conf['pause'] = self.checkPause.isChecked()

        return conf

    def enable_check(self, enable):
        super().enable_check(enable)

        self.startGroup.setCheckable(enable)
        self.startGroup.setChecked(False)

        self.loopGroup.setCheckable(enable)
        self.loopGroup.setChecked(False)

        self.checkPause.setTristate(enable)
        if enable:
            self.checkPause.setCheckState(QtCore.Qt.PartiallyChecked)

    def set_configuration(self, conf):
        super().set_configuration(conf)

        if 'pause' in conf:
            self.checkPause.setChecked(conf['pause'])
        if 'media' in conf:
            if 'loop' in conf['media']:
                self.spinLoop.setValue(conf['media']['loop'])
            if 'duration' in conf['media'] and conf['media']['duration'] > 0:
                t = QTime().fromMSecsSinceStartOfDay(conf['media']['duration'])
                self.startEdit.setMaximumTime(t)
            if 'start_at' in conf['media']:
                t = QTime().fromMSecsSinceStartOfDay(conf['media']['start_at'])
                self.startEdit.setTime(t)
class QtBoolEdit(QWidget):
    toggledSignal = pyqtSignal(bool)
    def __init__(self,parent=None):
        super(QtBoolEdit, self).__init__(parent)
        self.m_checkBox = QCheckBox(self)
        self.m_textVisible = True
        lt = QHBoxLayout()
        if (QApplication.layoutDirection() == Qt.LeftToRight):
            lt.setContentsMargins(4, 0, 0, 0)
        else:
            lt.setContentsMargins(0, 0, 4, 0)
        lt.addWidget(self.m_checkBox)
        self.setLayout(lt)
        self.m_checkBox.toggled.connect(self.toggledSignal)
        self.setFocusProxy(self.m_checkBox)
        self.m_checkBox.setText(self.tr("True"))

    def textVisible(self):
        return self.m_textVisible

    def setTextVisible(self,textVisible):
        if (self.m_textVisible == textVisible):
            return

        self.m_textVisible = textVisible
        if self.m_textVisible:
            if self.isChecked():
                self.m_checkBox.setText(self.tr("True"))
            else:
                self.m_checkBox.setText(self.tr("False"))
        else:
            self.m_checkBox.setText('')

    def checkState(self):
        return self.m_checkBox.checkState()

    def setCheckState(self,state):
        self.m_checkBox.setCheckState(state)

    def isChecked(self):
        return self.m_checkBox.isChecked()

    def setChecked(self,c):
        self.m_checkBox.setChecked(c)
        if self.m_textVisible==False:
            return
        if self.isChecked():
            self.m_checkBox.setText(self.tr("True"))
        else:
            self.m_checkBox.setText(self.tr("False"))

    def blockCheckBoxSignals(self,block):
        return self.m_checkBox.blockSignals(block)

    def mousePressEvent(self, event):
        if (event.buttons() == Qt.LeftButton):
            self.m_checkBox.click()
            event.accept()
        else:
            super(QtBoolEdit, self).mousePressEvent(event)

    def paintEvent(self, pt_QPaintEvent):
        opt = QStyleOption()
        opt.initFrom(self)
        p = QPainter(self)
        self.style().drawPrimitive(QStyle.PE_Widget, opt, p, self)
Esempio n. 12
0
class BasicFilterPage(QWidget):
    def __init__(self, parent=None):
        super(BasicFilterPage, self).__init__(parent)

        self.blockCombo = QComboBox()
        self.deviceCombo = QComboBox()
        self.unitCombo = QComboBox()

        self.combos = {'block': self.blockCombo, \
                       'device': self.deviceCombo, \
                       'unit': self.unitCombo}

        groupLayout = QFormLayout()
        groupLayout.addRow("Skupina měření:", self.blockCombo)
        groupLayout.addRow("Přístroj:", self.deviceCombo)
        groupLayout.addRow("Veličina:", self.unitCombo)

        filterGroup = QGroupBox("Základní filtry")
        filterGroup.setLayout(groupLayout)

        self.deviatedValuesCheckbox = QCheckBox()
        valuesLayout = QFormLayout()
        valuesLayout.addRow("Mimo odchylku:", self.deviatedValuesCheckbox)

        valuesGroup = QGroupBox("Hodnoty")
        valuesGroup.setLayout(valuesLayout)

        layout = QVBoxLayout()
        layout.addWidget(filterGroup)
        layout.addSpacing(12)
        layout.addWidget(valuesGroup)
        layout.addStretch(1)

        self.setLayout(layout)

    def setComboOptions(self, combo, options, selected=''):
        items = ['']
        for option in options:
            items.append(str(option))

        try:
            index = items.index(str(selected))
        except ValueError:
            index = 0

        combo.clear()
        combo.addItems(items)
        combo.setCurrentIndex(index)

    def getFilter(self):
        filter_ = {}

        for name, combo in self.combos.items():
            selected = combo.currentText()
            if selected:
                filter_[name] = selected

        filter_['deviated_values'] = bool(self.deviatedValuesCheckbox.checkState())

        return filter_

    def initControls(self, options, filter_):
        for name, combo in self.combos.items():
            try:
                comboOptions = options[name]
            except KeyError:
                continue
            else:
                selectedOption = filter_.get(name, '')
                self.setComboOptions(combo, comboOptions, selectedOption)

        checked = filter_.get('deviated_values', False)
        self.deviatedValuesCheckbox.setChecked(checked)
Esempio n. 13
0
class WeatherSationView(QTableView):
    def __init__(self, parent=None, *args):
        super(WeatherSationView, self).__init__()
        self.setShowGrid(False)
        self.setAlternatingRowColors(True)
        self.setMinimumWidth(650)
        self.setSortingEnabled(True)

        self.chkbox_header = QCheckBox(self.horizontalHeader())
        self.chkbox_header.setToolTip('Check or uncheck all the weather '
                                      'stations in the table.')
        self.chkbox_header.stateChanged.connect(self.chkbox_header_isClicked)
        self.horizontalHeader().installEventFilter(self)
        self.verticalHeader().hide()

        self.set_geocoord(None)
        self.populate_table(WeatherSationList())

        self.setItemDelegateForColumn(0, CheckBoxDelegate(self))
        self.setColumnWidth(0, 32)
        self.setColumnWidth(3, 75)
        self.setColumnWidth(4, 75)
        self.setColumnWidth(5, 75)
        self.setColumnHidden(7, True)
        self.setColumnHidden(8, True)
        self.setColumnHidden(9, True)
        self.setColumnHidden(10, True)

        self.horizontalHeader().setSectionResizeMode(QHeaderView.Fixed)
        self.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)

    @property
    def geocoord(self):
        return self.__latlon

    def set_geocoord(self, latlon):
        self.__latlon = latlon
        self.setColumnHidden(2, latlon is None)
        if latlon and self.stationlist:
            prox = calc_dist_from_coord(self.geocoord[0], self.geocoord[1],
                                        self.stationlist['Latitude'],
                                        self.stationlist['Longitude'])

            model = self.model()
            model._data[:, 2] = prox
            model.dataChanged.emit(model.index(0, 2),
                                   model.index(model.rowCount(0), 2))

    def eventFilter(self, source, event):
        if (event.type() == QEvent.Resize):
            self.resize_chkbox_header()
        return QWidget.eventFilter(self, source, event)

    def chkbox_header_isClicked(self):
        model = self.model()
        model._checks[:] = int(self.chkbox_header.checkState() == Qt.Checked)
        model.dataChanged.emit(model.index(0, 0),
                               model.index(model.rowCount(0), 0))

    def resize_chkbox_header(self):
        h = self.style().pixelMetric(QStyle.PM_IndicatorHeight)
        w = self.style().pixelMetric(QStyle.PM_IndicatorWidth)
        W = self.horizontalHeader().sectionSize(0)
        H = self.horizontalHeader().height()
        y0 = (H - h)//2
        x0 = (W - w)//2
        self.chkbox_header.setGeometry(x0, y0, w, h)

    def clear(self):
        """Removes all items in the view."""
        self.populate_table(WeatherSationList())

    def populate_table(self, stationlist):
        self.stationlist = stationlist
        N = len(stationlist)
        M = len(WeatherStationModel.HEADER)
        if N == 0:
            data = np.empty((0, M))
        else:
            if self.geocoord:
                prox = calc_dist_from_coord(
                        self.geocoord[0], self.geocoord[1],
                        stationlist['Latitude'], stationlist['Longitude'])
                self.setColumnHidden(2, False)
            else:
                prox = np.empty(N).astype(str)
                self.setColumnHidden(2, True)

            data = np.vstack([np.arange(N).astype(int),
                              stationlist['Name'],
                              prox,
                              stationlist['DLY First Year'],
                              stationlist['DLY Last Year'],
                              stationlist['Province'],
                              stationlist['ID'],
                              stationlist['Station ID'],
                              stationlist['Latitude'],
                              stationlist['Longitude'],
                              stationlist['Elevation']
                              ]).transpose()

        checked = self.chkbox_header.checkState() == Qt.Checked
        self.setModel(WeatherStationModel(data, checked))
        self.model().sort(self.horizontalHeader().sortIndicatorSection(),
                          self.horizontalHeader().sortIndicatorOrder())

    # ---- Utility methods

    def get_row_from_climateid(self, climateid):
        idx = np.where(self.model()._data[:, 6] == climateid)[0]
        if len(idx) > 0:
            return idx[0]
        else:
            return None

    def get_checked_rows(self):
        return np.where(self.model()._checks == 1)[0]

    def get_content4rows(self, rows, daterange='full'):
        """
        Grab the weather station info for the specified rows and
        save the results in a list.
        """
        indexes = self.model()._data[rows, 0]
        stationlist = WeatherSationList()
        for index in indexes:
            stationlist.append(self.stationlist[int(index)])
        return stationlist

    def get_prox_data(self):
        """Returns the proximity value shown in the table."""
        if self.geocoord:
            return np.array(self.model()._data[:, 2]).astype(float)
        else:
            return None

    def get_stationlist(self):
        """Get and format the content of the QTableView."""
        indexes = self.model()._data[:, 0]
        stationlist = WeatherSationList()
        for index in indexes:
            stationlist.append(self.stationlist[int(index)])
        return stationlist

    def save_stationlist(self, filename):
        """Save the content of the QTableWidget to file."""
        stationlist = self.get_stationlist()
        stationlist.save_to_file(filename)
Esempio n. 14
0
class CueGeneralSettings(SettingsPage):
    Name = 'Cue'

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.setLayout(QVBoxLayout())

        # Pre wait
        self.preWaitGroup = QGroupBox(self)
        self.preWaitGroup.setLayout(QHBoxLayout())
        self.layout().addWidget(self.preWaitGroup)

        self.preWaitSpin = QDoubleSpinBox(self.preWaitGroup)
        self.preWaitSpin.setMaximum(3600 * 24)
        self.preWaitGroup.layout().addWidget(self.preWaitSpin)

        self.preWaitLabel = QLabel(self.preWaitGroup)
        self.preWaitLabel.setAlignment(Qt.AlignCenter)
        self.preWaitGroup.layout().addWidget(self.preWaitLabel)

        # Post wait
        self.postWaitGroup = QGroupBox(self)
        self.postWaitGroup.setLayout(QHBoxLayout())
        self.layout().addWidget(self.postWaitGroup)

        self.postWaitSpin = QDoubleSpinBox(self.postWaitGroup)
        self.postWaitSpin.setMaximum(3600 * 24)
        self.postWaitGroup.layout().addWidget(self.postWaitSpin)

        self.postWaitLabel = QLabel(self.postWaitGroup)
        self.postWaitLabel.setAlignment(Qt.AlignCenter)
        self.postWaitGroup.layout().addWidget(self.postWaitLabel)

        # Next action
        self.nextActionGroup = QGroupBox(self)
        self.nextActionGroup.setLayout(QHBoxLayout())
        self.layout().addWidget(self.nextActionGroup)

        self.nextActionCombo = QComboBox(self.nextActionGroup)
        self.nextActionCombo.addItems([e.value for e in CueNextAction])
        self.nextActionGroup.layout().addWidget(self.nextActionCombo)

        # Checks
        self.stopPauseCheck = QCheckBox(self)
        self.layout().addWidget(self.stopPauseCheck)

        self.retranslateUi()

    def retranslateUi(self):
        self.preWaitGroup.setTitle('Pre wait')
        self.preWaitLabel.setText('Wait before cue execution')
        self.postWaitGroup.setTitle('Post wait')
        self.postWaitLabel.setText('Wait after cue execution')
        self.nextActionGroup.setTitle('Next action')
        self.stopPauseCheck.setText('Pause instead of stop (if supported)')

    def load_settings(self, settings):
        if 'pre_wait' in settings:
            self.preWaitSpin.setValue(settings['pre_wait'])
        if 'post_wait' in settings:
            self.postWaitSpin.setValue(settings['post_wait'])
        if 'next_action' in settings:
            self.nextActionCombo.setCurrentText(settings['next_action'])
        if 'stop_pause' in settings:
            self.stopPauseCheck.setChecked(settings['stop_pause'])

    def enable_check(self, enable):
        self.preWaitGroup.setCheckable(enable)
        self.preWaitGroup.setChecked(False)

        self.postWaitGroup.setCheckable(enable)
        self.postWaitGroup.setChecked(False)

        self.nextActionGroup.setCheckable(enable)
        self.nextActionGroup.setChecked(False)

        self.stopPauseCheck.setTristate(enable)
        if enable:
            self.stopPauseCheck.setCheckState(Qt.PartiallyChecked)

    def get_settings(self):
        conf = {}
        checkable = self.preWaitGroup.isCheckable()

        if not (checkable and not self.preWaitGroup.isChecked()):
            conf['pre_wait'] = self.preWaitSpin.value()
        if not (checkable and not self.postWaitGroup.isChecked()):
            conf['post_wait'] = self.postWaitSpin.value()
        if not (checkable and not self.nextActionGroup.isChecked()):
            conf['next_action'] = self.nextActionCombo.currentText()
        if self.stopPauseCheck.checkState() != Qt.PartiallyChecked:
            conf['stop_pause'] = self.stopPauseCheck.isChecked()

        return conf
Esempio n. 15
0
class FileChoiceTable(QTableWidget):
    """displays samples so user can choose some of them
    """
    files = pyqtSignal(int)
    files_chosen = pyqtSignal(int)
    
    def __init__(self, project, log, header, query, num_columns, myfilter, 
                 allele_status_column = None, instant_accept_status = None, 
                 parent = None):
        super().__init__()
        self.log = log
        if parent:
            self.settings = parent.settings
        else:
            import GUI_login
            self.settings = GUI_login.get_settings("admin", self.log)
        self.header = header
        self.allele_status_column = allele_status_column
        self.instant_accept_status = instant_accept_status
        self.query = query
        self.num_columns = num_columns
        self.filter = myfilter
        self.init_UI()
    
    def init_UI(self):
        self.setColumnCount(len(self.header))
        self.setHorizontalHeaderLabels(self.header)
        self.horizontalHeader().setStretchLastSection(True)
        self.verticalHeader().hide()
    
    def reset_filter(self, myfilter = ""):
        """sets a new filter for use in self.get_data()
        """
        self.myfilter = myfilter
        
    def get_data(self):
        """get alleles from database
        """
        success, data = db_internal.execute_query(self.query + self.myfilter, self.num_columns, 
                                                  self.log, "retrieving data for FileChoiceTable from database", 
                                                  "Database error", self)
        if success:
            self.data = data
        self.log.debug("Emitting 'files = {}'".format(len(self.data)))
        self.files.emit(len(self.data))
    
    def fill_UI(self):
        """fills table with data
        """
        self.get_data()
        
        rows = len(self.data) + 1
        self.setRowCount(rows)
        
        self.check_dic = {}
        all_checked = True
        for (i, row) in enumerate(self.data):
            cell_widget = QWidget()
            mini_layout = QHBoxLayout(cell_widget)
            cell_widget.setLayout(mini_layout)
            self.check_dic[i] = QCheckBox(self)
            self.check_dic[i].clicked.connect(self.count_chosen)
            self.check_dic[i].clicked.connect(self.unselect_select_all)
            mini_layout.addWidget(self.check_dic[i])
            mini_layout.setAlignment(Qt.AlignCenter)
            self.setCellWidget(i, 0, cell_widget)
            for (k, item) in enumerate(row):
                self.setItem(i, k + 1, QTableWidgetItem(str(item)))
            if self.allele_status_column:
                status = row[self.allele_status_column]
                color = general.color_dic[general.allele_status_dic[status.lower()]]
                status_item = QTableWidgetItem(status)
                status_item.setBackground(QColor(color))
                if self.instant_accept_status:
                    if status == self.instant_accept_status:
                        self.check_dic[i].setChecked(True)
                        status_item.setFont(general.font_bold)
                    else:
                        all_checked = False
            self.setItem(i, self.allele_status_column + 1, status_item)
        
        # add select-all row:
        cell_widget = QWidget()
        mini_layout = QHBoxLayout(cell_widget)
        cell_widget.setLayout(mini_layout)
        self.check_all = QCheckBox(self)
        mini_layout.addWidget(self.check_all)
        if all_checked:
            self.check_all.setChecked(True)
        mini_layout.setAlignment(Qt.AlignCenter)
        self.check_all.clicked.connect(self.toggle_select_all)
        self.setCellWidget(rows-1, 0, cell_widget)
        self.setItem(rows-1, 1, QTableWidgetItem(""))
        self.setItem(rows-1, 2, QTableWidgetItem("Select All"))
        self.setItem(rows-1, 3, QTableWidgetItem(""))       
        self.setItem(rows-1, 4, QTableWidgetItem(""))
        
        self.resizeColumnsToContents()
        self.count_chosen()
    
    def count_chosen(self):
        """counts and emits the number of currently chosen files
        """
        self.log.debug("Recounting chosen files...")
        n = 0
        for i in self.check_dic:
            box = self.check_dic[i]
            if box.checkState():
                n += 1
        self.log.debug("\t=> Currently {} files chosen".format(n))
        self.files_chosen.emit(n)
    
    def unselect_select_all(self):
        """unchecks the 'select all' checkbox when a single file is unchecked manually
        """
        if not self.sender().checkState():
            self.check_all.setChecked(False)
        
    def toggle_select_all(self):
        """select or deselect all alleles at once
        """
        if self.check_all.checkState():
            self.log.debug("Selecting all alleles")
            for i in self.check_dic:
                box = self.check_dic[i]
                box.setChecked(True)
                self.files_chosen.emit(len(self.data))
        else:
            self.log.debug("Deselecting all alleles")
            for i in self.check_dic:
                box = self.check_dic[i]
                box.setChecked(False)
                self.files_chosen.emit(0)
Esempio n. 16
0
class AutonumberDialog(QDialog):
    newtracks = pyqtSignal(int, int, 'Qt::CheckState', int, str, str, 'Qt::CheckState', name='newtracks')

    def __init__(self, parent=None, minval=0, numtracks=0,
                 enablenumtracks=False):

        QDialog.__init__(self, parent)

        self.setWindowTitle(
            translate('Autonumbering Wizard', "Autonumbering Wizard"))
        winsettings('autonumbering', self)

        def hbox(*widgets):
            box = QHBoxLayout()
            [box.addWidget(z) for z in widgets]
            box.addStretch()
            return box

        vbox = QVBoxLayout()

        self._start = QSpinBox()
        self._start.setValue(minval)
        self._start.setMaximum(65536)

        startlabel = QLabel(translate('Autonumbering Wizard', "&Start: "))
        startlabel.setBuddy(self._start)

        vbox.addLayout(hbox(startlabel, self._start))

        self._padlength = QSpinBox()
        self._padlength.setValue(1)
        self._padlength.setMaximum(65535)
        self._padlength.setMinimum(1)

        label = QLabel(translate('Autonumbering Wizard',
                                 'Max length after padding with zeroes: '))
        label.setBuddy(self._padlength)

        vbox.addLayout(hbox(label, self._padlength))

        self._separator = QCheckBox(translate('Autonumbering Wizard',
                                              "Add track &separator ['/']: Number of tracks"))
        self._numtracks = QSpinBox()
        self._numtracks.setEnabled(False)
        self._numtracks.setMaximum(65535)
        if numtracks:
            self._numtracks.setValue(numtracks)
        self._restart_numbering = QCheckBox(translate('Autonumbering Wizard',
                                                      "&Restart numbering at each directory group."))
        self._restart_numbering.stateChanged.connect(
            self.showDirectorySplittingOptions)

        vbox.addLayout(hbox(self._separator, self._numtracks))
        vbox.addWidget(self._restart_numbering)

        self.custom_numbering_widgets = []

        label = QLabel(translate('Autonumbering Wizard', "Group tracks using pattern:: "))

        self.grouping = QLineEdit()
        label.setBuddy(self.grouping)

        vbox.addLayout(hbox(label, self.grouping))
        self.custom_numbering_widgets.extend([label, self.grouping])

        label = QLabel(translate('Autonumbering Wizard', "Output field: "))

        self.output_field = QComboBox()
        label.setBuddy(self.output_field)

        self.output_field.setEditable(True)
        completer = self.output_field.completer()
        completer.setCaseSensitivity(Qt.CaseSensitive)
        completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)

        self.output_field.setCompleter(completer)
        self.output_field.addItems(gettaglist())
        vbox.addLayout(hbox(label, self.output_field))
        self.custom_numbering_widgets.extend([label, self.output_field])

        self.count_by_group = QCheckBox(translate('Autonumbering Wizard',
                                                  'Increase counter only on group change'))
        vbox.addWidget(self.count_by_group)
        self.custom_numbering_widgets.append(self.count_by_group)

        okcancel = OKCancel()
        vbox.addLayout(okcancel)
        self.setLayout(vbox)

        okcancel.ok.connect(self.emitValuesAndSave)
        okcancel.cancel.connect(self.close)
        self._separator.stateChanged.connect(
            lambda v: self._numtracks.setEnabled(v == Qt.Checked))

        # self._restart_numbering.stateChanged.connect(
        #              self.showDirectorySplittingOptions)

        self._separator.setChecked(enablenumtracks)

        self._loadSettings()

    def showDirectorySplittingOptions(self, state):
        is_checked = state == Qt.Checked
        for widget in self.custom_numbering_widgets:
            widget.setVisible(is_checked)

        if is_checked:
            self._numtracks.setVisible(False)
            self._separator.setText(translate('Autonumbering Wizard',
                                              "Add track &separator ['/']"))
        else:
            self._numtracks.setVisible(True)
            self._separator.setText(translate('Autonumbering Wizard',
                                              "Add track &separator ['/']: Number of tracks"))

    def emitValuesAndSave(self):
        if self._numtracks.isVisible():
            if self._separator.isChecked():
                numtracks = self._numtracks.value()
            else:
                numtracks = -1  # Don't use totals
        else:
            if self._separator.isChecked():
                numtracks = -2  # Use totals, automaticall generated
            else:
                numtracks = -1

        self.close()

        self.newtracks.emit(
            self._start.value(),
            numtracks,
            self._restart_numbering.checkState(),
            self._padlength.value(),
            str(self.grouping.text()),
            str(self.output_field.currentText()),
            self.count_by_group.checkState()
        )

        self._saveSettings()

    def _loadSettings(self):
        cparser = PuddleConfig()
        section = 'autonumbering'
        self._start.setValue(cparser.get(section, 'start', 1))
        self._separator.setCheckState(
            cparser.get(section, 'separator', Qt.Unchecked))
        self._padlength.setValue(cparser.get(section, 'padlength', 1))

        self._restart_numbering.setCheckState(
            cparser.get(section, 'restart', Qt.Unchecked))

        self.count_by_group.setCheckState(
            cparser.get(section, 'count_by_group', Qt.Unchecked))

        self.showDirectorySplittingOptions(self._restart_numbering.checkState())

        self.grouping.setText(cparser.get(section, 'grouping', '%__dirpath%'))

        output_field_text = cparser.get(section, 'output_field', 'track')
        if not output_field_text:
            output_field_text = 'track'

        last_output_field_index = self.output_field.findText(output_field_text)
        if last_output_field_index > -1:
            self.output_field.setCurrentIndex(last_output_field_index)

    def _saveSettings(self):
        cparser = PuddleConfig()
        section = 'autonumbering'
        cparser.set(section, 'start', self._start.value())
        cparser.set(section, 'separator', self._separator.checkState())
        cparser.set(section, 'count_by_group', self.count_by_group.checkState())
        cparser.set(section, 'numtracks', self._numtracks.value())
        cparser.set(section, 'restart', self._restart_numbering.checkState())
        cparser.set(section, 'padlength', self._padlength.value())
        cparser.set(section, 'grouping', self.grouping.text())
        cparser.set(section, 'output_field', self.output_field.currentText())
class AdvancedSerialDialog(QDialog):
    def __init__(self, state, parent):
        super().__init__(parent)

        self.setMinimumWidth(350)
        self.setModal(True)
        self.setWindowTitle("Advanced serial settings")

        layout = QVBoxLayout()
        self.setLayout(layout)

        texts = [
            "Please note:",
            (
                "Overriding the baud rate disables automatic"
                " detection and negotiation of baud rate."
            ),
            "Only use on special hardware.",
        ]

        for text in texts:
            lbl = QLabel(text, self)
            lbl.setWordWrap(True)
            layout.addWidget(lbl)

        layout.addStretch(1)

        self.cb = QCheckBox("Override baud rate", self)
        self.cb.stateChanged.connect(self.cb_state_changed)
        layout.addWidget(self.cb)

        self.sb = QSpinBox(self)
        self.sb.setRange(1, int(3e6))
        layout.addWidget(self.sb)

        layout.addStretch(1)

        buttons_widget = QWidget(self)
        layout.addWidget(buttons_widget)
        hbox = QHBoxLayout()
        buttons_widget.setLayout(hbox)
        hbox.addStretch(1)
        cancel_btn = QPushButton("Cancel")
        cancel_btn.clicked.connect(self.reject)
        hbox.addWidget(cancel_btn)
        save_btn = QPushButton("Save")
        save_btn.setDefault(True)
        save_btn.clicked.connect(self.accept)
        hbox.addWidget(save_btn)

        self.set_state(state)

    def cb_state_changed(self, state):
        self.sb.setEnabled(bool(state))

    def set_state(self, state):
        checked = state is not None
        self.cb.setChecked(checked)
        self.cb_state_changed(checked)
        self.sb.setValue(state if checked else 115200)

    def get_state(self):
        return self.sb.value() if self.cb.checkState() else None
Esempio n. 18
0
class PostScriptTab(QWidget):
    name = "Postscript"

    def __init__(self, font, parent=None):
        super(PostScriptTab, self).__init__(parent)

        namingGroup = QGroupBox("Naming", self)
        # namingGroup.setFlat(True)
        namingLayout = QGridLayout(self)

        fontNameLabel = QLabel("FontName:", self)
        self.fontNameEdit = QLineEdit(font.info.postscriptFontName, self)

        fullNameLabel = QLabel("FullName:", self)
        self.fullNameEdit = QLineEdit(font.info.postscriptFullName, self)

        weightNameLabel = QLabel("WeightName:", self)
        self.weightNameEdit = QLineEdit(font.info.postscriptWeightName, self)

        uniqueIDLabel = QLabel("Unique ID:", self)
        if font.info.postscriptUniqueID is not None:
            uniqueID = str(font.info.postscriptUniqueID)
        else:
            uniqueID = ''
        self.uniqueIDEdit = QLineEdit(uniqueID, self)
        self.uniqueIDEdit.setValidator(QIntValidator(self))

        l = 0
        namingLayout.addWidget(fontNameLabel, l, 0)
        namingLayout.addWidget(self.fontNameEdit, l, 1, 1, 2)
        namingLayout.addWidget(weightNameLabel, l, 3)
        namingLayout.addWidget(self.weightNameEdit, l, 4, 1, 2)
        l += 1
        namingLayout.addWidget(fullNameLabel, l, 0)
        namingLayout.addWidget(self.fullNameEdit, l, 1, 1, 2)
        namingLayout.addWidget(uniqueIDLabel, l, 3)
        namingLayout.addWidget(self.uniqueIDEdit, l, 4, 1, 2)
        namingGroup.setLayout(namingLayout)

        hintingGroup = QGroupBox("Hinting", self)
        # hintingGroup.setFlat(True)
        hintingLayout = QGridLayout(self)

        blueValuesLabel = QLabel("Blue values:", self)
        blueValues = " ".join(str(val)
                              for val in font.info.postscriptBlueValues)
        self.blueValuesEdit = QLineEdit(blueValues, self)

        otherBluesLabel = QLabel("Other blues:", self)
        otherBlues = " ".join(str(val)
                              for val in font.info.postscriptOtherBlues)
        self.otherBluesEdit = QLineEdit(otherBlues, self)

        familyBluesLabel = QLabel("Family blues:", self)
        familyBlues = " ".join(str(val)
                               for val in font.info.postscriptFamilyBlues)
        self.familyBluesEdit = QLineEdit(familyBlues, self)

        familyOtherBluesLabel = QLabel("Family other blues:", self)
        familyOtherBlues = " ".join(
            str(val) for val in font.info.postscriptFamilyOtherBlues)
        self.familyOtherBluesEdit = QLineEdit(familyOtherBlues, self)

        l = 0
        hintingLayout.addWidget(blueValuesLabel, l, 0)
        hintingLayout.addWidget(self.blueValuesEdit, l, 1, 1, 2)
        hintingLayout.addWidget(familyBluesLabel, l, 3)
        hintingLayout.addWidget(self.familyBluesEdit, l, 4, 1, 2)
        l += 1
        hintingLayout.addWidget(otherBluesLabel, l, 0)
        hintingLayout.addWidget(self.otherBluesEdit, l, 1, 1, 2)
        hintingLayout.addWidget(familyOtherBluesLabel, l, 3)
        hintingLayout.addWidget(self.familyOtherBluesEdit, l, 4, 1, 2)
        l += 1

        blueFuzzLabel = QLabel("Blue fuzz:", self)
        if font.info.postscriptBlueFuzz is not None:
            blueFuzz = str(font.info.postscriptBlueFuzz)
        else:
            blueFuzz = ''
        self.blueFuzzEdit = QLineEdit(blueFuzz, self)
        self.blueFuzzEdit.setValidator(QDoubleValidator(self))

        stemSnapHLabel = QLabel("StemSnapH:", self)
        stemSnapH = " ".join(str(val) for val in font.info.postscriptStemSnapH)
        self.stemSnapHEdit = QLineEdit(stemSnapH, self)

        blueScaleLabel = QLabel("Blue scale:", self)
        if font.info.postscriptBlueScale is not None:
            blueScale = str(font.info.postscriptBlueScale)
        else:
            blueScale = ''
        self.blueScaleEdit = QLineEdit(blueScale, self)
        self.blueScaleEdit.setValidator(QDoubleValidator(self))

        stemSnapVLabel = QLabel("StemSnapV:", self)
        stemSnapV = " ".join(str(val) for val in font.info.postscriptStemSnapV)
        self.stemSnapVEdit = QLineEdit(stemSnapV, self)

        blueShiftLabel = QLabel("Blue shift:", self)
        if font.info.postscriptBlueShift is not None:
            blueShift = str(font.info.postscriptBlueShift)
        else:
            blueShift = ''
        self.blueShiftEdit = QLineEdit(blueShift, self)
        self.blueShiftEdit.setValidator(QDoubleValidator(self))

        forceBoldLabel = QLabel("Force bold:", self)
        forceBold = font.info.postscriptForceBold
        self.forceBoldBox = QCheckBox(self)
        self.forceBoldBox.setTristate()
        if forceBold is None:
            self.forceBoldBox.setCheckState(Qt.PartiallyChecked)
        else:
            self.forceBoldBox.setChecked(forceBold)

        hintingLayout.addWidget(blueFuzzLabel, l, 0)
        hintingLayout.addWidget(self.blueFuzzEdit, l, 1, 1, 2)
        hintingLayout.addWidget(stemSnapHLabel, l, 3)
        hintingLayout.addWidget(self.stemSnapHEdit, l, 4, 1, 2)
        l += 1
        hintingLayout.addWidget(blueScaleLabel, l, 0)
        hintingLayout.addWidget(self.blueScaleEdit, l, 1, 1, 2)
        hintingLayout.addWidget(stemSnapVLabel, l, 3)
        hintingLayout.addWidget(self.stemSnapVEdit, l, 4, 1, 2)
        l += 1
        hintingLayout.addWidget(blueShiftLabel, l, 0)
        hintingLayout.addWidget(self.blueShiftEdit, l, 1, 1, 2)
        hintingLayout.addWidget(forceBoldLabel, l, 3)
        hintingLayout.addWidget(self.forceBoldBox, l, 4, 1, 2)
        hintingGroup.setLayout(hintingLayout)

        metricsGroup = QGroupBox("Metrics", self)
        # metricsGroup.setFlat(True)
        metricsLayout = QGridLayout(self)

        defaultWidthXLabel = QLabel("DefaultWidthX:", self)
        if font.info.postscriptDefaultWidthX is not None:
            defaultWidthX = str(font.info.postscriptDefaultWidthX)
        else:
            defaultWidthX = ''
        self.defaultWidthXEdit = QLineEdit(defaultWidthX, self)
        self.defaultWidthXEdit.setValidator(QDoubleValidator(self))

        underlineThicknessLabel = QLabel("UnderlineThickness:", self)
        if font.info.postscriptUnderlineThickness is not None:
            underlineThickness = str(font.info.postscriptUnderlineThickness)
        else:
            underlineThickness = ''
        self.underlineThicknessEdit = QLineEdit(underlineThickness, self)
        self.underlineThicknessEdit.setValidator(QDoubleValidator(self))

        nominalWidthXLabel = QLabel("NominalWidthX:", self)
        if font.info.postscriptNominalWidthX is not None:
            nominalWidthX = str(font.info.postscriptNominalWidthX)
        else:
            nominalWidthX = ''
        self.nominalWidthXEdit = QLineEdit(nominalWidthX, self)
        self.nominalWidthXEdit.setValidator(QDoubleValidator(self))

        underlinePositionLabel = QLabel("UnderlinePosition:", self)
        if font.info.postscriptUnderlinePosition is not None:
            underlinePosition = str(font.info.postscriptUnderlinePosition)
        else:
            underlinePosition = ''
        self.underlinePositionEdit = QLineEdit(underlinePosition, self)
        self.underlinePositionEdit.setValidator(QDoubleValidator(self))

        slantAngleLabel = QLabel("SlantAngle:", self)
        if font.info.postscriptSlantAngle is not None:
            slantAngle = str(font.info.postscriptSlantAngle)
        else:
            slantAngle = ''
        self.slantAngleEdit = QLineEdit(slantAngle, self)
        self.slantAngleEdit.setValidator(QDoubleValidator(self))

        isFixedPitchLabel = QLabel("isFixedPitched:", self)
        isFixedPitch = font.info.postscriptIsFixedPitch
        self.isFixedPitchBox = QCheckBox(self)
        self.isFixedPitchBox.setTristate()
        if isFixedPitch is None:
            self.isFixedPitchBox.setCheckState(Qt.PartiallyChecked)
        else:
            self.isFixedPitchBox.setChecked(isFixedPitch)

        l = 0
        metricsLayout.addWidget(defaultWidthXLabel, l, 0)
        metricsLayout.addWidget(self.defaultWidthXEdit, l, 1, 1, 2)
        metricsLayout.addWidget(underlineThicknessLabel, l, 3)
        metricsLayout.addWidget(self.underlineThicknessEdit, l, 4, 1, 2)
        l += 1
        metricsLayout.addWidget(nominalWidthXLabel, l, 0)
        metricsLayout.addWidget(self.nominalWidthXEdit, l, 1, 1, 2)
        metricsLayout.addWidget(underlinePositionLabel, l, 3)
        metricsLayout.addWidget(self.underlinePositionEdit, l, 4, 1, 2)
        l += 1
        metricsLayout.addWidget(slantAngleLabel, l, 0)
        metricsLayout.addWidget(self.slantAngleEdit, l, 1, 1, 2)
        metricsLayout.addWidget(isFixedPitchLabel, l, 3)
        metricsLayout.addWidget(self.isFixedPitchBox, l, 4, 1, 2)
        metricsGroup.setLayout(metricsLayout)

        charactersGroup = QGroupBox("Characters", self)
        # charactersGroup.setFlat(True)
        charactersLayout = QGridLayout(self)

        defaultCharacterLabel = QLabel("Default character:", self)
        self.defaultCharacterEdit = QLineEdit(
            font.info.postscriptDefaultCharacter, self)

        windowsCharacterSetLabel = QLabel("Windows character set:", self)
        self.windowsCharacterSetDrop = QComboBox(self)
        items = [
            "None", "ANSI", "Default", "Symbol", "Macintosh", "Shift JIS",
            "Hangul", "Hangul (Johab)", "GB2312", "Chinese BIG5", "Greek",
            "Turkish", "Vietnamese", "Hebrew", "Arabic", "Baltic", "Bitstream",
            "Cyrillic", "Thai", "Eastern European", "OEM"]
        self.windowsCharacterSetDrop.insertItems(0, items)
        if font.info.postscriptWindowsCharacterSet is not None:
            self.windowsCharacterSetDrop.setCurrentIndex(
                font.info.postscriptWindowsCharacterSet)

        l = 0
        charactersLayout.addWidget(defaultCharacterLabel, l, 0)
        charactersLayout.addWidget(self.defaultCharacterEdit, l, 1, 1, 2)
        charactersLayout.addWidget(windowsCharacterSetLabel, l, 3)
        charactersLayout.addWidget(self.windowsCharacterSetDrop, l, 4, 1, 2)
        charactersGroup.setLayout(charactersLayout)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(namingGroup)
        mainLayout.addWidget(hintingGroup)
        mainLayout.addWidget(metricsGroup)
        mainLayout.addWidget(charactersGroup)
        self.setLayout(mainLayout)

    def writeValues(self, font):
        fontName = self.fontNameEdit.text()
        if fontName != '':
            font.info.postscriptFontName = fontName
        else:
            font.info.postscriptFontName = None
        fullName = self.fullNameEdit.text()
        if fullName != '':
            font.info.postscriptFullName = fullName
        else:
            font.info.postscriptFullName = None
        weightName = self.weightNameEdit.text()
        if weightName != '':
            font.info.postscriptWeightName = weightName
        else:
            font.info.postscriptWeightName = None
        uniqueID = self.uniqueIDEdit.text()
        if uniqueID != '':
            font.info.postscriptUniqueID = int(uniqueID)
        else:
            font.info.postscriptUniqueID = None
        blueValues = self.blueValuesEdit.text().split(" ")
        if blueValues is None:
            font.info.postscriptBlueValues = None
        else:
            blues = []
            for blue in blueValues:
                if blue != '':
                    blues.append(int(blue))
            font.info.postscriptBlueValues = blues
        otherBlues = self.otherBluesEdit.text().split(" ")
        if otherBlues is None:
            font.info.postscriptOtherBlues = None
        else:
            blues = []
            for blue in otherBlues:
                if blue != '':
                    blues.append(int(blue))
            font.info.postscriptOtherBlues = blues
        familyBlues = self.familyBluesEdit.text().split(" ")
        if familyBlues is None:
            font.info.postscriptFamilyBlues = None
        else:
            blues = []
            for blue in familyBlues:
                if blue != '':
                    blues.append(int(blue))
            font.info.postscriptFamilyBlues = blues
        familyOtherBlues = self.familyOtherBluesEdit.text().split(" ")
        if familyOtherBlues is None:
            font.info.postscriptFamilyOtherBlues = None
        else:
            blues = []
            for blue in familyOtherBlues:
                if blue != '':
                    blues.append(int(blue))
            font.info.postscriptFamilyOtherBlues = blues
        blueFuzz = self.blueFuzzEdit.text()
        if "." in blueFuzz:
            font.info.postscriptBlueFuzz = float(blueFuzz)
        elif blueFuzz != '':
            font.info.postscriptBlueFuzz = int(blueFuzz)
        else:
            font.info.postscriptBlueFuzz = None
        blueScale = self.blueScaleEdit.text()
        if blueScale != '':
            font.info.postscriptBlueScale = float(blueScale)
        else:
            font.info.postscriptBlueScale = None
        blueShift = self.blueShiftEdit.text()
        if "." in blueShift:
            font.info.postscriptBlueShift = float(blueShift)
        elif blueShift != '':
            font.info.postscriptBlueShift = int(blueShift)
        else:
            font.info.postscriptBlueShift = None
        stemSnapH = self.stemSnapHEdit.text().split(" ")
        if stemSnapH is None:
            font.info.postscriptStemSnapH = None
        else:
            stems = []
            for stem in stemSnapH:
                if stem != '':
                    stems.append(int(stem))
            font.info.postscriptStemSnapH = stems
        stemSnapV = self.stemSnapVEdit.text().split(" ")
        if stemSnapV is None:
            font.info.postscriptStemSnapV = None
        else:
            stems = []
            for stem in stemSnapV:
                if stem != '':
                    stems.append(int(stem))
            font.info.postscriptStemSnapV = stems
        forceBold = self.forceBoldBox.checkState()
        if forceBold == Qt.PartiallyChecked:
            font.info.postscriptForceBold = None
        else:
            font.info.postscriptForceBold = bool(forceBold)
        defaultWidthX = self.defaultWidthXEdit.text()
        if "." in defaultWidthX:
            font.info.postscriptDefaultWidthX = float(defaultWidthX)
        elif defaultWidthX != '':
            font.info.postscriptDefaultWidthX = int(defaultWidthX)
        else:
            font.info.postscriptDefaultWidthX = None
        nominalWidthX = self.nominalWidthXEdit.text()
        if "." in nominalWidthX:
            font.info.postscriptNominalWidthX = float(nominalWidthX)
        elif nominalWidthX != '':
            font.info.postscriptNominalWidthX = int(nominalWidthX)
        else:
            font.info.postscriptNominalWidthX = None
        underlineThickness = self.underlineThicknessEdit.text()
        if "." in underlineThickness:
            font.info.postscriptUnderlineThickness = float(underlineThickness)
        elif underlineThickness != '':
            font.info.postscriptUnderlineThickness = \
                int(underlineThickness)
        else:
            font.info.postscriptUnderlineThickness = None
        underlinePosition = self.underlinePositionEdit.text()
        if "." in underlinePosition:
            font.info.postscriptUnderlinePosition = float(underlinePosition)
        elif underlinePosition != '':
            font.info.postscriptUnderlinePosition = int(underlinePosition)
        else:
            font.info.postscriptUnderlinePosition = None
        slantAngle = self.slantAngleEdit.text()
        if "." in slantAngle:
            font.info.postscriptSlantAngle = float(slantAngle)
        elif slantAngle != '':
            font.info.postscriptSlantAngle = int(slantAngle)
        else:
                font.info.postscriptSlantAngle = None
        isFixedPitch = self.isFixedPitchBox.checkState()
        if isFixedPitch == Qt.PartiallyChecked:
            font.info.postscriptIsFixedPitch = None
        else:
            font.info.postscriptIsFixedPitch = bool(isFixedPitch)
        defaultCharacter = self.defaultCharacterEdit.text()
        if defaultCharacter != '':
            font.info.postscriptDefaultCharacter = defaultCharacter
        else:
            font.info.postscriptDefaultCharacter = None
        windowsCharacterSet = self.windowsCharacterSetDrop.currentIndex()
        if windowsCharacterSet == 0:
            font.info.postscriptWindowsCharacterSet = None
        else:
            font.info.postscriptWindowsCharacterSet = windowsCharacterSet
Esempio n. 19
0
class LayerControl(QWidget):
    """
    Custom LayerControl widget.

    Constructor:

        ipc = LayerControl('test title')

    Events:

        .change   the contents were changed
        .remove   the image should be removed

    The '.change' event has attached attributes holding the values from the
    widget, all checked so they are 'sane'.
    """

    # various sizes
    ButtonWidth = 40
    ButtonHeight = 40
    ComboboxWidth = 70

    # signals raised by this widget
    change = pyqtSignal(str, int, QColor, QColor, bool, bool, int, int)
    remove = pyqtSignal()

    # some stylesheets
    LabelStyle = 'QLabel { background-color : #f0f0f0; border: 1px solid gray; border-radius: 3px; }'
    GroupStyle = ('QGroupBox { background-color: rgb(230, 230, 230); }'
                  'QGroupBox::title { subcontrol-origin: margin; '
                  'background-color: rgb(215, 215, 215); '
                  'border-radius: 3px; '
                  'padding: 2 2px; '
                  'color: black; }')
    ButtonStyle = ('QPushButton {'
                   'margin: 1px;'
                   'border-color: #0c457e;'
                   'border-style: outset;'
                   'border-radius: 3px;'
                   'border-width: 1px;'
                   'color: black;'
                   'background-color: white;'
                   '}')
    ButtonColourStyle = ('QPushButton {'
                         'margin: 1px;'
                         'border-color: #0c457e;'
                         'border-style: outset;'
                         'border-radius: 3px;'
                         'border-width: 1px;'
                         'color: black;'
                         'background-color: %s;'
                         '}')

    def __init__(self,
                 title,
                 placement=DefaultPlacement,
                 width=DefaultWidth,
                 closed=DefaultClosed,
                 filled=DefaultFilled,
                 colour=DefaultColour,
                 fillcolour=DefaultFillColour,
                 offset_x=0,
                 offset_y=0):
        """Initialise a LayerControl instance.

        title        text to show in static box outline around control
        placement    placement string for object
        width        width in pixels of the drawn polygon
        colour       sets the colour of the polygon outline
        closed       True if the polygon is to be forcibly closed
        filled       True if the polygon is to be filled
        fillcolour   the colour to fill the polygon with (if filled is True)
        offset_x     X offset of object
        offset_y     Y offset of object
        """

        super().__init__()

        # save parameters
        self.v_placement = placement
        self.v_width = width
        self.v_colour = colour
        self.v_closed = closed
        self.v_filled = filled
        self.v_fillcolour = fillcolour
        self.v_offset_x = offset_x
        self.v_offset_y = offset_y

        # create subwidgets used in this custom widget
        self.placement = QComboBox()
        for p in [
                'none', 'nw', 'cn', 'ne', 'ce', 'se', 'cs', 'sw', 'cw', 'cc'
        ]:
            self.placement.addItem(p)
        self.placement.setCurrentIndex(9)

        self.line_width = QComboBox()
        for p in range(21):
            self.line_width.addItem(str(p))
        self.line_width.setCurrentIndex(3)
        self.line_width.setFixedWidth(LayerControl.ComboboxWidth)

        self.line_colour = QPushButton('')
        self.line_colour.setFixedWidth(LayerControl.ButtonWidth)
        self.line_colour.setToolTip('Click here to change the point colour')
        self.line_colour.setStyleSheet(LayerControl.ButtonStyle)

        self.fill_colour = QPushButton('')
        self.fill_colour.setFixedWidth(LayerControl.ButtonWidth)
        self.fill_colour.setToolTip('Click here to change the fill colour')
        self.fill_colour.setStyleSheet(LayerControl.ButtonStyle)

        self.cb_closed = QCheckBox('closed: ', self)
        self.cb_filled = QCheckBox('filled: ', self)

        self.x_offset = QComboBox()
        for p in range(0, 121, 10):
            self.x_offset.addItem(str(p - 60))
        self.x_offset.setCurrentIndex(6)
        self.x_offset.setFixedWidth(LayerControl.ComboboxWidth)

        self.y_offset = QComboBox()
        for p in range(0, 121, 10):
            self.y_offset.addItem(str(p - 60))
        self.y_offset.setCurrentIndex(6)
        self.y_offset.setFixedWidth(LayerControl.ComboboxWidth)

        btn_remove = QPushButton('Remove')
        btn_remove.resize(btn_remove.sizeHint())

        btn_update = QPushButton('Update')
        btn_update.resize(btn_update.sizeHint())

        # start the layout
        option_box = QGroupBox(title)
        option_box.setStyleSheet(LayerControl.GroupStyle)

        box_layout = QGridLayout()
        box_layout.setContentsMargins(2, 2, 2, 2)
        box_layout.setHorizontalSpacing(1)
        box_layout.setColumnStretch(0, 1)

        # start layout
        row = 1
        label = QLabel('placement: ')
        label.setAlignment(Qt.AlignRight)
        box_layout.addWidget(label, row, 0)
        box_layout.addWidget(self.placement, row, 1)
        label = QLabel('width: ')
        label.setAlignment(Qt.AlignRight)
        box_layout.addWidget(label, row, 2)
        box_layout.addWidget(self.line_width, row, 3)

        row += 1
        label = QLabel('colour: ')
        label.setAlignment(Qt.AlignRight)
        box_layout.addWidget(label, row, 0)
        box_layout.addWidget(self.line_colour, row, 1)
        label = QLabel('fill colour: ')
        label.setAlignment(Qt.AlignRight)
        box_layout.addWidget(label, row, 2)
        box_layout.addWidget(self.fill_colour, row, 3)

        row += 1
        label = QLabel('filled: ')
        label.setAlignment(Qt.AlignRight)
        box_layout.addWidget(label, row, 2)
        box_layout.addWidget(self.cb_filled, row, 3)

        row += 1
        label = QLabel('offset X: ')
        label.setAlignment(Qt.AlignRight)
        box_layout.addWidget(label, row, 0)
        box_layout.addWidget(self.x_offset, row, 1)
        label = QLabel('Y: ')
        label.setAlignment(Qt.AlignRight)
        box_layout.addWidget(label, row, 2)
        box_layout.addWidget(self.y_offset, row, 3)

        row += 1
        box_layout.addWidget(btn_remove, row, 1)
        box_layout.addWidget(btn_update, row, 3)

        option_box.setLayout(box_layout)

        layout = QHBoxLayout()
        layout.setContentsMargins(1, 1, 1, 1)
        layout.addWidget(option_box)

        self.setLayout(layout)

        # set size hints
        self.setMinimumSize(300, 200)
        size_policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.setSizePolicy(size_policy)

        # connect internal widget events to handlers
        self.line_colour.clicked.connect(self.changeLineColour)
        self.fill_colour.clicked.connect(self.changeFillColour)
        btn_remove.clicked.connect(self.removeImage)
        btn_update.clicked.connect(self.updateData)

    def changeLineColour(self, event):
        color = QColorDialog.getColor()
        if color.isValid():
            colour = color.name()
            # set colour button background
            self.line_colour.setStyleSheet(LayerControl.ButtonColourStyle %
                                           colour)

    def changeFillColour(self, event):
        color = QColorDialog.getColor()
        if color.isValid():
            colour = color.name()
            # set colour button background
            self.fill_colour.setStyleSheet(LayerControl.ButtonColourStyle %
                                           colour)

    def removeImage(self, event):
        self.remove.emit()

    def updateData(self, event):
        # get data from the widgets
        placement = str(self.placement.currentText())
        if placement == 'none':
            placement = None
        line_width = int(self.line_width.currentText())
        line_colour = self.line_colour.palette().color(1)
        fill_colour = self.fill_colour.palette().color(1)
        closed = self.cb_closed.checkState()
        filled = self.cb_filled.checkState()
        x_offset = int(self.x_offset.currentText())
        y_offset = int(self.y_offset.currentText())

        print(
            f'updateData: placement={placement}, line_width={line_width}, closed={closed}, filled={filled}, x_offset={x_offset}, y_offset={y_offset}'
        )

        self.change.emit(placement, line_width, line_colour, fill_colour,
                         closed, filled, x_offset, y_offset)
Esempio n. 20
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        browseNetwork1Button = self.createButton(_('Browse'),
                self.browseNetwork1File)
        browseNetwork2Button = self.createButton(_('Browse'),
                self.browseNetwork2File)
        browseNetworkMappingButton = self.createButton(_('Browse'),
                self.browseNetworkMappingFile)
        browseList1Button = self.createButton(_('Browse'),
                self.browseList1File)
        browseList2Button = self.createButton(_('Browse'),
                self.browseList2File)
        browseTrueMapButton = self.createButton(_('Browse'),
                self.browseTrueMapFile)
        browseNetworkFlatButton = self.createButton(_('Browse'),
                self.browseNetworkFlatFile)
        generateNetworkFlatButton = self.createButton(
            _('Generate flat network'), self.genFlatNetwork)
        userLinkButton = self.createButton(
            _("Link user"), self.userLink)

        self.network1PathComboBox = self.createComboBox()
        self.network2PathComboBox = self.createComboBox()
        self.networkMappingPathComboBox = self.createComboBox()
        self.networkFlatPathComboBox = self.createComboBox()
        self.sampleUser1PathComboBox = self.createComboBox()
        self.sampleUser2PathComboBox = self.createComboBox()
        self.trueMapPathComboBox = self.createComboBox()
        self.delimiterComboBox = self.createComboBox('\\t')
        self.delimiterComboBox.addItem(',')
        self.bfsLevelComboBox = self.createComboBox('2')
        self.bfsLevelComboBox.addItem('3')
        self.bfsLevelComboBox.addItem('4')
        self.bfsLevelComboBox.addItem('5')

        network1Label = QLabel(_('Network 1:'))
        network2Label = QLabel(_('Network 2:'))
        networkMappingLabel = QLabel(_('Network mapping:'))
        sampleUser1Label = QLabel(_("Sample user list 1:"))
        sampleUser2Label = QLabel(_("Sample user list 2:"))
        trueMapLabel = QLabel(_("True map: "))
        networkFlatLabel = QLabel(_('Flat network:'))
        delimiterLabel = QLabel(_('CSV delimiter:'))
        bfsLevelLabel = QLabel(_('BFS level:'))
        
        self.infoCheckBox = QCheckBox(_('Info'))
        self.infoCheckBox.setCheckState(True)
        self.warnCheckBox = QCheckBox(_('Warn'))
        self.warnCheckBox.setCheckState(True)
        self.fatalCheckBox = QCheckBox(_('Fatal'))
        self.fatalCheckBox.setCheckState(True)
        self.importantCheckBox = QCheckBox(_('Important'))
        self.importantCheckBox.setCheckState(True)
        self.verboseCheckBox = QCheckBox(_('Verbose'))
        

        self.logTextBox = self.createLogBox()

        mainLayout = QGridLayout()
        mainLayout.setContentsMargins(5, 5, 5, 5)

        mainLayout.addWidget(network1Label, 0, 0)
        mainLayout.addWidget(self.network1PathComboBox, 0, 1, 1, 4)
        mainLayout.addWidget(browseNetwork1Button, 0, 5, 1, 2)

        mainLayout.addWidget(network2Label, 1, 0)
        mainLayout.addWidget(self.network2PathComboBox, 1, 1, 1, 4)
        mainLayout.addWidget(browseNetwork2Button, 1, 5, 1, 2)

        mainLayout.addWidget(networkMappingLabel, 2, 0)
        mainLayout.addWidget(self.networkMappingPathComboBox, 2, 1, 1, 4)
        mainLayout.addWidget(browseNetworkMappingButton, 2, 5, 1, 2)
        
        mainLayout.addWidget(sampleUser1Label, 3, 0)
        mainLayout.addWidget(self.sampleUser1PathComboBox, 3, 1, 1, 4)
        mainLayout.addWidget(browseList1Button, 3, 5, 1, 2)
        
        mainLayout.addWidget(sampleUser2Label, 4, 0)
        mainLayout.addWidget(self.sampleUser2PathComboBox, 4, 1, 1, 4)
        mainLayout.addWidget(browseList2Button, 4, 5, 1, 2)
        
        mainLayout.addWidget(trueMapLabel, 5, 0)
        mainLayout.addWidget(self.trueMapPathComboBox, 5, 1, 1, 4)
        mainLayout.addWidget(browseTrueMapButton, 5, 5, 1, 2)

        mainLayout.addWidget(networkFlatLabel, 6, 0)
        mainLayout.addWidget(self.networkFlatPathComboBox, 6, 1, 1, 4)
        mainLayout.addWidget(browseNetworkFlatButton, 6, 5, 1, 2)

        mainLayout.addWidget(delimiterLabel, 7, 0, 1, 1)
        mainLayout.addWidget(self.delimiterComboBox, 7, 1, 1, 1)
        mainLayout.addWidget(bfsLevelLabel, 7, 2, 1, 1)
        mainLayout.addWidget(self.bfsLevelComboBox , 7, 3, 1, 2)
        mainLayout.addWidget(generateNetworkFlatButton, 7, 5, 1, 2)

        mainLayout.addWidget(userLinkButton, 7, 7, 1, 2)
        
        mainLayout.addWidget(self.infoCheckBox, 8, 0, 1, 1)
        mainLayout.addWidget(self.warnCheckBox, 8, 1, 1, 1)
        mainLayout.addWidget(self.fatalCheckBox, 8, 2, 1, 1)
        mainLayout.addWidget(self.importantCheckBox, 8, 3, 1, 1)
        mainLayout.addWidget(self.verboseCheckBox, 8, 4, 1, 1)

        mainLayout.addWidget(self.logTextBox, 9, 0, 5, 7)

        widget = QWidget()
        self.setCentralWidget(widget)
        widget.setLayout(mainLayout)

        self.createActions()
        self.createMenus()

        self.setWindowTitle(_('Flat network user relationship tool'))

    @staticmethod
    def updateComboBox(comboBox):
        if comboBox.findText(comboBox.currentText()) == -1:
            comboBox.addItem(comboBox.currentText())

    def createActions(self):
        self.englishAct = QAction("&English", self, triggered =
                self.switchToEnglish)

        self.chineseAct = QAction("简体中文", self, triggered =
                self.switchToChinese)

    def createMenus(self):
        self.langMenu = self.menuBar().addMenu(_("&Language"))
        self.langMenu.addAction(self.englishAct)
        self.langMenu.addAction(self.chineseAct)

    def switchToEnglish(self):
        gConfigure['lang'] = 'en'
        SaveConfigure()

    def switchToChinese(self):
        gConfigure['lang'] = 'zh'
        SaveConfigure()

    def browseNetwork1File(self):
        fileNetwork1Path = QFileDialog.getOpenFileName(
                self, _('Network 1 CSV File'),
                QDir.currentPath(), 'Comma-separated values (*.csv)')

        if fileNetwork1Path:
            if self.network1PathComboBox.findText(
                    fileNetwork1Path[0]) == -1:
                self.network1PathComboBox.addItem(fileNetwork1Path[0])

            self.network1PathComboBox.setCurrentIndex(
                    self.network1PathComboBox.findText(fileNetwork1Path[0]))

    def browseNetwork2File(self):
        fileNetwork2Path = QFileDialog.getOpenFileName(
                self, _('Network 2 CSV File'),
                QDir.currentPath(), 'Comma-separated values (*.csv)')

        if fileNetwork2Path:
            if self.network2PathComboBox.findText(fileNetwork2Path[0]) == -1:
                self.network2PathComboBox.addItem(fileNetwork2Path[0])

            self.network2PathComboBox.setCurrentIndex(
                    self.network2PathComboBox.findText(fileNetwork2Path[0]))
    
    def browseList1File(self):
        list1FilePath = QFileDialog.getOpenFileName(
                self, _('Sample user list 1 CSV File'),
                QDir.currentPath(), 'Comma-separated values (*.csv)')

        if list1FilePath:
            if self.sampleUser1PathComboBox.findText(list1FilePath[0]) == -1:
                self.sampleUser1PathComboBox.addItem(list1FilePath[0])

            self.sampleUser1PathComboBox.setCurrentIndex(
                    self.sampleUser1PathComboBox.findText(list1FilePath[0]))
    
    def browseList1File(self):
        list1FilePath = QFileDialog.getOpenFileName(
                self, _('Sample user list 1 CSV File'),
                QDir.currentPath(), 'Comma-separated values (*.csv)')

        if list1FilePath:
            if self.sampleUser1PathComboBox.findText(list1FilePath[0]) == -1:
                self.sampleUser1PathComboBox.addItem(list1FilePath[0])

            self.sampleUser1PathComboBox.setCurrentIndex(
                    self.sampleUser1PathComboBox.findText(list1FilePath[0]))
    
    def browseList2File(self):
        list2FilePath = QFileDialog.getOpenFileName(
                self, _('Sample user list 2 CSV File'),
                QDir.currentPath(), 'Comma-separated values (*.csv)')

        if list2FilePath:
            if self.sampleUser2PathComboBox.findText(list2FilePath[0]) == -1:
                self.sampleUser2PathComboBox.addItem(list2FilePath[0])

            self.sampleUser2PathComboBox.setCurrentIndex(
                    self.sampleUser2PathComboBox.findText(list2FilePath[0]))
    
    def browseTrueMapFile(self):
        trueMapFilePath = QFileDialog.getOpenFileName(
                self, _('True mapping CSV File'),
                QDir.currentPath(), 'Comma-separated values (*.csv)')

        if trueMapFilePath:
            if self.trueMapPathComboBox.findText(trueMapFilePath[0]) == -1:
                self.trueMapPathComboBox.addItem(trueMapFilePath[0])

            self.trueMapPathComboBox.setCurrentIndex(
                    self.trueMapPathComboBox.findText(trueMapFilePath[0]))

    def browseNetworkMappingFile(self):
        fileNetworkMappingPath = QFileDialog.getOpenFileName(
                self, _('Network Mapping CSV File'),
                QDir.currentPath(), 'Comma-separated values (*.csv)')

        if fileNetworkMappingPath:
            if self.networkMappingPathComboBox.findText(
                    fileNetworkMappingPath[0]) == -1:
                self.networkMappingPathComboBox.addItem(
                        fileNetworkMappingPath[0])

            self.networkMappingPathComboBox.setCurrentIndex(
                    self.networkMappingPathComboBox.findText(
                        fileNetworkMappingPath[0]))

    def browseNetworkFlatFile(self):
        fileNetworkFlatPath = QFileDialog.getSaveFileName(
                self, _('Flat Network CSV File'),
                QDir.currentPath(), 'Comma-separated values (*.csv)')

        if fileNetworkFlatPath:
            if self.networkFlatPathComboBox.findText(
                    fileNetworkFlatPath[0]) == -1:
                self.networkFlatPathComboBox.addItem(
                        fileNetworkFlatPath[0])

            self.networkFlatPathComboBox.setCurrentIndex(
                    self.networkFlatPathComboBox.findText(
                        fileNetworkFlatPath[0]))

    def createButton(self, text, member):
        button = QPushButton(text)
        button.clicked.connect(member)
        return button

    def createComboBox(self, text=""):
        comboBox = QComboBox()
        comboBox.setEditable(True)
        comboBox.addItem(text)
        comboBox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        return comboBox

    def createLogBox(self):
        logTextBox = QPlainTextEdit()
        logTextBox.setReadOnly(True)
        logTextBox.setMaximumBlockCount(100)
        logTextBox.setCenterOnScroll(True)
        return logTextBox

    def insertLog(self, logline=''):
        self.logTextBox.appendPlainText(logline)
        self.updateInterface()

    def getFilePath(self):
        filePath = {}
        filePath['FirstNetFile'] = self.network1PathComboBox.currentText()
        filePath['SecondNetFile'] = self.network2PathComboBox.currentText()
        filePath['NodeMappingFile'] = self.networkMappingPathComboBox.currentText()
        filePath['OutputFile'] = self.networkFlatPathComboBox.currentText()
        filePath['TrueMapFile'] = self.trueMapPathComboBox.currentText()

        return filePath

    def getDelimiter(self):
        delimiter = self.delimiterComboBox.currentText()
        if delimiter == '\\t':
            delimiter = '\t'

        return delimiter
    
    def getSampleFilePath(self):
        sampleFilePath = {}
        sampleFilePath["first"] = self.sampleUser1PathComboBox.currentText()
        sampleFilePath["second"] = self.sampleUser2PathComboBox.currentText()
        
        return sampleFilePath

    def genFlatNetwork(self):
        filePath = self.getFilePath()
        delimiter = self.self.getDelimiter()

        bfsLevel = self.bfsLevelComboBox.currentText()
        if not bfsLevel.isdigit():
            bfsLevel = 2

        Network.GenerateSubNetwork(filePath, delimiter, bfsLevel)

    def userLink(self):
        filePath = self.getFilePath()
        delimiter = self.getDelimiter()
        sampleFilePath = self.getSampleFilePath()
        
        Guess.DoUserLink(filePath, sampleFilePath, delimiter)

    def updateInterface(self):
        QApplication.processEvents()
        
    def getIsInfoLog(self):
        return self.infoCheckBox.checkState()
    
    def getIsWarnLog(self):
        return self.warnCheckBox.checkState()
    
    def getIsFatalLog(self):
        return self.fatalCheckBox.checkState()
    
    def getIsImportantLog(self):
        return self.importantCheckBox.checkState()
    
    def getIsVerboseLog(self):
        return self.verboseCheckBox.checkState()
Esempio n. 21
0
class Example(QWidget):
    def __init__(self):
        '''
        一些初始设置
        '''
        super().__init__()
        self.initUI()

    def initUI(self):
        '''
        界面初始设置
        '''
        self.cb1 = QCheckBox('全选', self)
        self.cb2 = QCheckBox('你是', self)
        self.cb3 = QCheckBox('我的', self)
        self.cb4 = QCheckBox('宝贝', self)

        bt = QPushButton('提交', self)

        self.resize(300, 200)
        self.setWindowTitle('关注微信公众号:学点编程吧--复选框')

        self.cb1.move(20, 20)
        self.cb2.move(30, 50)
        self.cb3.move(30, 80)
        self.cb4.move(30, 110)

        bt.move(20, 160)

        self.cb1.stateChanged.connect(self.changecb1)
        self.cb2.stateChanged.connect(self.changecb2)
        self.cb3.stateChanged.connect(self.changecb2)
        self.cb4.stateChanged.connect(self.changecb2)
        bt.clicked.connect(self.go)

        self.show()

    def go(self):
        '''
        复选框选择状态提交后看看你能输出什么
        '''
        if self.cb2.isChecked() and self.cb3.isChecked(
        ) and self.cb4.isChecked():
            QMessageBox.information(self, 'I Love U', '你是我的宝贝!')
        elif self.cb2.isChecked() and self.cb3.isChecked():
            QMessageBox.information(self, 'I Love U', '你是我的!')
        elif self.cb2.isChecked() and self.cb4.isChecked():
            QMessageBox.information(self, 'I Love U', '你是宝贝!')
        elif self.cb3.isChecked() and self.cb4.isChecked():
            QMessageBox.information(self, 'I Love U', '我的宝贝!')
        elif self.cb2.isChecked():
            QMessageBox.information(self, 'I Love U', '你是!')
        elif self.cb3.isChecked():
            QMessageBox.information(self, 'I Love U', '我的!')
        elif self.cb4.isChecked():
            QMessageBox.information(self, 'I Love U', '宝贝!')
        else:
            QMessageBox.information(self, 'I Love U', '貌似你没有勾选啊!')

    def changecb1(self):
        '''
        复选框cb1全选和反选
        '''
        if self.cb1.checkState() == Qt.Checked:
            self.cb2.setChecked(True)
            self.cb3.setChecked(True)
            self.cb4.setChecked(True)
        elif self.cb1.checkState() == Qt.Unchecked:
            self.cb2.setChecked(False)
            self.cb3.setChecked(False)
            self.cb4.setChecked(False)

    def changecb2(self):
        '''
        复选框cb2、cb3、cb4不同状态时,cb1状态的变化
        '''
        if self.cb2.isChecked() and self.cb3.isChecked(
        ) and self.cb4.isChecked():
            self.cb1.setCheckState(Qt.Checked)  #复选框cb2、cb3、cb4全选时,cb1状态是全选
        elif self.cb2.isChecked() or self.cb3.isChecked(
        ) or self.cb4.isChecked():
            self.cb1.setTristate(True)
            self.cb1.setCheckState(
                Qt.PartiallyChecked)  #复选框cb2、cb3、cb4有一个被选中时,cb1状态是半选
        else:
            self.cb1.setTristate(False)  #必须设置否,否则cb1会出现半选状态。
            self.cb1.setCheckState(Qt.Unchecked)  #复选框cb2、cb3、cb4其他状态时,cb1状态是半选
Esempio n. 22
0
    def initUI(self):
        StoryTypeGroupBox = QGroupBox()
        StoryTypeLayer = FlowLayout()
        for key in WdStoryType.keys():
            widget = QCheckBox(WdStoryType[key][1] if WdStoryType[key][1] != "" else WdStoryType[key][0])
            widget.setObjectName("WdStoryType." + str(key))
            widget.setCheckState(WdStoryType[key][2])
            widget.setEnabled(widget.checkState() != 1)
            widget.setMinimumWidth(230)
            StoryTypeLayer.addWidget(widget)
            self.StoryTypeList.append(widget)
        StoryTypeGroupBox.setLayout(StoryTypeLayer)

        InlineShapeTypeGroupBox = QGroupBox()
        InlineShapeTypeLayer = FlowLayout()
        for key in WdInlineShapeType.keys():
            widget = QCheckBox(
                WdInlineShapeType[key][1] if WdInlineShapeType[key][1] != "" else WdInlineShapeType[key][0]
            )
            widget.setObjectName("WdInlineShapeType." + str(key))
            widget.setCheckState(WdInlineShapeType[key][2])
            widget.setEnabled(widget.checkState() != 1)
            widget.setMinimumWidth(230)
            InlineShapeTypeLayer.addWidget(widget)
            self.InlineShapeList.append(widget)
        InlineShapeTypeGroupBox.setLayout(InlineShapeTypeLayer)

        ShapeTypeGroupBox = QGroupBox()
        ShapeTypeLayer = FlowLayout()
        for key in MsoShapeType.keys():
            widget = QCheckBox(MsoShapeType[key][1] if MsoShapeType[key][1] != "" else MsoShapeType[key][0])
            widget.setObjectName("MsoShapeType." + str(key))
            widget.setCheckState(MsoShapeType[key][2])
            widget.setEnabled(widget.checkState() != 1)
            widget.setMinimumWidth(230)
            ShapeTypeLayer.addWidget(widget)
            self.ShapeTypeList.append(widget)
        ShapeTypeGroupBox.setLayout(ShapeTypeLayer)

        """TabWidget=QTabWidget()
        TabWidget.addTab(StoryTypeGroupBox,"StoryType")
        TabWidget.addTab(InlineShapeTypeGroupBox,"InlineShapeType")
        TabWidget.addTab(ShapeTypeGroupBox,"ShapeType")
        TabWidget.setCurrentIndex(0)"""
        TabWidget = QToolBox()
        TabWidget.addItem(StoryTypeGroupBox, "StoryType")
        TabWidget.addItem(InlineShapeTypeGroupBox, "InlineShapeType")
        TabWidget.addItem(ShapeTypeGroupBox, "ShapeType")
        TabWidget.setCurrentIndex(0)

        hbox = QVBoxLayout()
        hbox.addWidget(TabWidget)

        btnGrp = QDialogButtonBox()
        btnClose = QPushButton("Закрыть")
        # btnApply=QPushButton("Применить")
        btnGrp.addButton(btnClose, QDialogButtonBox.ActionRole)
        # btnGrp.addButton(btnApply,QDialogButtonBox.ActionRole)
        hbox.addWidget(btnGrp)

        btnClose.clicked.connect(self.close)
        # btnApply.clicked.connect(self.apply)
        self.apply()
        self.setLayout(hbox)
        self.setGeometry(500, 100, 500, 400)
        self.setWindowTitle("Опции")
        self.setWindowFlags(Qt.Dialog | Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
Esempio n. 23
0
class StartPos(QWidget):

    signal_modified = pyqtSignal(object)
    signal_selected_changed = pyqtSignal(object)
    signal_delete = pyqtSignal(object)
    all_selected = set()

    def __init__(self, x, y, w, *args, **kwargs):
        super(StartPos, self).__init__(*args, **kwargs)

        self.is_selected = False

        self.widget_show = QCheckBox(self)
        self.widget_x = QDoubleSpinBox(self)
        self.widget_y = QDoubleSpinBox(self)
        self.widget_w = QDoubleSpinBox(self)
        self.widgets = [
            self.widget_show, self.widget_x, self.widget_y, self.widget_w
        ]

        # init chckbox show
        self.widget_show.setCheckState(Qt.Checked)

        # create editable fields
        for widget in self.widgets[1:]:
            widget.setDecimals(3)
            widget.setMinimum(-10000 if widget != self.widget_w else -np.pi)
            widget.setMaximum(10000 if widget != self.widget_w else np.pi)
            widget.setFrame(False)
            widget.setSingleStep(0.01)
            widget.setAlignment(Qt.AlignCenter)

        self.widget_x.setValue(x)
        self.widget_y.setValue(y)
        self.widget_w.setValue(w)

        # connect signals and slots
        self.widget_show.stateChanged.connect(self.object_changed)
        for widget in self.widgets[1:]:
            widget.valueChanged.connect(self.object_changed)

    def x(self):
        return self.widget_x.value()

    def y(self):
        return self.widget_y.value()

    def w(self):
        return self.widget_w.value()

    def translate(self, vector):
        self.widget_x.setValue(self.x() + vector.x())
        self.widget_y.setValue(self.y() + vector.y())
        self.object_changed()

    def setSelected(self, new_val: bool):
        # check if value changed
        if new_val != self.is_selected:

            # add or remove from selected set
            if new_val:
                StartPos.all_selected.add(self)
            elif self in StartPos.all_selected:
                StartPos.all_selected.remove(self)

            # set new value and signal
            self.is_selected = new_val
            self.signal_selected_changed.emit(self)

    def selected(self):
        return self.is_selected

    def is_hidden(self):
        return self.widget_show.checkState() == Qt.Unchecked

    def object_changed(self):
        self.signal_modified.emit(self)

    @staticmethod
    def clear_all_selected():
        aux = StartPos.all_selected
        StartPos.all_selected = set()
        for pc in aux:
            pc.setSelected(False)

    def delete(self):
        if self in StartPos.all_selected:
            StartPos.all_selected.remove(self)
        self.signal_delete.emit(self)

    def xml_tag(self):
        return f'<pos x="{self.x()}" y="{self.y()}" w="{self.w()}" />'

    def __str__(self):
        return f'{self.x():9.3f}, {self.y():9.3f}, {self.w():9.3f}'

    @staticmethod
    def fromstring(s):
        args = np.fromstring(s.replace('[', '').replace(']', ''), sep=",")
        if len(args) == 3:
            return StartPos(args[0], args[1], args[2])
        else:
            print('PC parse error')
            return None

    def pickable(self):
        return PickableStartPos(self.x(), self.y(), self.w())

    def __eq__(self, pos):
        return abs(self.x() - pos.x()) < 0.001 and abs(self.y() -
                                                       pos.y()) < 0.001

    __hash__ = QWidget.__hash__
Esempio n. 24
0
class dig_edit_conversation(QWidget):  # 編輯對話
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        client = MongoClient("127.0.0.1", 27017)
        db = client.gossip
        self.collection = db.sentences

        self.main_layout = QVBoxLayout()

        situation_widget = QFormLayout()
        self.select_layout = QHBoxLayout()

        self.search_text = QLineEdit()
        self.search_text.textChanged.connect(self.search_situations)

        self.tableWidget = QTableWidget()
        self.tableWidget.setRowCount(self.collection.find().count())
        self.tableWidget.setColumnCount(1)
        self.tableWidget.itemSelectionChanged.connect(self.show_selected_item)
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableWidget.setSelectionMode(QAbstractItemView.SingleSelection)
        self.tableWidget.verticalHeader().setVisible(False)
        self.tableWidget.horizontalHeader().setVisible(False)

        self.tableWidget2 = QTableWidget()
        self.tableWidget2.setColumnCount(1)
        self.tableWidget2.itemSelectionChanged.connect(self.show_selected_sentence)
        self.tableWidget2.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableWidget2.setSelectionMode(QAbstractItemView.SingleSelection)
        self.tableWidget2.verticalHeader().setVisible(False)
        self.tableWidget2.horizontalHeader().setVisible(False)

        self.situation_index_list = []
        self.sentence_index_list = []
        self.search_situations()
        self.tableWidget2.setColumnWidth(0,500)
        self.tableWidget.resizeColumnsToContents()
        

        self.new_or_not = QCheckBox('新增情境')
        self.new_or_not.stateChanged.connect(self.state_changed)

        self.remove_btn = QPushButton('刪除情境')
        self.remove_btn.clicked.connect(self.remove_btn_method)

        self.select_layout.addWidget(self.search_text)
        self.select_layout.addWidget(self.new_or_not)
        self.select_layout.addWidget(self.remove_btn)
        self.name = QTextEdit()
        self.sentence = QTextEdit()


        situation_widget.addRow(QLabel('搜尋'), self.select_layout)
        situation_widget.addRow(QLabel('欲編輯情境'), self.tableWidget)
        situation_widget.addRow(QLabel('情境所有語句'), self.tableWidget2)
        situation_widget.addRow(QLabel('說話者'), self.name)
        situation_widget.addRow(QLabel('對話語句'), self.sentence)

        button_layout = QHBoxLayout()
        save_btn = QPushButton("儲存")
        save_btn.clicked.connect(self.save_btn_method)
        cancel_btn = QPushButton("取消")
        cancel_btn.clicked.connect(self.cancel_btn_method)

        button_layout.addWidget(save_btn)
        button_layout.addWidget(cancel_btn)

        self.main_layout.addLayout(situation_widget)
        self.main_layout.addLayout(button_layout)

        self.setLayout(self.main_layout)

    # 好像有BUG,會拿到下一句
    @pyqtSlot()
    def show_selected_item(self):
        self.tableWidget2.clear()
        self.sentence_index_list.clear()
        if len(self.situation_index_list) > 0:
            print(self.tableWidget.currentIndex().row())
            data = self.collection.find({'Situation': self.situation_index_list[
                min(self.tableWidget.currentIndex().row(),
                    len(self.situation_index_list) - 1)]})
            self.tableWidget2.setRowCount(data.count())
            if data != None:
                for index, item in enumerate(data):
                    self.tableWidget2.setItem(index, 0, QTableWidgetItem(str(item['Sentence'])))
                    self.sentence_index_list.append(item['Sentence'])
        else:
            pass

    @pyqtSlot()
    def show_selected_sentence(self):
        if len(self.sentence_index_list) > 0:
            print(self.tableWidget.currentItem().text())
            data = self.collection.find_one({'Sentence': self.sentence_index_list[
                min(self.tableWidget2.currentIndex().row(),
                    len(self.sentence_index_list) - 1)]})
            if data != None:
                self.name.setText(str(data['Name']))
                self.sentence.setText(data['Sentence'])
                
        else:
            pass
    

    @pyqtSlot()
    def search_situations(self):
        self.tableWidget.clear()
        self.situation_index_list.clear()

        if not self.search_text.text() == '':
            search_condition = [{'Situation': {'$regex': '{0}'.format(word)}}
                                for word in self.search_text.text().split()]
            search = list(self.collection.find({'$and': search_condition}))
            search = sorted(set([x['Situation'] for x in search]))
            self.tableWidget.setRowCount(len(search))

            for index, item in enumerate(search):
                self.tableWidget.setItem(index, 0, QTableWidgetItem(str(item)))
                self.situation_index_list.append(item)

        else:
            search = list(self.collection.find({'Name':''}))
            search = sorted(set([x['Situation'] for x in search]))
            self.tableWidget.setRowCount(len(search))
            for index, item in enumerate(search):
                self.tableWidget.setItem(index, 0, QTableWidgetItem(str(item)))
                self.situation_index_list.append(item)



    # finished
    @pyqtSlot()
    def state_changed(self):
        self.name.clear()
        self.sentence.clear()
        if self.new_or_not.checkState():
            self.tableWidget.setDisabled(True)
            self.tableWidget2.setDisabled(True)
        else:
            self.tableWidget.setDisabled(False)
            self.tableWidget2.setDisabled(False)

    # 清除最後一個好像有BUG
    # 已解決: 最後一個被刪除後會留下一個空的string
    @pyqtSlot()
    def remove_btn_method(self):
        if self.tableWidget2.currentItem() is not None:
            if self.new_or_not.checkState():
                QMessageBox.information(self, "提醒", '請先勾去"新增情境"')

            elif len(self.sentence_index_list) > 0:
                result = QMessageBox.question(self, '警告', '確定要刪除"{0}"嗎?'.format(self.tableWidget2.currentItem().text()),
                                              QMessageBox.Yes | QMessageBox.No,
                                              QMessageBox.No)

                if result == QMessageBox.Yes:
                    data = self.sentence_index_list[self.tableWidget2.currentIndex().row()]
                    self.collection.remove({'Sentence': data})

                    del self.sentence_index_list[self.tableWidget2.currentIndex().row()]

                    if self.tableWidget2.rowCount() == 1:
                        self.tableWidget2.setItem(0, 0, QTableWidgetItem(''))

                    else:
                        self.tableWidget2.removeRow(self.tableWidget2.currentIndex().row())

                else:
                    pass

            else:
                pass
        else:
            pass

    # finished
    @pyqtSlot()
    def save_btn_method(self):
        if self.new_or_not.checkState():
            data = {'uuid': self.collection.find().count(), 'Situation': self.tableWidget.currentItem().text(),
                    'Sentence': self.sentence.toPlainText(), 'Name': self.name.toPlainText()
                        }
            self.collection.insert(data)
            self.sentence_index_list.append(data['Sentence'])
            self.tableWidget2.insertRow(self.tableWidget2.rowCount())
            self.tableWidget2.setItem(self.tableWidget2.rowCount() - 1, 0, QTableWidgetItem(str(data['Sentence'])))
            QMessageBox.information(self, "提醒", '已儲存"{}"'.format(self.sentence.toPlainText()))

        elif len(self.sentence_index_list) > 0:
            data = self.collection.find_one({'Sentence': self.sentence_index_list[self.tableWidget2.currentIndex().row()]})
            data['Name'] = self.name.toPlainText()
            data['Sentence'] = self.sentence.toPlainText().split('\n')
            self.collection.save(data)
            self.tableWidget2.setItem(self.tableWidget2.currentIndex().row(), 0, QTableWidgetItem(str(data['Sentence'])))
            QMessageBox.information(self, "提醒", '已儲存"{}"'.format(self.sentence.toPlainText()))

        else:
            pass

    @pyqtSlot()
    def cancel_btn_method(self):
        self.search_text.clear()
        self.name.clear()
        self.sentence.clear()
Esempio n. 25
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.button_map = dict()
        self.initUI()

    def initUI(self):

        #Menu Bar
        action_open = QAction('&Open', self)
        action_open.setShortcut('Ctrl+O')
        action_open.setStatusTip('Open')
        action_open.triggered.connect(self.openFile)

        action_quit = QAction('&Exit', self)
        action_quit.setShortcut('Ctrl+Q')
        action_quit.setStatusTip('Exit application')
        action_quit.triggered.connect(qApp.quit)

        action_show_log_window = QAction('&Log', self)
        action_show_log_window.setShortcut('Ctrl+L')
        action_show_log_window.setStatusTip('Open Log Window')
        action_show_log_window.triggered.connect(self.openLogWindow)

        action_show_help_window = QAction('&Help', self)
        action_show_help_window.setShortcut('Ctrl+H')
        action_show_help_window.setStatusTip('Open Help Window')
        action_show_help_window.triggered.connect(self.openHelpWindow)

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        viewMenu = menubar.addMenu('&View')
        helpMenu = menubar.addMenu('&Help')

        fileMenu.addAction(action_open)
        fileMenu.addAction(action_quit)
        viewMenu.addAction(action_show_log_window)
        helpMenu.addAction(action_show_help_window)

        #Widgets

        self.input_filename_label = QLabel('Input Filename')
        self.input_filename = QLineEdit()
        self.input_filename.setText("")

        self.output_filename_label = QLabel('Output Filename')
        self.output_filename = QLineEdit()
        self.output_filename.setText("")

        self.filter_label = QLabel('Filter')
        self.filter = QLineEdit()
        self.filter.setText("< AUTO >")

        self.modify_label = QLabel('Modify')
        self.modify = QLineEdit()
        self.modify.setText("< AUTO >")

        self.type_label = QLabel('Type')
        self.type = QComboBox()
        self.type.addItem("AUTO")
        self.type.addItem("IP")
        self.type.addItem("MAC")
        self.type.addItem("VLAN")
        self.type.currentIndexChanged.connect(self.comboBoxChange)

        self.payload_label = QLabel('Check Payload')
        self.payload = QCheckBox()

        self.button_run = QPushButton('Run', self)
        self.button_run.resize(self.button_run.sizeHint())
        self.button_run.clicked.connect(self.buttonHandler)
        self.button_map[self.button_run] = "run"

        self.grid = QGridLayout()
        self.grid.setSpacing(10)
        self.grid.addWidget(self.input_filename_label, 0, 0, 1, 1)
        self.grid.addWidget(self.input_filename, 0, 1, 1, 3)
        self.grid.addWidget(self.output_filename_label, 1, 0, 1, 1)
        self.grid.addWidget(self.output_filename, 1, 1, 1, 3)
        self.grid.addWidget(self.filter_label, 2, 0, 1, 1)
        self.grid.addWidget(self.filter, 2, 1, 1, 3)
        self.grid.addWidget(self.modify_label, 3, 0, 1, 1)
        self.grid.addWidget(self.modify, 3, 1, 1, 3)
        self.grid.addWidget(self.type_label, 4, 0, 1, 1)
        self.grid.addWidget(self.type, 4, 1, 1, 1)
        self.grid.addWidget(self.payload_label, 5, 0, 1, 1)
        self.grid.addWidget(self.payload, 5, 1, 1, 1)
        self.grid.addWidget(self.button_run, 5, 3, 1, 1)

        self.central_widget = QWidget()
        self.central_widget.setLayout(self.grid)

        #MainWindow
        self.setCentralWidget(self.central_widget)
        self.setGeometry(300, 300, 400, 250)
        self.setWindowTitle('PCAP Obfuscator')
        self.setWindowIcon(QIcon('LisboaAppsIcon.png'))

        self.show()

        #LogWindow
        self.log_window = LogWindow()

        #HelpWindow
        self.help_window = HelpWindow()

    def buttonHandler(self):
        action = self.button_map[self.sender()]
        if action == "run":
            error, log = pcap_obfuscator(self.input_filename.text(),
                                         self.output_filename.text(),
                                         self.filter.text(),
                                         self.modify.text(),
                                         self.type.currentText(),
                                         self.payload.checkState())
            self.log_window.log(log)

            if error == None:
                msg = QMessageBox()
                msg.setIcon(QMessageBox.Information)
                msg.setText("PCAP obfuscation complete!")
                msg.setInformativeText(self.output_filename.text() +
                                       " created.")
                msg.setWindowTitle("PCAP Obfuscator")
                msg.setStandardButtons(QMessageBox.Ok)
                msg.exec_()
            else:
                msg = QMessageBox()
                msg.setIcon(QMessageBox.Warning)
                msg.setText("An error occurred.")
                msg.setInformativeText(error)
                msg.setWindowTitle("PCAP Obfuscator")
                msg.setStandardButtons(QMessageBox.Ok)
                msg.exec_()

    def comboBoxChange(self):
        if self.type.currentText() == "IP":
            self.filter.setText("*.*.*.*")
            self.modify.setText("")
        elif self.type.currentText() == "MAC":
            self.filter.setText("*:*:*:*:*:*")
            self.modify.setText("")
        elif self.type.currentText() == "VLAN":
            self.filter.setText("")
            self.modify.setText("")
        elif self.type.currentText() == "AUTO":
            self.filter.setText("< AUTO >")
            self.modify.setText("< AUTO >")

    def openFile(self, *filename):
        options = QFileDialog.Options()
        self.open_filename, _ = QFileDialog.getOpenFileName(
            self,
            "Open PCAP File",
            "",
            "PCAP Files (*.pcap);;All Files (*)",
            options=options)
        self.input_filename.setText(self.open_filename)
        self.output_filename.setText(
            self.open_filename.rsplit('/', 1)[0] + "/obfuscated.pcap")

    def openLogWindow(self):
        self.log_window.show()

    def openHelpWindow(self):
        self.help_window.show()

    def closeEvent(self, event):

        reply = QMessageBox.question(self, 'Message', "Are you sure to quit?",
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)

        if reply == QMessageBox.Yes:
            self.log_window.close()
            self.help_window.close()
            event.accept()
        else:
            event.ignore()
Esempio n. 26
0
class dig_sentence_log(QWidget):  # 回答紀錄
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        client = MongoClient('localhost', 27017)
        db = client.gossip
        self.collection_log = db.logs
        self.collection_sen = db.sentences

        self.main_layout = QVBoxLayout()

        sentence_widget = QFormLayout()
        self.select_layout = QHBoxLayout()
        self.show_all_sentences = QCheckBox('顯示所有紀錄')
        self.show_all_sentences.stateChanged.connect(self.state_changed)
        self.sentences_id = []

        self.search_text = QLineEdit()
        self.search_text.textChanged.connect(self.search_sentences)

        self.tableWidget = QTableWidget()
        self.tableWidget.setRowCount(self.collection_log.find().count())
        self.tableWidget.setColumnCount(1)
        self.tableWidget.itemSelectionChanged.connect(self.show_selected_item)
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableWidget.setSelectionMode(QAbstractItemView.SingleSelection)
        self.tableWidget.verticalHeader().setVisible(False)
        self.tableWidget.horizontalHeader().setVisible(False)

        self.sentence_index_list = []
        self.search_sentences()

        self.tableWidget.resizeColumnsToContents()

        self.remove_btn = QPushButton('刪除紀錄')
        self.remove_btn.clicked.connect(self.remove_btn_method)

        self.select_layout.addWidget(self.search_text)
        self.select_layout.addWidget(self.show_all_sentences)
        self.select_layout.addWidget(self.remove_btn)

        temp = self.collection_log.find_one()
        self.sentence = QTextEdit()
        self.name = ''
        self.events = QTextEdit()
        if temp is not None:
            self.sentence.setText(str(temp['Sentence']))
            self.name = temp['Name']
            self.events.setText('、'.join([x['Action'] for x in temp['Actions']]))
        self.situation = QTextEdit()

        sentence_widget.addRow(QLabel('搜尋'), self.select_layout)
        sentence_widget.addRow(QLabel('對話紀錄'), self.tableWidget)
        sentence_widget.addRow(QLabel('對話'), self.sentence)
        sentence_widget.addRow(QLabel('連續事件'), self.events)
        sentence_widget.addRow(QLabel('情境'), self.situation)

        button_layout = QHBoxLayout()
        save_btn = QPushButton("儲存")
        save_btn.clicked.connect(self.save_btn_method)
        cancel_btn = QPushButton("取消")
        cancel_btn.clicked.connect(self.cancel_btn_method)

        button_layout.addWidget(save_btn)
        button_layout.addWidget(cancel_btn)

        self.main_layout.addLayout(sentence_widget)
        self.main_layout.addLayout(button_layout)

        self.setLayout(self.main_layout)

    @pyqtSlot()
    def search_sentences(self):
        self.tableWidget.clear()
        self.sentence_index_list.clear()
        search_condition = []

        if not self.search_text.text() == '':
            search_condition += [{'Sentence': {'$regex': '{0}'.format(word)}}
                                 for word in self.search_text.text().split()]

        if len(search_condition):
            search = self.collection_log.find({'$and': search_condition})
        else:
            search = self.collection_log.find()

        self.tableWidget.setRowCount(search.count())

        for index, item in enumerate(search):
            self.tableWidget.setItem(index, 0, QTableWidgetItem(str(item['Sentence'])))
            self.sentence_index_list.append(item['_id'])

    @pyqtSlot()
    def load_sentence(self):
        for _ in range(len(self.sentences_id)):
            self.log_list.removeItem(0)

        self.sentences_id = []

        if self.show_all_sentences.checkState():
            for row in self.collection_log.find():
                self.sentences_id.append(row['_id'])
                self.log_list.addItem(str(row['Sentence']))
            if self.log_list.count() > len(self.sentences_id):
                if len(self.sentences_id) > 0:
                    self.log_list.removeItem(0)

        else:
            for row in self.collection_log.find():
                self.sentences_id.append(row['_id'])
                self.log_list.addItem(str(row['Sentence']))

    @pyqtSlot()
    def show_selected_item(self):
        if len(self.sentence_index_list) > 0:
            data = self.collection_log.find_one({'_id': self.sentence_index_list[
                min(self.tableWidget.currentIndex().row(), len(self.sentence_index_list) - 1)]})

            if data != None:
                self.sentence.setText(str(data['Sentence']))
                self.events.setText('、'.join([x['Action'] for x in data['Actions']]))
                self.name = data['Name']

        else:
            pass

    @pyqtSlot()
    def state_changed(self):
        self.sentence.clear()
        self.events.clear()
        self.search_sentences()

    @pyqtSlot()
    def remove_btn_method(self):
        if self.tableWidget.currentItem() is not None:
            if len(self.sentence_index_list) > 0:
                result = QMessageBox.question(self, '警告', '確定要刪除"{0}"嗎?'.format(self.tableWidget.currentItem().text()),
                                              QMessageBox.Yes | QMessageBox.No,
                                              QMessageBox.No)

                if result == QMessageBox.Yes:
                    current_index = self.sentence_index_list[self.tableWidget.currentIndex().row()]
                    self.collection_log.remove({'_id': current_index})

                    del self.sentence_index_list[self.tableWidget.currentIndex().row()]

                    if self.tableWidget.rowCount() == 1:
                        self.tableWidget.setItem(0, 0, QTableWidgetItem(''))

                    else:
                        self.tableWidget.removeRow(self.tableWidget.currentIndex().row())

                else:
                    pass
            else:
                QMessageBox.information(self, '警告', '目前沒有句子')
        else:
            pass

    def remove_item_from_table(self):
        current_index = self.sentence_index_list[self.tableWidget.currentIndex().row()]
        self.collection_log.remove({'_id': current_index})

        del self.sentence_index_list[self.tableWidget.currentIndex().row()]

        if self.tableWidget.rowCount() == 1:
            self.tableWidget.setItem(0, 0, QTableWidgetItem(''))

        else:
            self.tableWidget.removeRow(self.tableWidget.currentIndex().row())

    @pyqtSlot()
    def save_btn_method(self):
        if len(self.sentence_index_list) > 0:
            temp = self.collection_sen.find_one()
            if temp is not None:
                temp['Sentence'].append(self.sentence.toPlainText())
                self.collection_sen.save(temp)
            else:
                data = {'uuid': self.collection_ori.find().count(), 'Sentence': self.sentence.toPlainText(),
                        'Situation': self.situation.toPlainText(), 'Name': self.name
                        }
                self.collection_sen.insert(data)

            QMessageBox.information(self, '提醒', '已儲存"{}"'.format(self.sentence.toPlainText()))
            self.remove_item_from_table()

        else:
            QMessageBox.information(self, '警告', '目前沒有句子')

    @pyqtSlot()
    def cancel_btn_method(self):
        data = self.collection_log.find_one({'_id': self.sentence_index_list[self.tableWidget.currentIndex().row()]})
        self.sentence.setText(str(data['Sentence']))
        self.events.setText('、'.join([x['Action'] for x in temp['Actions']]))
Esempio n. 27
0
class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    
    def initUI(self):
        #-----------Creation---------------------------------------------
        #label
        labelStroka = QLabel('Строка: ')
        labelResult = QLabel('Результат: ')
        
        #lineEdit
        
        self.lineEditInput = QLineEdit()
        self.lineEditResult = QLineEdit()
        self.input_ = self.lineEditInput.text()
        self.output_ = self.lineEditResult.text()
        
        #chekbox
        self.checkbox1 = QCheckBox('Удалить слова размером меньше n символов, n = ')
        self.checkbox2 = QCheckBox('Заменить все цифры на *')
        self.checkbox3 = QCheckBox('Вставить по пробелу между символами')
        self.checkbox4 = QCheckBox('Сортировать слова в строке')

        #QSpinBox
        self.spinBox1 = QSpinBox()

        #QPushButton
        buttonFormat = QPushButton('Форматировать!',self)

        #QRadioButton
        self.radio1 = QRadioButton('По размеру')
        self.radio1.setChecked(True)
        self.radio2 = QRadioButton('Лексиграфически')
        #---------------Position-----------------------------
        grid = QGridLayout()
        grid.setSpacing(10)
        
        #label
        grid.addWidget(labelStroka,1,0)
        grid.addWidget(labelResult,9,0)

        #lineEdit
        grid.addWidget(self.lineEditInput,1,1)
        grid.addWidget(self.lineEditResult,9,1)

        #chekbox
        grid.addWidget(self.checkbox1,2,1)
        grid.addWidget(self.checkbox2,3,1)
        grid.addWidget(self.checkbox3,4,1)
        grid.addWidget(self.checkbox4,5,1)

        #QPushButton
        grid.addWidget(buttonFormat,8,1)

        #QSpinBox
        grid.addWidget(self.spinBox1,2,2)

        #QRadioButton
        grid.addWidget(self.radio1,6,1)
        grid.addWidget(self.radio2,7,1)
        #---------------------------------------------------------
        #---------Event Magic------------------------------------
        buttonFormat.clicked.connect(self.buttonClicked)
        #---------------------------------------------------------
        self.setLayout(grid)
        self.setGeometry(300, 300, 350, 300)
        self.setWindowTitle('Review')
        self.show()
    def keyPressEvent(self, e):

        if e.key() == Qt.Key_Escape:
            self.close
   
    def buttonClicked(self):
        #---on button click starts formatting------
        self.input_ = ''
        self.output_ = ''
        self.input_ = self.lineEditInput.text()
        self.output_ = self.input_
        tempArr = []
        #------------------------------------------
        #--------1st checkbox----------------------
        if (self.checkbox1.checkState()==2):
            n = self.spinBox1.value()
            splitInputArr = self.input_.split(' ')
            for i in range(len(splitInputArr)):
                if len(splitInputArr[i])>=n:
                    tempArr.append(splitInputArr[i])
                self.output_ = ' '.join(tempArr)
            self.lineEditResult.setText(self.output_)
        #--------2nd checkbox----------------------
        if (self.checkbox2.checkState()==2):
            self.output_ = re.sub('\d','*',self.output_)    
            self.lineEditResult.setText(self.output_)
        #--------3rd checkbox----------------------
        if (self.checkbox3.checkState()==2):
            #tempSubArr = list(self.output_)
            self.output_ = ' '.join(list(self.output_))
            self.lineEditResult.setText(self.output_)
        #--------4th checkbox----------------------
        if (self.checkbox4.checkState()==2) and (self.radio1.isChecked): #Size
            tempSplit = self.output_.split()
            tempSplit.sort(key=len)
            for i in range(len(tempSplit)):
                self.output_ = ' '.join(tempSplit)
            self.lineEditResult.setText(self.output_)

        if (self.checkbox4.checkState()==2) and (self.radio2.isChecked): #Lex
            tempSplit = self.output_.split()
            tempSplit.sort()
            for i in range(len(tempSplit)):
                self.output_ = ' '.join(tempSplit)
            self.lineEditResult.setText(self.output_)
        #----------Output--------------------------
        if ((self.checkbox1.checkState() == 0) and (self.checkbox2.checkState()==0) and (self.checkbox3.checkState()==0) and (self.checkbox4.checkState()==0)):
            self.output_ = self.input_
            self.lineEditResult.setText(self.output_)
        #------------------------------------------
        self.lineEditResult.setText(self.output_)
Esempio n. 28
0
class OperatingTimeWindow(QMainWindow):
    def setupUI(self, mui):
        self.initUI(mui)
        self.mainUI(mui)
        self.configUI(mui)
        self.thresholdUI(mui)
        self.timeUI()
        self.timeFigureUI(mui)
        self.activetiyDetailUI(mui)

        self.draw_figure()
        ## value
        self.cycle_counter = 0

    def initUI(self, mui):
        self.gb_config = QGroupBox()
        self.gb_oprTime = QGroupBox()
        mui.gb_setThreshold = QGroupBox()
        self.gb_figTime = QGroupBox()
        self.gb_actDetail = QGroupBox()

    def mainUI(self, mui):
        self.setWindowTitle('Operating Time Calclation')
        self.setGeometry(1200, 50, 0, 0)
        main_frame = QWidget()

        sw_optForm = QStackedWidget()
        sw_optForm.addWidget(mui.gb_setThreshold)
        sw_optForm.addWidget(self.gb_figTime)
        sw_optForm.addWidget(self.gb_actDetail)
        combo_optForm = QComboBox()
        combo_optForm.addItem('1: Setting Threshold')
        combo_optForm.addItem('2: Operating Time Graph')
        combo_optForm.addItem('3: Activity Details')
        combo_optForm.currentIndexChanged.connect(sw_optForm.setCurrentIndex)

        vbox_main = QVBoxLayout()
        vbox_main.addWidget(self.gb_config)
        vbox_main.addWidget(self.gb_oprTime)
        vbox_main.addWidget(combo_optForm)
        vbox_main.addWidget(sw_optForm)
        main_frame.setLayout(vbox_main)
        self.setCentralWidget(main_frame)

    def configUI(self, mui):
        btn_readConfig = QPushButton('Read')
        btn_readConfig.clicked.connect(lambda: self.readConfig(mui))
        self.le_readConfig = QLineEdit()
        btn_saveConfig = QPushButton('Save')
        btn_saveConfig.clicked.connect(lambda: self.saveConfig(mui))
        self.le_saveConfig = QLineEdit()

        ### -1-
        hbox1 = QHBoxLayout()
        hbox1.addWidget(btn_readConfig)
        hbox1.addWidget(self.le_readConfig)
        ### -2-
        hbox2 = QHBoxLayout()
        hbox2.addWidget(btn_saveConfig)
        hbox2.addWidget(self.le_saveConfig)
        ### |-1-2-|
        vbox_gb_config = QVBoxLayout()
        vbox_gb_config.addLayout(hbox1)
        vbox_gb_config.addLayout(hbox2)

        self.gb_config.setSizePolicy(QSizePolicy.Expanding,
                                     QSizePolicy.Maximum)
        self.gb_config.setTitle("Config File")
        self.gb_config.setLayout(vbox_gb_config)

    def timeUI(self):
        ### Add Element
        stdOprTimeTextLabel = QLabel()
        stdOprTimeTextLabel.setText('Standard :')
        self.stdOprTimeSb = QDoubleSpinBox()
        self.stdOprTimeSb.setSingleStep(0.01)
        self.stdOprTimeSb.setSuffix(" [sec]")
        self.stdOprTimeSb.setValue(3.0)
        calcOprTimeTextLabel = QLabel()
        calcOprTimeTextLabel.setText('Calculation :')
        self.calcOprTimeLabel = QLabel()
        self.calcOprTimeLabel.setText('0.000')
        extTimeLabel = QLabel()
        extTimeLabel.setText("[sec]")
        self.fpsSb = QSpinBox()
        self.fpsSb.setValue(30)
        self.fpsSb.setPrefix("fps: ")
        self.fpsSb.setRange(1, 150)
        differenceTimeTextLabel = QLabel()
        differenceTimeTextLabel.setText('Difference :')
        self.differenceTimeLabel = QLabel()
        self.differenceTimeLabel.setText('x.xxx')
        self.cb_alarm = QCheckBox('Alarm Threshold:')
        self.dsb_alarmRange = QDoubleSpinBox()
        self.dsb_alarmRange.setRange(0, 10)
        self.dsb_alarmRange.setValue(3.0)
        self.dsb_alarmRange.setSingleStep(0.1)
        self.dsb_alarmRange.setSuffix(' [sec]')

        self.cb_saveOprTime = QCheckBox('Save:')
        self.le_filepath = QLineEdit()
        self.le_filepath.setText("CSV File")
        self.btn_save_fd = QPushButton('...')
        self.btn_save_fd.clicked.connect(self.setSaveTimeFilePath)
        self.btn_save_fd.setFixedWidth(30)

        ### -1-
        hbox1 = QHBoxLayout()
        hbox1.addWidget(stdOprTimeTextLabel)
        hbox1.addWidget(self.stdOprTimeSb)
        hbox1.addStretch(1)
        ### -2-
        hbox2 = QHBoxLayout()
        hbox2.addWidget(calcOprTimeTextLabel)
        hbox2.addWidget(self.calcOprTimeLabel)
        hbox2.addWidget(extTimeLabel)
        hbox2.addWidget(self.fpsSb)
        hbox2.addStretch(1)
        ### -3-
        hbox3 = QHBoxLayout()
        hbox3.addWidget(differenceTimeTextLabel)
        hbox3.addWidget(self.differenceTimeLabel)
        hbox3.addStretch(1)
        hbox3.addWidget(self.cb_alarm)
        hbox3.addWidget(self.dsb_alarmRange)
        ### -4-
        hbox4 = QHBoxLayout()
        hbox4.addWidget(self.cb_saveOprTime)
        hbox4.addWidget(self.le_filepath)
        hbox4.addWidget(self.btn_save_fd)

        ### |-1-2-3-4-|
        vbox_gb_oprTime = QVBoxLayout()
        vbox_gb_oprTime.addLayout(hbox1)
        vbox_gb_oprTime.addLayout(hbox2)
        vbox_gb_oprTime.addLayout(hbox3)
        vbox_gb_oprTime.addLayout(hbox4)

        self.gb_oprTime.setSizePolicy(QSizePolicy.Expanding,
                                      QSizePolicy.Maximum)
        self.gb_oprTime.setTitle("Operating Time")
        self.gb_oprTime.setLayout(vbox_gb_oprTime)

    def activetiyDetailUI(self, mui):

        series = QPieSeries()
        chart = QChart()
        chart.addSeries(series)
        #chart.setTitle("Activity Details")
        #chart.legend().hide()

        self.chartView = QChartView()
        self.chartView.setChart(chart)
        self.chartView.setRenderHint(QPainter.Antialiasing)
        self.chartView.setMinimumWidth(350)

        vbox_gb_actDetail = QVBoxLayout()
        vbox_gb_actDetail.addWidget(self.chartView)

        self.gb_actDetail.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Maximum)
        self.gb_actDetail.setLayout(vbox_gb_actDetail)

    def timeFigureUI(self, mui):
        fig = Figure((10, 5), dpi=100)
        self.canvas_time = FigureCanvas(fig)
        self.axes = fig.add_subplot(111)
        self.axes.clear()
        self.x_cycle = deque([])
        self.y_time = deque([])
        self.axes.bar(self.x_cycle, self.y_time)

        self.cb_registrationTime = QCheckBox('Registration')
        self.btn_initGraph = QPushButton('Init')
        self.btn_initGraph.clicked.connect(self.clearGraph)
        lbl_maxCount = QLabel('Num:')
        self.sb_maxCount = QSpinBox()
        self.sb_maxCount.setRange(1, 50)
        self.sb_maxCount.setValue(10)
        lbl_maxValue = QLabel('Val:')
        self.sb_maxValue = QSpinBox()
        self.sb_maxValue.setRange(1, 50)
        self.sb_maxValue.setValue(5)
        lbl_mean = QLabel('Mean:')
        self.le_mean = QLineEdit('')
        lbl_variance = QLabel('Variance:')
        self.le_variance = QLineEdit('')

        ### -1-
        hbox1 = QHBoxLayout()
        hbox1.addWidget(self.cb_registrationTime)
        hbox1.addStretch(1)
        hbox1.addWidget(lbl_maxCount)
        hbox1.addWidget(self.sb_maxCount)
        hbox1.addStretch(1)
        hbox1.addWidget(self.btn_initGraph)

        ### -2-
        hbox2 = QHBoxLayout()
        hbox2.addWidget(lbl_maxValue)
        hbox2.addWidget(self.sb_maxValue)
        hbox2.addWidget(lbl_mean)
        hbox2.addWidget(self.le_mean)
        hbox2.addWidget(lbl_variance)
        hbox2.addWidget(self.le_variance)

        ### |-1-2-|
        vbox_gb_figTime = QVBoxLayout()
        vbox_gb_figTime.addLayout(hbox1)
        vbox_gb_figTime.addWidget(self.canvas_time)
        vbox_gb_figTime.addLayout(hbox2)

        self.gb_figTime.setMinimumHeight(350)
        self.gb_figTime.setLayout(vbox_gb_figTime)

    def thresholdUI(self, mui):
        ### Add Element
        mui.cb_thX1_on = QCheckBox("X1")
        mui.cb_thX2_on = QCheckBox("X2")
        mui.cb_thY1_on = QCheckBox("Y1")
        mui.cb_thY2_on = QCheckBox("Y2")
        mui.cb_thZ1_on = QCheckBox("Z1")
        mui.cb_thZ2_on = QCheckBox("Z2")
        ## X
        mui.sld_thX1 = QSlider(Qt.Vertical)
        mui.sld_thX1.setRange(-50, 50)
        mui.sld_thX1.setValue(0)
        mui.sb_thX1 = QSpinBox()
        mui.sb_thX1.setRange(-50, 50)
        mui.sb_thX1.setValue(mui.sld_thX1.value())
        mui.sb_thX1.valueChanged.connect(mui.setSliderThresholdParameter)
        mui.sld_thX1.valueChanged.connect(mui.setSpinBoxGraphParameter)
        mui.sld_thX1.valueChanged.connect(mui.refreshGraphSlider)
        mui.sb_thX1Variance = QSpinBox()
        mui.sb_thX1Variance.setRange(0, 1000)
        mui.sb_thX1Variance.valueChanged.connect(mui.refreshGraphSpinBox)
        mui.sld_thX2 = QSlider(Qt.Vertical)
        mui.sld_thX2.setRange(-50, 50)
        mui.sld_thX2.setValue(0)
        mui.sb_thX2 = QSpinBox()
        mui.sb_thX2.setRange(-50, 50)
        mui.sb_thX2.setValue(mui.sld_thX1.value())
        mui.sb_thX2.valueChanged.connect(mui.setSliderThresholdParameter)
        mui.sld_thX2.valueChanged.connect(mui.setSpinBoxGraphParameter)
        mui.sld_thX2.valueChanged.connect(mui.refreshGraphSlider)
        mui.sb_thX2Variance = QSpinBox()
        mui.sb_thX2Variance.setRange(0, 1000)
        mui.sb_thX2Variance.valueChanged.connect(mui.refreshGraphSpinBox)
        ## Y
        mui.sld_thY1 = QSlider(Qt.Vertical)
        mui.sld_thY1.setRange(-50, 50)
        mui.sld_thY1.setValue(0)
        mui.sb_thY1 = QSpinBox()
        mui.sb_thY1.setRange(-50, 50)
        mui.sb_thY1.setValue(mui.sld_thY1.value())
        mui.sb_thY1.valueChanged.connect(mui.setSliderThresholdParameter)
        mui.sld_thY1.valueChanged.connect(mui.setSpinBoxGraphParameter)
        mui.sld_thY1.valueChanged.connect(mui.refreshGraphSlider)
        mui.sb_thY1Variance = QSpinBox()
        mui.sb_thY1Variance.setRange(0, 1000)
        mui.sb_thY1Variance.valueChanged.connect(mui.refreshGraphSpinBox)
        mui.sld_thY2 = QSlider(Qt.Vertical)
        mui.sld_thY2.setRange(-50, 50)
        mui.sld_thY2.setValue(0)
        mui.sb_thY2 = QSpinBox()
        mui.sb_thY2.setRange(-50, 50)
        mui.sb_thY2.setValue(mui.sld_thY1.value())
        mui.sb_thY2.valueChanged.connect(mui.setSliderThresholdParameter)
        mui.sld_thY2.valueChanged.connect(mui.setSpinBoxGraphParameter)
        mui.sld_thY2.valueChanged.connect(mui.refreshGraphSlider)
        mui.sb_thY2Variance = QSpinBox()
        mui.sb_thY2Variance.setRange(0, 1000)
        mui.sb_thY2Variance.valueChanged.connect(mui.refreshGraphSpinBox)
        ##Z
        mui.sld_thZ1 = QSlider(Qt.Vertical)
        mui.sld_thZ1.setRange(-50, 50)
        mui.sld_thZ1.setValue(0)
        mui.sb_thZ1 = QSpinBox()
        mui.sb_thZ1.setRange(-50, 50)
        mui.sb_thZ1.setValue(mui.sld_thZ1.value())
        mui.sb_thZ1.valueChanged.connect(mui.setSliderThresholdParameter)
        mui.sld_thZ1.valueChanged.connect(mui.setSpinBoxGraphParameter)
        mui.sld_thZ1.valueChanged.connect(mui.refreshGraphSlider)
        mui.sb_thZ1Variance = QSpinBox()
        mui.sb_thZ1Variance.setRange(0, 1000)
        mui.sb_thZ1Variance.valueChanged.connect(mui.refreshGraphSpinBox)
        mui.sld_thZ2 = QSlider(Qt.Vertical)
        mui.sld_thZ2.setRange(-50, 50)
        mui.sld_thZ2.setValue(0)
        mui.sb_thZ2 = QSpinBox()
        mui.sb_thZ2.setRange(-50, 50)
        mui.sb_thZ2.setValue(mui.sld_thZ2.value())
        mui.sb_thZ2.valueChanged.connect(mui.setSliderThresholdParameter)
        mui.sld_thZ2.valueChanged.connect(mui.setSpinBoxGraphParameter)
        mui.sld_thZ2.valueChanged.connect(mui.refreshGraphSlider)
        mui.sb_thZ2Variance = QSpinBox()
        mui.sb_thZ2Variance.setRange(0, 1000)
        mui.sb_thZ2Variance.valueChanged.connect(mui.refreshGraphSpinBox)

        #
        lbl_scaleX = QLabel('scale X:')
        lbl_scaleY = QLabel('scale Y:')
        lbl_scaleZ = QLabel('scale Z:')
        mui.sb_thX_scale = QDoubleSpinBox()
        mui.sb_thX_scale.setRange(0.01, 100)
        mui.sb_thX_scale.setValue(0.05)
        mui.sb_thX_scale.setSingleStep(0.01)
        mui.sb_thY_scale = QDoubleSpinBox()
        mui.sb_thY_scale.setRange(0.01, 100)
        mui.sb_thY_scale.setValue(0.05)
        mui.sb_thY_scale.setSingleStep(0.01)
        mui.sb_thZ_scale = QDoubleSpinBox()
        mui.sb_thZ_scale.setRange(0.01, 100)
        mui.sb_thZ_scale.setValue(0.05)
        mui.sb_thZ_scale.setSingleStep(0.01)

        ### -1-
        hbox1 = QHBoxLayout()
        hbox1.addWidget(lbl_scaleX)
        hbox1.addWidget(mui.sb_thX_scale)
        hbox1.addWidget(lbl_scaleY)
        hbox1.addWidget(mui.sb_thY_scale)
        hbox1.addWidget(lbl_scaleZ)
        hbox1.addWidget(mui.sb_thZ_scale)

        ### |1|
        vbox1 = QVBoxLayout()
        vbox1.addWidget(mui.cb_thX1_on)
        vbox1.addWidget(mui.sb_thX1)
        vbox1.addWidget(mui.sld_thX1)
        vbox1.addWidget(mui.sb_thX1Variance)
        vbox1_2 = QVBoxLayout()
        vbox1_2.addWidget(mui.cb_thX2_on)
        vbox1_2.addWidget(mui.sb_thX2)
        vbox1_2.addWidget(mui.sld_thX2)
        vbox1_2.addWidget(mui.sb_thX2Variance)
        ### |2|
        vbox2 = QVBoxLayout()
        vbox2.addWidget(mui.cb_thY1_on)
        vbox2.addWidget(mui.sb_thY1)
        vbox2.addWidget(mui.sld_thY1)
        vbox2.addWidget(mui.sb_thY1Variance)
        vbox2_2 = QVBoxLayout()
        vbox2_2.addWidget(mui.cb_thY2_on)
        vbox2_2.addWidget(mui.sb_thY2)
        vbox2_2.addWidget(mui.sld_thY2)
        vbox2_2.addWidget(mui.sb_thY2Variance)
        ### |3|
        vbox3 = QVBoxLayout()
        vbox3.addWidget(mui.cb_thZ1_on)
        vbox3.addWidget(mui.sb_thZ1)
        vbox3.addWidget(mui.sld_thZ1)
        vbox3.addWidget(mui.sb_thZ1Variance)
        vbox3_2 = QVBoxLayout()
        vbox3_2.addWidget(mui.cb_thZ2_on)
        vbox3_2.addWidget(mui.sb_thZ2)
        vbox3_2.addWidget(mui.sld_thZ2)
        vbox3_2.addWidget(mui.sb_thZ2Variance)
        ### -2|1|2|3|-
        hbox2 = QHBoxLayout()
        hbox2.addLayout(vbox1)
        hbox2.addLayout(vbox1_2)
        hbox2.addLayout(vbox2)
        hbox2.addLayout(vbox2_2)
        hbox2.addLayout(vbox3)
        hbox2.addLayout(vbox3_2)

        ### |-1-2-|
        vbox_gb_setThreshold = QVBoxLayout()
        vbox_gb_setThreshold.addLayout(hbox1)
        vbox_gb_setThreshold.addLayout(hbox2)

        mui.gb_setThreshold.setMinimumHeight(400)
        mui.gb_setThreshold.setLayout(vbox_gb_setThreshold)

    def readConfig(self, mui):
        filename = QFileDialog.getOpenFileName(self, 'Open file', '.')
        self.le_readConfig.setText(filename[0])
        if self.le_readConfig.text() == "":
            return -1

        config = ConfigParser()
        config.read(self.le_readConfig.text())

        ## set parameter
        self.stdOprTimeSb.setValue(
            float(config['timeUI']['StandartOperationTime']))
        self.fpsSb.setValue(int(config['timeUI']['FPS']))
        self.cb_saveOprTime.setChecked(
            "True" == (config['timeUI']['SaveOperationTime']))
        self.le_filepath.setText(config['timeUI']['SaveFilename'])
        mui.cb_thX1_on.setChecked(
            "True" == (config['thresholdUI']['UseThreshold_X1']))
        mui.cb_thX2_on.setChecked(
            "True" == (config['thresholdUI']['UseThreshold_X2']))
        mui.cb_thY1_on.setChecked(
            "True" == (config['thresholdUI']['UseThreshold_Y1']))
        mui.cb_thY2_on.setChecked(
            "True" == (config['thresholdUI']['UseThreshold_Y2']))
        mui.cb_thZ1_on.setChecked(
            "True" == (config['thresholdUI']['UseThreshold_Z1']))
        mui.cb_thZ2_on.setChecked(
            "True" == (config['thresholdUI']['UseThreshold_Z2']))
        mui.sb_thX_scale.setValue(
            float(config['thresholdUI']['Threshold_ScaleX']))
        mui.sb_thY_scale.setValue(
            float(config['thresholdUI']['Threshold_ScaleY']))
        mui.sb_thZ_scale.setValue(
            float(config['thresholdUI']['Threshold_ScaleZ']))
        mui.sb_thX1.setValue(int(config['thresholdUI']['Threshold_ValueX1']))
        mui.sb_thX2.setValue(int(config['thresholdUI']['Threshold_ValueX2']))
        mui.sb_thY1.setValue(int(config['thresholdUI']['Threshold_ValueY1']))
        mui.sb_thY2.setValue(int(config['thresholdUI']['Threshold_ValueY2']))
        mui.sb_thZ1.setValue(int(config['thresholdUI']['Threshold_ValueZ1']))
        mui.sb_thZ2.setValue(int(config['thresholdUI']['Threshold_ValueZ2']))
        mui.sb_thX1Variance.setValue(
            int(config['thresholdUI']['Threshold_VarianceX1']))
        mui.sb_thX2Variance.setValue(
            int(config['thresholdUI']['Threshold_VarianceX2']))
        mui.sb_thY1Variance.setValue(
            int(config['thresholdUI']['Threshold_VarianceY1']))
        mui.sb_thY2Variance.setValue(
            int(config['thresholdUI']['Threshold_VarianceY2']))
        mui.sb_thZ1Variance.setValue(
            int(config['thresholdUI']['Threshold_VarianceZ1']))
        mui.sb_thZ2Variance.setValue(
            int(config['thresholdUI']['Threshold_VarianceZ2']))
        mui.combo.setCurrentText(config['figureUI']['TargetSkeltonParts'])

    def saveConfig(self, mui):
        filename = QFileDialog.getSaveFileName(self, 'Save File', '.')
        self.le_saveConfig.setText(filename[0])
        if self.le_saveConfig.text() == "":
            return -1

        config = ConfigParser()
        config.optionxform = str
        config.add_section('timeUI')
        config.add_section('thresholdUI')
        config.add_section('figureUI')
        config.add_section('mainUI')
        config.set('timeUI', 'StandartOperationTime',
                   str(self.stdOprTimeSb.value()))
        config.set('timeUI', 'FPS', str(self.fpsSb.value()))
        config.set('timeUI', 'SaveOperationTime',
                   str(self.cb_saveOprTime.checkState()))
        config.set('timeUI', 'SaveFilename', str(self.le_filepath.text()))
        config.set('thresholdUI', 'UseThreshold_X1',
                   self.bool2string(mui.cb_thX1_on.checkState()))
        config.set('thresholdUI', 'UseThreshold_X2',
                   self.bool2string(mui.cb_thX2_on.checkState()))
        config.set('thresholdUI', 'UseThreshold_Y1',
                   self.bool2string(mui.cb_thY1_on.checkState()))
        config.set('thresholdUI', 'UseThreshold_Y2',
                   self.bool2string(mui.cb_thY2_on.checkState()))
        config.set('thresholdUI', 'UseThreshold_Z1',
                   self.bool2string(mui.cb_thZ1_on.checkState()))
        config.set('thresholdUI', 'UseThreshold_Z2',
                   self.bool2string(mui.cb_thZ2_on.checkState()))
        config.set('thresholdUI', 'Threshold_ScaleX',
                   str(mui.sb_thX_scale.value()))
        config.set('thresholdUI', 'Threshold_ScaleY',
                   str(mui.sb_thY_scale.value()))
        config.set('thresholdUI', 'Threshold_ScaleZ',
                   str(mui.sb_thZ_scale.value()))
        config.set('thresholdUI', 'Threshold_ValueX1',
                   str(mui.sb_thX1.value()))
        config.set('thresholdUI', 'Threshold_ValueX2',
                   str(mui.sb_thX2.value()))
        config.set('thresholdUI', 'Threshold_ValueY1',
                   str(mui.sb_thY1.value()))
        config.set('thresholdUI', 'Threshold_ValueY2',
                   str(mui.sb_thY2.value()))
        config.set('thresholdUI', 'Threshold_ValueZ1',
                   str(mui.sb_thZ1.value()))
        config.set('thresholdUI', 'Threshold_ValueZ2',
                   str(mui.sb_thZ2.value()))
        config.set('thresholdUI', 'Threshold_VarianceX1',
                   str(mui.sb_thX1Variance.value()))
        config.set('thresholdUI', 'Threshold_VarianceX2',
                   str(mui.sb_thX2Variance.value()))
        config.set('thresholdUI', 'Threshold_VarianceY1',
                   str(mui.sb_thY1Variance.value()))
        config.set('thresholdUI', 'Threshold_VarianceY2',
                   str(mui.sb_thY2Variance.value()))
        config.set('thresholdUI', 'Threshold_VarianceZ1',
                   str(mui.sb_thZ1Variance.value()))
        config.set('thresholdUI', 'Threshold_VarianceZ2',
                   str(mui.sb_thZ2Variance.value()))
        config.set('figureUI', 'TargetSkeltonParts',
                   str(mui.combo.currentText()))
        config.write(open(self.le_saveConfig.text(), 'w'))

    def drawChart(self, mui):
        series = QPieSeries()
        series.append("Main", mui.keyfunc.mainActivityFrame)
        series.append("Key", mui.keyfunc.keyActivityFrame)
        slice1 = series.slices()[0]
        #slice1.setExploded()
        slice1.setLabelVisible()
        slice1.setPen(QPen(QColor(40, 100, 240, 250), 2))
        slice1.setBrush(QColor(40, 100, 240, 200))
        slice2 = series.slices()[1]
        slice2.setLabelVisible()
        slice2.setPen(QPen(QColor(20, 150, 240, 250), 2))
        slice2.setBrush(QColor(20, 150, 240, 200))

        chart = QChart()
        chart.addSeries(series)
        #chart.setTitle("Activity Details")
        #chart.legend().hide()

        self.chartView.setChart(chart)

    def getCalclationTime(self, mui):
        if self.cb_registrationTime.checkState():
            self.setCalclationTimeGraph()
        self.calcDifferenceOperatingTime()
        if self.cb_saveOprTime.checkState():
            self.writeText(mui)

    def setCalclationTimeGraph(self):
        if (len(self.x_cycle) >= self.sb_maxCount.value()):
            self.x_cycle.popleft()
            self.y_time.popleft()
        self.cycle_counter += 1
        self.x_cycle.append(self.cycle_counter)
        self.y_time.append(float(self.calcOprTimeLabel.text()))
        self.le_mean.setText("{0:.2f}".format(np.array(self.y_time).mean()))
        self.le_variance.setText("{0:.2f}".format(
            self.calclVariance(np.array(self.y_time))))
        self.draw_figure()

    def draw_figure(self):
        self.axes.clear()
        self.axes.set_ylim([0, self.sb_maxValue.value()])
        self.axes.bar(self.x_cycle, self.y_time, color='#6060AA')
        self.canvas_time.draw()

    def clearGraph(self):
        self.cycle_counter = 0
        self.x_cycle = deque([])
        self.y_time = deque([])
        self.draw_figure()

    def calclVariance(self, val):
        variance = np.sum((val * val)) / len(val) - (val.mean() * val.mean())
        return variance

    def calcDifferenceOperatingTime(self):
        time = self.stdOprTimeSb.value() - float(self.calcOprTimeLabel.text())
        self.differenceTimeLabel.setText("{0:.2f}[sec]".format(time))
        if self.cb_alarm.checkState():
            if self.dsb_alarmRange.value() <= abs(time) and 0 < time:
                self.popupMessage(0, abs(time))
            elif self.dsb_alarmRange.value() <= abs(time) and 0 > time:
                self.popupMessage(1, abs(time))

    def popupMessage(self, signal, time):
        if signal == 0:
            QMessageBox.warning(
                self, 'Alarm Message',
                "標準作業時間({1:.2f}秒)と比較して{0:.2f}秒速いです".format(
                    time, self.stdOprTimeSb.value()), QMessageBox.Close)
        elif signal == 1:
            QMessageBox.warning(
                self, 'Alarm Message',
                "標準作業時間({1:.2f}秒)と比較して{0:.2f}秒遅いです".format(
                    time, self.stdOprTimeSb.value()), QMessageBox.Close)

    def writeText(self, mui):
        import csv
        import os.path
        writeItemname = True
        if os.path.isfile(self.le_filepath.text()):
            writeItemname = False
        with open(self.le_filepath.text(), 'a', newline="") as f:
            writer = csv.writer(f)
            if writeItemname:
                writer.writerow(
                    ['Filename', 'FPS', 'Calclation Time', 'Setting Time'])
            writer.writerow([
                mui.fnameQle.text(),
                self.fpsSb.value(),
                float(self.calcOprTimeLabel.text()),
                self.stdOprTimeSb.value()
            ])

    def setSaveTimeFilePath(self):
        filename = QFileDialog.getSaveFileName(self, 'Save File', '.')
        self.le_filepath.setText(filename[0])

    def bool2string(self, bool_val):
        if bool_val:
            return 'True'
        else:
            return 'False'
Esempio n. 29
0
class AlgWin(QWidget):
    okCLickedSignal = pyqtSignal(Algo, name='okClicked')

    def __init__(self, parent=None, alg=None):
        QWidget.__init__(self, parent)
        winsettings('algwin', self)
        taglabel = QLabel('&Tags')
        self.tags = QLineEdit('artist | title')
        taglabel.setBuddy(self.tags)
        self.alcombo = QComboBox()
        allabel = QLabel('&Algorithms')
        allabel.setBuddy(self.alcombo)
        self.threshold = QLineEdit('90')
        self.threshold.setValidator(QDoubleValidator(self.threshold))
        perlabel = QLabel("&Match threshold")
        perlabel.setBuddy(self.threshold)

        self.matchcase = QCheckBox('&Match Case')

        okcancel = OKCancel()
        okcancel.okButton.setDefault(True)

        okcancel.ok.connect(self.okClicked)
        okcancel.cancel.connect(self.close)

        vbox = QVBoxLayout()
        [vbox.addWidget(z) for z in [taglabel, self.tags, perlabel, self.threshold,
                                     allabel, self.alcombo, self.matchcase]]
        frame = QFrame()
        frame.setFrameStyle(QFrame.Shape.Box)
        frame.setLayout(vbox)

        box = QVBoxLayout()
        box.addWidget(frame)
        box.addLayout(okcancel)
        self.setLayout(box)

        x = [funcinfo(z) for z in funcs]
        names = [z[0] for z in x]
        ds = [z[1] for z in x]

        self.alcombo.clear()
        self.alcombo.addItems(names)
        self.alcombo.setCurrentIndex(0)
        tooltip = "<dl>%s</dl>" % ''.join(['<dt><b>%s<b></dt> <dd>%s</dd>' % z for z in x])
        self.alcombo.setToolTip(tooltip)
        if alg:
            self.loadAlgo(alg)

    def loadAlgo(self, alg):
        i = self.alcombo.findText(alg.funcname)
        if i >= 0:
            self.alcombo.setCurrentIndex(i)
        else:
            self.alcombo.addItem(alg.funcname)
            self.alcombo.setCurrentIndex(self.alcombo.count() - 1)

        self.tags.setText(' | '.join(alg.tags))
        self.threshold.setText('%.2f' % (alg.threshold * 100))
        if alg.matchcase:
            self.matchcase.setCheckState(Qt.CheckState.Checked)
        else:
            self.matchcase.setCheckState(Qt.CheckState.Unchecked)

    def saveAlgo(self):
        tags = [x for x in [z.strip() for z in str(self.tags.text()).split("|")] if x != ""]
        func = funcs[self.alcombo.currentIndex()]
        threshold = float(str(self.threshold.text())) / 100
        matchcase = False
        if self.matchcase.checkState() == Qt.CheckState.Checked:
            matchcase = True

        return Algo(tags, threshold, func, matchcase)

    def okClicked(self):
        self.okClickedSignal.emit(self.saveAlgo())
        self.close()
Esempio n. 30
0
class Window(QWidget):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        self.initUI()

    def initUI(self):
        self.listCheckBox = [
            "系统时间", "设备名称", "设备版本", "设备类型", "运行时间", "cpu利用率", '内存使用', '板卡信息',
            '板卡切换情况', '邻居信息', '温度与电源信息', 'ACL', 'HomelessVideo'
        ]

        grid = QGridLayout()

        self.resize(300, 200)
        self.setWindowTitle("来快活呀")

        for i, v in enumerate(self.listCheckBox):
            self.listCheckBox[i] = QCheckBox(v)
            grid.addWidget(self.listCheckBox[i], i, 0)

        self.checkbox = QCheckBox("选择全部")
        self.checkbox.stateChanged.connect(self.selectall)

        self.button = QPushButton("Run")
        self.button.clicked.connect(self.buttonclicked)

        grid.addWidget(self.checkbox, 25, 0, 1, 2)
        grid.addWidget(self.button, 26, 0, 1, 2)
        self.setLayout(grid)

    def buttonclicked(self):
        ###It will return a varlist.
        ###It will display what you have chosen.
        varlist = []
        for i, v in enumerate(self.listCheckBox):
            if v.checkState():
                varlist.append(v.text())
        print(varlist)
        ###After a varlist is chosen, run the function in order to export the chosen items
        t1 = time.time()
        readwritevalue(varlist)
        GetFormated()  ##Get the Final output of Xunjian-Report.csv
        Getxlsx()  ##Get the Xunjian-Report.xls
        GetDocx()  ##Get the docx format
        print("Run time %s" % (time.time() - t1))

        ###Multiple process###
        ###Don't know how to proceed with multiprocessing under the PyQt yet.
        ##The following will spend more time to complete the programme.
        ##From the url https://stackoverflow.com/questions/15675043/multiprocessing-and-gui-updating-qprocess-or-multiprocessing
        ##It describes how to use multiprocessing and QThread together.

        # t1 = time.time()
        # pool = Pool(4)
        # pool.map(readwritevalue,  varlist)
        # GetFormated()  ##Get the Final output of Xunjian-Report.csv
        # Getxlsx()  ##Get the Xunjian-Report.xls
        # GetDocx()  ##Get the docx format
        # pool.close()
        # pool.join()
        # print("Run time %s" %(time.time()-t1))

    def selectall(self):
        if self.checkbox.checkState() == Qt.Checked:
            for i, v in enumerate(self.listCheckBox):
                self.listCheckBox[i].setChecked(True)
        else:
            for i, v in enumerate(self.listCheckBox):
                self.listCheckBox[i].setChecked(False)
Esempio n. 31
0
class FormWidget(QWidget):
    def __init__(self, parent):
        super(FormWidget, self).__init__(parent)
        self.resultDict = {}
        self.csvList = []
        self.fileStartTime = ""
        self.fileStopTime = ""
        self.openGoogleEarth = True

        self.statusBar = QStatusBar()
        self.statusBar.showMessage('Open a CSV File to begin')

        # Buttons
        self.openFileBtn = QPushButton('Open CSV Files', self)
        self.openFileBtn.setToolTip('Open Coordinator formatted CSV files')
        self.openFileBtn.clicked.connect(self.showOpenFile)
        self.startParseBtn = QPushButton('Start Search', self)
        self.startParseBtn.clicked.connect(self.parseFile)
        self.startParseBtn.setDisabled(True)
        self.plotSelectionBtn = QPushButton('Plot Selected ISSI', self)
        self.plotSelectionBtn.clicked.connect(self.onPlotFile)
        self.plotSelectionBtn.setDisabled(True)
        self.saveDataBtn = QPushButton('Save ISSI Search Data', self)
        self.saveDataBtn.clicked.connect(self.save_data)
        self.saveDataBtn.setDisabled(True)
        self.resetTimeBtn = QPushButton('Reset Times', self)
        self.resetTimeBtn.clicked.connect(self.onResetTimes)
        self.resetTimeBtn.setDisabled(True)
        self.plotAllBtn = QPushButton("Plot all ISSI's (caution)")
        self.plotAllBtn.clicked.connect(self.onPlotFile)
        self.plotAllBtn.setDisabled(True)
        self.stopPlotBtn = QPushButton('Stop Plot')
        self.stopPlotBtn.clicked.connect(self.stopThread)
        self.stopPlotBtn.setDisabled(True)
        self.openResultsFolder = QPushButton('Open Results folder')
        self.openResultsFolder.clicked.connect(self.open_results_folder)
        self.openResultsFolder.setDisabled(True)

        # CheckBoxes
        self.areaSearchSwitch = QCheckBox('Search Area', self)
        self.areaSearchSwitch.stateChanged.connect(self.areaSearch)
        self.issiSearchSwitch = QCheckBox('search for ISSIs', self)
        self.issiSearchSwitch.stateChanged.connect(self.issiSearch)
        self.googleEarthInstalled = QCheckBox('Plot to Google Earth')
        self.googleEarthInstalled.stateChanged.connect(self.googleEarth)
        self.googleEarthInstalled.toggle()
        self.includeissiswitch = QCheckBox('Include Range', self)
        self.includeissiswitch.stateChanged.connect(self.includes)
        self.excludeissiswitch = QCheckBox('Exclude Range', self)
        self.excludeissiswitch.stateChanged.connect(self.excludes)

        # List Fields
        self.issiList = QListWidget()
        self.issiList.setToolTip(
            'Single Click to show details\nDouble Click to add to ISSI search')
        self.issiList.currentItemChanged.connect(self.onIssiClick)
        self.issiList.itemDoubleClicked.connect(self.onissidoubleclick)
        self.detailsList = QListWidget()
        self.detailsList.setToolTip('Double Click to plot on Google Maps')
        self.detailsList.itemDoubleClicked.connect(self.onDetailDoubleClick)

        # Labels
        self.latLabel = QLabel('Latitude: ')
        self.lonLabel = QLabel('Longitude: ')
        self.distLabel = QLabel('Search Radius (km): ')
        self.starttimeLabel = QLabel('Start Time: ')
        self.stoptimeLabel = QLabel('Stop Time: ')
        self.issilabel = QLabel('ISSI Results')
        self.detailslabel = QLabel(
            'Details [ISSI, Time, Latitude, Longitude, Speed, Heading, Distance from search, Location]'
        )

        # Lines
        self.line = QFrame()
        self.line.setFrameShape(QFrame.HLine)
        self.line.setFrameShadow(QFrame.Sunken)
        self.line1 = QFrame()
        self.line1.setFrameShape(QFrame.HLine)
        self.line1.setFrameShadow(QFrame.Sunken)
        self.line2 = QFrame()
        self.line2.setFrameShape(QFrame.HLine)
        self.line2.setFrameShadow(QFrame.Sunken)
        self.line3 = QFrame()
        self.line3.setFrameShape(QFrame.HLine)
        self.line3.setFrameShadow(QFrame.Sunken)

        # Text Fields
        self.csvFileName = QLineEdit('No Files loaded')
        self.startTime = QLineEdit('Start Time')
        self.stopTime = QLineEdit('Stop Time')
        self.lat = QLineEdit('57.148778')
        self.lat.setDisabled(True)
        self.lon = QLineEdit('-2.095077')
        self.lon.setDisabled(True)
        self.distance = QLineEdit('2.5')
        self.distance.setDisabled(True)
        self.issi = QLineEdit()
        self.issi.setDisabled(True)
        self.includeissi = QLineEdit('677;6780;6785')
        self.includeissi.setToolTip('3 or 4 digits separated by ;')
        self.includeissi.setDisabled(True)
        self.excludeissi = QLineEdit('688;666')
        self.excludeissi.setToolTip('3 or 4 digits separated by ;')
        self.excludeissi.setDisabled(True)

        # Progress Bar
        self.progress = QProgressBar()
        self.progress.setRange(0, 100)
        self.progress.setValue(0)

        self.hbox_load_files = QHBoxLayout()
        self.hbox_load_files.addWidget(self.openFileBtn, 1)
        self.hbox_load_files.addWidget(self.csvFileName, 5)
        self.hbox_search_time = QHBoxLayout()
        self.hbox_times = QHBoxLayout()
        self.hbox_search_time.addWidget(self.resetTimeBtn, 1)
        self.hbox_times.addWidget(self.starttimeLabel)
        self.hbox_times.addWidget(self.startTime)
        self.hbox_times.addWidget(self.stoptimeLabel)
        self.hbox_times.addWidget(self.stopTime)
        self.hbox_times.addStretch(1)
        self.hbox_search_time.addLayout(self.hbox_times, 5)

        self.hbox_search_area = QHBoxLayout()
        self.hbox_search_area.addWidget(self.areaSearchSwitch)
        self.hbox_search_area.addStretch(1)
        self.hbox_search_area.addWidget(self.latLabel)
        self.hbox_search_area.addWidget(self.lat)
        self.hbox_search_area.addWidget(self.lonLabel)
        self.hbox_search_area.addWidget(self.lon)
        self.hbox_search_area.addWidget(self.distLabel)
        self.hbox_search_area.addWidget(self.distance)
        self.hbox_serach_issi = QHBoxLayout()
        self.hbox_serach_issi.addWidget(self.issiSearchSwitch)
        self.hbox_serach_issi.addWidget(self.issi, 1)
        self.hbox_detail_labels = QHBoxLayout()
        self.hbox_detail_labels.addWidget(self.issilabel, 1)
        self.hbox_detail_labels.addWidget(self.detailslabel, 5)
        self.hbox_results = QHBoxLayout()
        self.hbox_results.addWidget(self.issiList, 1)
        self.hbox_results.addWidget(self.detailsList, 5)
        self.hbox_plot_results = QHBoxLayout()
        self.hbox_plot_results.addWidget(self.googleEarthInstalled)
        self.hbox_plot_results.addWidget(self.plotSelectionBtn)
        self.hbox_plot_results.addWidget(self.plotAllBtn)
        self.hbox_plot_results.addWidget(self.saveDataBtn)
        self.hbox_plot_results.addWidget(self.openResultsFolder)
        self.hbox_progress_bar = QHBoxLayout()
        self.hbox_progress_bar.addWidget(self.stopPlotBtn)
        self.hbox_progress_bar.addWidget(self.progress)
        self.hbox_filters = QHBoxLayout()
        self.hbox_filters.addWidget(self.includeissiswitch)
        self.hbox_filters.addWidget(self.includeissi)
        self.hbox_filters.addWidget(self.excludeissiswitch)
        self.hbox_filters.addWidget(self.excludeissi)

        # Create Vbox
        self.vbox = QVBoxLayout()
        self.vbox.addLayout(self.hbox_load_files)
        self.vbox.addLayout(self.hbox_search_time)
        self.vbox.addWidget(self.line)
        self.vbox.addLayout(self.hbox_search_area)
        self.vbox.addWidget(self.line1)
        self.vbox.addLayout(self.hbox_filters)
        self.vbox.addLayout(self.hbox_serach_issi)
        self.vbox.addWidget(self.line2)
        self.vbox.addWidget(self.startParseBtn)
        self.vbox.addLayout(self.hbox_detail_labels)
        self.vbox.addLayout(self.hbox_results, 1)
        self.vbox.addLayout(self.hbox_plot_results)
        self.vbox.addLayout(self.hbox_progress_bar)
        self.vbox.addWidget(self.line3)
        self.vbox.addWidget(self.statusBar)

        self.setLayout(self.vbox)

    def open_results_folder(self):
        filepath = os.path.abspath(os.path.dirname(sys.argv[0]))
        resultpath = filepath + '\\results\\'
        os.startfile(resultpath)

    def includes(self, state):
        if state == Qt.Checked:
            self.includeissi.setDisabled(False)
        else:
            self.includeissi.setDisabled(True)

    def excludes(self, state):
        if state == Qt.Checked:
            self.excludeissi.setDisabled(False)
        else:
            self.excludeissi.setDisabled(True)

    def save_data(self):
        current = self.issiList.selectedItems()
        print(current[0].text())
        save_file = QFileDialog.getSaveFileName(
            self, 'Save ISSI File', "results\\{}".format(current[0].text()),
            "Text Files (*.txt);;json Files (*.json);;csv Files (*.csv)")

        print(save_file)
        if save_file[1] == 'json Files (*.json)':
            with open(save_file[0], 'w') as jsonfile:
                json.dump(self.resultDict[current[0].text()], jsonfile)

        if save_file[1] == 'Text Files (*.txt)':
            with open(save_file[0], 'w') as txtfile:
                result_list = []
                for line in self.resultDict[current[0].text()]:
                    result_list.append('{}\n'.format(line))
                txtfile.writelines(result_list)

        if save_file[1] == 'csv Files (*.csv)':
            with open(save_file[0], 'w') as csvfile:
                fieldnames = [
                    'ISSI', 'Time', 'Latitude', 'Longitute', 'Speed',
                    'Heading', 'Distance', 'Location'
                ]
                writer = csv.writer(csvfile, lineterminator='\n')
                writer.writerow(fieldnames)
                writer.writerows(self.resultDict[current[0].text()])

    def showOpenFile(self):
        self.csvList = []
        self.issiList.clear()
        self.detailsList.clear()
        self.plotSelectionBtn.setDisabled(True)
        self.saveDataBtn.setDisabled(True)
        self.plotAllBtn.setDisabled(True)
        fname = QFileDialog.getOpenFileNames(self, 'Open Coordinator CSV file',
                                             "", "CSV Files (*.csv)")

        if fname[0]:

            start_time_text = ""
            end_time_text = ""
            files_text = ""
            latest_end_time = datetime.datetime.strptime(
                '01/01/1970 00:00:00', '%d/%m/%Y %H:%M:%S')
            row_count = 0
            line_fail_count = 0
            for file_id in range(len(fname[0])):
                f = open(fname[0][file_id], 'r')
                if files_text != "":
                    files_text += '; '
                files_text += (fname[0][file_id]).split('/')[-1]

                with f:
                    for row in f:
                        row_count += 1
                        self.csvList.append(row)

                row = 0
                for item in self.csvList:
                    row += 1
                    update = (row / row_count) * 100
                    self.progress.setValue(update)
                    item_list = item.split(',')
                    if item_list[0] == "Node":
                        continue
                    else:
                        try:
                            time_text = datetime.datetime.strptime(
                                item_list[2], '%d/%m/%Y %H:%M:%S')
                        except:
                            line_fail_count += 1
                            continue
                        if start_time_text == "":
                            start_time_text = item_list[2]
                        else:
                            if time_text > latest_end_time:
                                latest_end_time = time_text
                                end_time_text = item_list[2]

                self.fileStartTime = start_time_text
                self.fileStopTime = end_time_text
                self.startTime.setText(self.fileStartTime)
                self.stopTime.setText(self.fileStopTime)

                self.csvFileName.setText(files_text)
                self.statusBar.showMessage(
                    'File Loaded, contains {} lines, with {} bad row(s)'.
                    format(row_count, line_fail_count))
                self.startParseBtn.setDisabled(False)
                self.resetTimeBtn.setDisabled(False)
                print(line_fail_count)

        else:
            pass

    def parseFile(self):
        self.plotSelectionBtn.setDisabled(True)
        self.saveDataBtn.setDisabled(True)
        self.plotAllBtn.setDisabled(True)
        self.progress.setValue(0)
        self.issiList.clear()
        self.detailsList.clear()
        distance = 0
        searchlat = 0
        searchlon = 0
        starttime = datetime.datetime.strptime(self.startTime.text(),
                                               '%d/%m/%Y %H:%M:%S')
        stoptime = datetime.datetime.strptime(self.stopTime.text(),
                                              '%d/%m/%Y %H:%M:%S')
        issilist = []
        includeslist = []
        excludeslist = []
        area_switch = False
        issi_switch = False
        includes = False
        excludes = False

        if self.areaSearchSwitch.checkState() == Qt.Checked:
            area_switch = True
            distance = float(self.distance.text())
            searchlat = float(self.lat.text())
            searchlon = float(self.lon.text())
        if self.issiSearchSwitch.checkState() == Qt.Checked:
            issi_switch = True
            issilist = self.issi.text().split(';')
        if self.includeissiswitch.checkState() == Qt.Checked:
            includes = True
            includeslist = self.includeissi.text().split(';')
        if self.excludeissiswitch.checkState() == Qt.Checked:
            excludes = True
            excludeslist = self.excludeissi.text().split(';')

        self.parse_file = ParseFile(self.csvList, starttime, stoptime,
                                    distance, searchlat, searchlon, issilist,
                                    area_switch, issi_switch, includes,
                                    includeslist, excludes, excludeslist)

        self.parse_file.parse_message_signal.connect(self.parse_update)
        self.parse_file.parse_progress_signal.connect(self.parse_update)
        self.parse_file.parse_result_dict_signal.connect(self.parse_update)
        self.parse_file.parse_result_list_signal.connect(self.parse_update)
        self.parse_file.start()

    def parse_update(self, value):
        if isinstance(value, int):
            self.progress.setValue(value)
        if isinstance(value, str):
            self.statusBar.showMessage(value)
        if isinstance(value, list):
            for i in value:
                self.issiList.addItem(i)
        if isinstance(value, dict):
            self.resultDict = value

    def onResetTimes(self):
        self.startTime.setText(self.fileStartTime)
        self.stopTime.setText(self.fileStopTime)

    def areaSearch(self, state):

        if state != Qt.Checked:
            self.lat.setDisabled(True)
            self.lon.setDisabled(True)
            self.distance.setDisabled(True)
        else:
            self.lat.setDisabled(False)
            self.lon.setDisabled(False)
            self.distance.setDisabled(False)

    def issiSearch(self, state):
        if state != Qt.Checked:
            self.issi.setDisabled(True)
        else:
            self.issi.setDisabled(False)

    def googleEarth(self, state):
        if state != Qt.Checked:
            self.openGoogleEarth = False
        else:
            self.openGoogleEarth = True

    def onIssiClick(self, current, previous):
        self.detailsList.clear()
        if current != None:
            for x in range(0, len(self.resultDict[current.text()])):
                self.detailsList.addItem('{}'.format(
                    self.resultDict[current.text()][x]))
        self.plotSelectionBtn.setDisabled(False)
        self.saveDataBtn.setDisabled(False)
        self.plotAllBtn.setDisabled(False)
        self.openResultsFolder.setDisabled(False)

    def onissidoubleclick(self, state):
        currentissi = self.issi.text()
        if currentissi != "":
            currentissi += ";"
        currentissi = currentissi + state.text()
        self.issi.setText(currentissi)

    def onDetailDoubleClick(self, state):
        lat = ast.literal_eval(state.text())[2]
        lon = ast.literal_eval(state.text())[3]
        url = "https://www.google.com/maps/search/?api=1&query={},{}".format(
            lat, lon)
        webbrowser.open(url)

    def onPlotFile(self):
        self.progress.setValue(0)
        self.stopPlotBtn.setDisabled(False)
        sender = self.sender()
        issilist = []
        gps = [0]
        if self.areaSearchSwitch.checkState() == Qt.Checked:
            gps = [self.lat.text(), self.lon.text(), self.distance.text()]

        if sender.text() == "Plot all ISSI's (caution)":
            for key in sorted(self.resultDict.keys()):
                issilist.append(key)
        else:
            issilist.append(self.issiList.currentItem().text())

        self.plot_thread = PlotFiles(self.resultDict, issilist,
                                     self.openGoogleEarth, gps)
        self.plot_thread.progressSignal.connect(self.updateprogress)
        self.plot_thread.threadMessage.connect(self.updateprogress)
        self.plot_thread.start()

    def stopThread(self):
        self.plot_thread.stop()
        self.statusBar.showMessage('Plot stopped')

    def updateprogress(self, value):

        if isinstance(value, str):
            self.statusBar.showMessage(value)
            self.stopPlotBtn.setDisabled(True)
        else:
            self.progress.setValue(value)
Esempio n. 32
0
class FieldEdit(QWidget):
    valueChanged = QtCore.pyqtSignal()

    def __init__(self, svd_field):
        QWidget.__init__(self)
        self.svd = svd_field
        self.horiz_layout = QHBoxLayout(self)
        self.horiz_layout.setContentsMargins(0, 0, 0, 0)
        self.horiz_layout.setSpacing(6)
        if self.svd["access"] == "read-only":
            self.is_enabled = False
        else:
            self.is_enabled = True

        self.num_bwidth = self.svd["msb"] - self.svd["lsb"] + 1

        if self.num_bwidth == 1:
            self.chbox_val = QCheckBox(self)
            self.chbox_val.setEnabled(self.is_enabled)
            self.chbox_val.setMaximumSize(QtCore.QSize(16777215, 20))
            self.chbox_val.stateChanged.connect(
                self.handle_field_value_changed)
            self.horiz_layout.addWidget(self.chbox_val)
        else:
            self.nedit_val = NumEdit(self.num_bwidth)
            self.nedit_val.setEnabled(self.is_enabled)
            self.nedit_val.editingFinished.connect(
                self.handle_field_value_changed)
            self.nedit_val.setMaximumSize(QtCore.QSize(16777215, 20))
            self.horiz_layout.addWidget(self.nedit_val)

        if self.svd["enums"]:
            self.is_enums = True
            self.combo_enum = QComboBox(self)
            self.combo_enum.setEnabled(self.is_enabled)
            self.combo_enum.currentIndexChanged.connect(
                self.handle_enum_value_changed)
            self.combo_enum.values = []
            for enum in self.svd["enums"]:
                self.combo_enum.values += [int(enum["value"])]
                self.combo_enum.addItem(
                    "(0x%x) %s : %s" %
                    (int(enum["value"]), enum["name"], enum["description"]))
            self.combo_enum.setMaximumSize(QtCore.QSize(16777215, 20))
            self.horiz_layout.addWidget(self.combo_enum)
            if self.num_bwidth == 1:
                self.chbox_val.setMaximumSize(QtCore.QSize(320, 20))
            else:
                self.nedit_val.setMaximumSize(QtCore.QSize(320, 20))
        else:
            self.is_enums = False

    # -- Slots --
    def handle_field_value_changed(self, value=None):
        if self.is_enums:
            try:
                if self.val() != self.combo_enum.values[
                        self.combo_enum.currentIndex()]:
                    self.combo_enum.setCurrentIndex(
                        self.combo_enum.values.index(self.val()))
            except ValueError:
                self.combo_enum.setCurrentIndex(-1)
        self.valueChanged.emit()

    def handle_enum_value_changed(self, currentIndex):
        if self.is_enums and currentIndex != -1:
            if self.val() != self.combo_enum.values[currentIndex]:
                self.setVal(self.combo_enum.values[currentIndex])

    # -- API --
    def val(self):
        if self.num_bwidth == 1:
            if self.chbox_val.checkState():
                return 1
            else:
                return 0
        else:
            return self.nedit_val.num()

    def setVal(self, val):
        if self.num_bwidth == 1:
            if val:
                self.chbox_val.setCheckState(QtCore.Qt.Checked)
            else:
                self.chbox_val.setCheckState(QtCore.Qt.Unchecked)
        else:
            self.nedit_val.setNum(val)
        self.handle_field_value_changed()
Esempio n. 33
0
class schema_target(QDialog):
    def setupUi(self):
        # self.Dialog = Dialog
        self.setWindowTitle("层指标")
        # self.resize(400, 300)
        self.setFixedSize(400, 200)
        grid = QGridLayout()
        grid.setSpacing(10)

        py_dir_label = QLabel("py文件夹:")
        self.py_dir_edit = QLineEdit()
        py_dir_button = QPushButton("选择文件")

        self.qc_group_by = QCheckBox("group by 字段")
        self.qc_temp_table = QCheckBox("临时表个数")
        self.qc_join = QCheckBox("join个数")
        self.qc_origin_target_table = QCheckBox("源表和目标表")
        self.qc_sql_func = QCheckBox("sql函数个数")
        self.qc_all = QCheckBox("反选")
        py_dir_button.clicked.connect(self.get_py_dir)
        self.qc_all.clicked.connect(self.chang_status)

        comfirm_button = QPushButton("运行")
        quit_button = QPushButton("退出")

        comfirm_button.clicked.connect(self.run)
        quit_button.clicked.connect(self.close)

        grid.addWidget(py_dir_label, 1, 0)
        grid.addWidget(self.py_dir_edit, 1, 1)
        grid.addWidget(py_dir_button, 1, 2)

        grid.addWidget(self.qc_group_by, 2, 0)
        grid.addWidget(self.qc_temp_table, 2, 2)
        # grid.addWidget(ddl_button, 2, 2)

        grid.addWidget(self.qc_join, 3, 0)
        grid.addWidget(self.qc_origin_target_table, 3, 2)
        # grid.addWidget(py_dir_button, 3, 2)
        grid.addWidget(self.qc_sql_func, 4, 0)
        grid.addWidget(self.qc_all, 4, 2)

        grid.addWidget(comfirm_button, 5, 0)
        grid.addWidget(quit_button, 5, 1)
        self.setLayout(grid)
        self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)  #设置窗体总显示在最上面
        # self.retranslateUi(Dialog)
        # Dialog.setWindowModality(Qt.ApplicationModal)
        self.exec_()
        QtCore.QMetaObject.connectSlotsByName(self)

    def chang_status(self, ):
        self.qc_group_by.setChecked(
            True if self.qc_group_by.checkState() == Qt.Unchecked else False
        )  # if self.qc_group_by.checkState() == Qt.Unchecked else False
        self.qc_temp_table.setChecked(
            True if self.qc_temp_table.checkState() == Qt.Unchecked else False)
        self.qc_join.setChecked(True if self.qc_join.checkState() ==
                                Qt.Unchecked else False)
        self.qc_origin_target_table.setChecked(
            True if self.qc_origin_target_table.checkState() ==
            Qt.Unchecked else False)
        self.qc_sql_func.setChecked(True if self.qc_sql_func.checkState() ==
                                    Qt.Unchecked else False)
        # print(self.qc_all.get())
    def get_py_dir(self, ):
        dir_name = QFileDialog.getExistingDirectory(None, 'Open file', r'c:\\')
        # print(dir_name)
        self.py_dir_edit.setText(dir_name)

    def run(self):
        try:
            obj = statistics_target()
            dir_name = self.py_dir_edit.text()
            if self.qc_group_by.checkState() == Qt.Checked:
                obj.get_statistics_group_by_count(dir_name)
            if self.qc_join.checkState() == Qt.Checked:
                obj.get_statistics_join_count(dir_name)
            if self.qc_temp_table.checkState() == Qt.Checked:
                obj.get_statistics_temp_table_count(dir_name)
            if self.qc_sql_func.checkState() == Qt.Checked:
                obj.get_statistics_sql_function_count(dir_name)
            if self.qc_origin_target_table.checkState() == Qt.Checked:
                obj.get_statistics_origin_target_table(dir_name)
            QMessageBox.information(self, '提示', '程序执行成功')
        except Exception as e:
            QMessageBox.critical(self, '错误', f"错误信息为{e}")
Esempio n. 34
0
class AdupUI(QMainWindow):
    """ADUP View (GUI)."""
    def __init__(self, controller):
        #View initializer
        super().__init__()
        self._controller = controller
        # Set some main window's properties
        self.setWindowTitle('User Creator')
        self.setFixedSize(400, 500)
        self.general_layout = QVBoxLayout()
        # Set the central widget which is the parent for the rest of the gui components
        self._central_widget = QWidget(self)
        self.setCentralWidget(self._central_widget)
        self._central_widget.setLayout(self.general_layout)
        #Create the main form
        self._create_main_form()
        self._create_checkboxes()
        self._create_buttons()
        self.detect_button_click()
        self.detect_text_changes()
        self.set_company_combobox()
        self.detect_combobox_change()
        self.set_ou_combobox()

    def _create_main_form(self):
        #Create the main form
        self.main_form_layout = QFormLayout()
        #Create the form's widgets
        self.fn_line_edit = QLineEdit()
        self.sn_line_edit = QLineEdit()
        self.dn_line_edit = QLineEdit()
        self.pre2k_line_edit = QLineEdit()
        self.uln_line_edit = QLineEdit()
        self.company_combobox = QComboBox()
        self.dept_combobox = QComboBox()
        self.job_title_combobox = QComboBox()
        self.mngr_line_edit = QLineEdit()
        self.mngr_check_btn = QPushButton("Check Manager Pre2k Name", self)
        self.emp_no_line_edit = QLineEdit()
        self.psswd_line_edit = QLineEdit()
        #Set the password to hidden
        self.psswd_line_edit.setEchoMode(QLineEdit.Password)
        self.org_unit_combobox = QComboBox()
        self.get_org_unit_btn = QPushButton()
        #Add widgets to form
        self.main_form_layout.addRow(QLabel("First Name: *"), self.fn_line_edit)
        self.main_form_layout.addRow(QLabel("Surname: *"), self.sn_line_edit)
        self.main_form_layout.addRow(QLabel("Display Name: *"), self.dn_line_edit)
        self.main_form_layout.addRow(QLabel("Pre 2k Logon Name: *"), self.pre2k_line_edit)
        self.main_form_layout.addRow(QLabel("User Logon Name: *"), self.uln_line_edit)
        self.main_form_layout.addRow(QLabel("Company: *"), self.company_combobox)
        self.main_form_layout.addRow(QLabel("Department: *"), self.dept_combobox)
        self.main_form_layout.addRow(QLabel("Job Title: *"), self.job_title_combobox)
        self.main_form_layout.addRow(QLabel("Manager: *"), self.mngr_line_edit)
        self.mngr_exists_lbl = QLabel("")
        self.main_form_layout.addRow(self.mngr_check_btn, self.mngr_exists_lbl)
        self.main_form_layout.addRow(QLabel("Employee Number:"), self.emp_no_line_edit)
        self.main_form_layout.addRow(QLabel("Password: *"), self.psswd_line_edit)
        self.main_form_layout.addRow(QLabel("Organisational Unit:"), self.org_unit_combobox)
        #Add this form layout to the main layout
        self.general_layout.addLayout(self.main_form_layout)

    def _create_checkboxes(self):
        self.checkbox_layout = QVBoxLayout()
        #Create checkbox widgets
        self.change_psswd = QCheckBox("Change Password at Next Logon")
        self.psswd_no_expire = QCheckBox("Password Never Expires")
        #set checkboxes to checked
        self.change_psswd.setChecked(True)
        self.psswd_no_expire.setChecked(True)
        #Add checkboxes to form
        self.checkbox_layout.addWidget(self.change_psswd)
        self.checkbox_layout.addWidget(self.psswd_no_expire)
        #Add to the main layout
        self.general_layout.addLayout(self.checkbox_layout)

    def _create_buttons(self):
        self.buttons_layout = QFormLayout()
        #Create the widgets
        self.check_duplicate_btn = QPushButton("Check for duplicates", self)
        self.check_duplicate_lbl = QLabel("")
        self.create_powershell_btn = QPushButton("Create Powershell Cmd", self)
        self.create_powershell_command_result_line_edit = QLineEdit()
        self.create_powershell_command_result_line_edit.setReadOnly(True)
        self.create_user_btn = QPushButton("Create User", self)
        #button set to disabled until conditions are met
        self.create_user_btn.setEnabled(False)
        #Add buttons to form
        self.buttons_layout.addRow(self.check_duplicate_btn, self.check_duplicate_lbl)
        self.buttons_layout.addRow(self.create_powershell_btn, self.create_powershell_command_result_line_edit)
        self.buttons_layout.addRow(self.create_user_btn)
        #Add to the main layout
        self.general_layout.addLayout(self.buttons_layout)

    def detect_combobox_change(self):
        """Detect changes to the comboboxes and call a function sending combobox text"""
        self.company_combobox.currentTextChanged.connect(self.set_department_combobox)
        self.dept_combobox.currentTextChanged.connect(self.set_job_combobox)

    def set_company_combobox(self):
        """Set the company combobox values"""
        companies = self._controller.get_companies()
        self.company_combobox.addItems(companies)

    def set_department_combobox(self):
        """Set the department combobox values"""
        #Clears the box if the user changes their mind
        self.dept_combobox.clear()
        departments = self._controller.get_next_combo_element(self.company_combobox.currentText(), 'company')
        self.dept_combobox.addItems(departments)

    def set_job_combobox(self):
        """Set the Job combobox values"""
        #Clears the box if the user changes their mind
        self.job_title_combobox.clear()
        jobs = self._controller.get_next_combo_element(self.dept_combobox.currentText(), 'department', self.company_combobox.currentText(), self.dept_combobox.currentIndex())
        self.job_title_combobox.addItems(jobs)

    def set_ou_combobox(self):
        """Set the OU combobox values"""
        try:
            self.org_unit_combobox.addItems(self._controller.get_ou_structure())
        except Exception as e:
            print("Unable to query OU structure")
            print(e)

    def detect_text_changes(self):
        """Detect when a form item changes and call the mandatory field check"""
        self.fn_line_edit.textChanged.connect(self.check_mandatory_fields)
        self.sn_line_edit.textChanged.connect(self.check_mandatory_fields)
        self.dn_line_edit.textChanged.connect(self.check_mandatory_fields)
        self.pre2k_line_edit.textChanged.connect(self.check_mandatory_fields)
        self.uln_line_edit.textChanged.connect(self.check_mandatory_fields)
        self.company_combobox.currentIndexChanged.connect(self.check_mandatory_fields)
        self.dept_combobox.currentIndexChanged.connect(self.check_mandatory_fields)
        self.job_title_combobox.currentIndexChanged.connect(self.check_mandatory_fields)
        self.mngr_line_edit.textChanged.connect(self.check_mandatory_fields)
        self.psswd_line_edit.textChanged.connect(self.check_mandatory_fields)
        self.org_unit_combobox.currentIndexChanged.connect(self.check_mandatory_fields)

    def detect_button_click(self):
        """Detects when a button is pressed and sends to controller"""
        self.create_powershell_btn.clicked.connect(self.create_powershell_command)
        self.create_user_btn.clicked.connect(self.create_user)
        self.check_duplicate_btn.clicked.connect(self.check_duplicate_usr)
        self.mngr_check_btn.clicked.connect(self.check_manager_exists)

    def check_mandatory_fields(self):
        """Detects if the mandatory fields are filled, if not the create user button will be deactivated"""
        if(self.fn_line_edit.text() != '' and self.sn_line_edit.text() and self.dn_line_edit.text() != '' and self.pre2k_line_edit.text() != '' and self.uln_line_edit.text() != '' and  self.company_combobox.currentText != '' and self.dept_combobox.currentText != '' and self.job_title_combobox.currentText != '' and self.mngr_line_edit.text() != '' and self.psswd_line_edit.text() != '' and self.org_unit_combobox.currentText != ''):
            self.create_user_btn.setEnabled(True)
        else:
            self.create_user_btn.setEnabled(False)

    def check_duplicate_usr(self):
        """Checks if the filled in SAM name matches an existing user"""
        user_exists = self._controller.usr_exist_check(self.pre2k_line_edit.text(), self.uln_line_edit.text())

        if user_exists == True:
            self.check_duplicate_lbl.setText("User exists")
            self.check_duplicate_lbl.setStyleSheet("color: red;")
        else:
            self.check_duplicate_lbl.setText("User does not exist")
            self.check_duplicate_lbl.setStyleSheet("color: green;")

    def check_manager_exists(self):
        """Checks if the manager exists"""
        
        try:
            user_exists = self._controller.usr_exist_check(self.mngr_line_edit.text())
        except Exception as e:
            print(e)

        if user_exists == True:
            self.mngr_exists_lbl.setText("Manager Exists")
            self.mngr_exists_lbl.setStyleSheet("color: green;")
        else:
            self.mngr_exists_lbl.setText("Manager Does Not Exist")
            self.mngr_exists_lbl.setStyleSheet("color: red;")



    def create_powershell_command(self):
        """Create the user creation Powershell command"""        
        command = self._controller.create_user_command(self.fn_line_edit.text(), self.sn_line_edit.text(), self.dn_line_edit.text(), self.pre2k_line_edit.text(), self.uln_line_edit.text(), self.company_combobox.currentText(), self.dept_combobox.currentText(), self.job_title_combobox.currentText(), self.mngr_line_edit.text(), self.org_unit_combobox.currentText(), self.psswd_line_edit.text(), self.change_psswd.checkState(), self.psswd_no_expire.checkState())
        
        #Clear line edit before filling it 
        self.create_powershell_command_result_line_edit.clear()
        self.create_powershell_command_result_line_edit.setText(command)

    def create_user(self):
        """Get create user command and create user"""
        command = self._controller.create_user_command(self.fn_line_edit.text(), self.sn_line_edit.text(), self.dn_line_edit.text(), self.pre2k_line_edit.text(), self.uln_line_edit.text(), self.company_combobox.currentText(), self.dept_combobox.currentText(), self.job_title_combobox.currentText(), self.mngr_line_edit.text(), self.org_unit_combobox.currentText(), self.psswd_line_edit.text(), self.change_psswd.checkState(), self.psswd_no_expire.checkState())

        try:
            self._controller.create_user(command)
        except Exception as e:
            print(e)
Esempio n. 35
0
class MiniViewer(QWidget):
    """MiniViewer that allows to rapidly visualize scans either with a single
    image per scan with cursors to move in five dimensions or with all images
    of the greater dimension of the scan.

    When the latter is selected, the displayed images depends on their
    dimension:

        - 3D: display all the slices.
        - 4D: display the middle slice of the third dimension for each time
           of the fourth dimension.
        - 5D: display the middle slice of the third dimension for the first
           time of the fourth dimension for each time of the fifth dimension.

    Note:
        - idx corresponds to the index of the displayed image
        - idx in [0, self.max_scans]
        - most of the class's attributes are lists of 0 to self.max_scans
           elements

    .. Methods:
        - __init__: initialise the MiniViewer object
        - boxSlider: create sliders, their connections and thumbnail labels
          for a selected index
        - changePosValue: change the value of a cursor for the selected index
        - check_box_cursors_state_changed: updates the config file
        - clearLayouts: clear the final layout
        - create_slider: create a slider
        - createDimensionLabels: create the dimension labels for the
          selected index
        - createFieldValue: create a field where will be displayed the
          position of a cursor
        - createLayouts: create the layouts
        - displayPosValue: display the position of each cursor for the
          selected index
        - enableSliders: enable each slider of the selected index
        - image_to_pixmap: create a 2D pixmap from a N-D Nifti image
        - image2DModifications: apply modifications to the image to
          display it correctly
        - indexImage: update the sliders values depending on the size of
          the selected image
        - navigImage: display the 2D image for the selected index
        - openTagsPopUp: opens a pop-up to select the legend of the thumbnails
        - setThumbnail: set the thumbnail tag value under the image frame
        - show_slices: create the thumbnails from the selected file paths
        - update_nb_slices: update the config file and the thumbnails
        - update_visualization_method: update the config file and the
          thumbnails
        - verify_slices: verify the number of selected documents

    """
    def __init__(self, project):
        """Initialise the MiniViewer object

        :param project: current project in the software

        """
        super().__init__()

        self.project = project
        self.first_time = True

        # The MiniViewer is set hidden to give more space to the data_browser
        self.setHidden(True)

        # When multiple selection, limiting the number of thumbnails to
        # max_scans
        self.max_scans = 4

        # Config that allows to read the software preferences
        self.config = Config()

        # Initializing some components of the MiniViewer
        self.labels = QWidget()
        self.frame = QFrame()
        self.scroll_area = QScrollArea()
        self.scroll_area.setWidget(self.frame)
        self.frame_final = QFrame()

        self.label_nb_slices = QLabel()
        self.label_nb_slices.setText("Maximum number of slices: ")

        self.line_edit_nb_slices = QLineEdit()
        self.line_edit_nb_slices.setText(str(self.config.getNbAllSlicesMax()))
        self.line_edit_nb_slices.returnPressed.connect(self.update_nb_slices)

        # All these objects are depending on the number of scans to visualize
        self.im_2D = []
        self.slider_3D = []
        self.slider_4D = []
        self.slider_5D = []
        self.txt_slider_3D = []
        self.txt_slider_4D = []
        self.txt_slider_5D = []
        self.label3D = []
        self.label4D = []
        self.label5D = []
        self.imageLabel = []
        self.img = []
        self.label_description = []

        # Layouts
        self.createLayouts()
        self.setLayout(self.v_box_final)

        # Checkboxes
        self.check_box_slices = QCheckBox('Show all slices (no cursors)')
        if self.config.getShowAllSlices() == True:
            self.check_box_slices.setCheckState(Qt.Checked)
        else:
            self.check_box_slices.setCheckState(Qt.Unchecked)
        self.check_box_slices.stateChanged.connect(
            self.update_visualization_method)

        self.check_box_cursors = QCheckBox('Chain cursors')
        self.check_box_cursors.setToolTip("Allows to connect all cursors "
                                          "when selecting multiple documents")
        if self.config.getChainCursors() == True:
            self.check_box_cursors.setCheckState(Qt.Checked)
        else:
            self.check_box_cursors.setCheckState(Qt.Unchecked)
        self.check_box_cursors.stateChanged.connect(
            self.check_box_cursors_state_changed)

        self.file_paths = ""

    def boxSlider(self, idx):
        """Define horizontal sliders connections and thumbnail labels.

        :param idx: the selected index
        """
        self.slider_3D.insert(idx, self.create_slider(0, 0, 0))
        self.slider_4D.insert(idx, self.create_slider(0, 0, 0))
        self.slider_5D.insert(idx, self.create_slider(0, 0, 0))

        self.slider_3D[idx].valueChanged.connect(
            partial(self.changePosValue, idx, 1))
        self.slider_4D[idx].valueChanged.connect(
            partial(self.changePosValue, idx, 2))
        self.slider_5D[idx].valueChanged.connect(
            partial(self.changePosValue, idx, 3))

        self.txt_slider_3D.insert(idx, self.createFieldValue())
        self.txt_slider_4D.insert(idx, self.createFieldValue())
        self.txt_slider_5D.insert(idx, self.createFieldValue())

    def check_box_cursors_state_changed(self):
        """Update the config file.

        Called when the state of the checkbox to chain the cursors changes.
        """
        if self.check_box_cursors.checkState() == Qt.Checked:
            self.config.setChainCursors(True)
        elif self.check_box_cursors.checkState() == Qt.Unchecked:
            self.config.setChainCursors(False)

    def clearLayouts(self):
        """Clear the final layout"""

        for i in reversed(range(self.v_box_final.count())):
            if self.v_box_final.itemAt(i).widget() is not None:
                self.v_box_final.itemAt(i).widget().setParent(None)

    def changePosValue(self, idx, cursor_to_change):
        """
        Change the value of a cursor for the selected index.

        :param idx: the selected index
        :param cursor_to_change: the cursor to change (1, 2 or 3)
        """
        # If the "Chain cursors" mode is not selected, there is nothing to do
        if self.check_box_cursors.checkState() == Qt.Unchecked:
            self.navigImage(idx)
        else:
            # Checking with cursor has been modified
            if cursor_to_change == 1:
                cursor = self.slider_3D
            elif cursor_to_change == 2:
                cursor = self.slider_4D
            else:
                cursor = self.slider_5D

            # Loop on the thumbnails
            for idx_loop in range(min(self.max_scans, len(self.file_paths))):
                # Disconnecting the connection when changing other cursors
                # values
                cursor[idx_loop].valueChanged.disconnect()
                # Do something only when the cursor is not the one that has
                # been changed by the user
                if idx_loop != idx:
                    if cursor[idx].value() == cursor[idx].maximum():
                        value = cursor[idx_loop].maximum()

                    elif cursor[idx].value() == cursor[idx].minimum():
                        value = cursor[idx_loop].minimum()

                    else:
                        # Updating the new value as the value of the cursor
                        # that has been changed by the user
                        value = round((cursor[idx_loop].maximum() + 1) *
                                      (cursor[idx].value() + 1) /
                                      max(1, cursor[idx].maximum() + 1))
                        value = min(cursor[idx_loop].maximum(), value - 1)
                        value = max(0, int(value))
                    cursor[idx_loop].setValue(value)

                # Changing the image to show
                self.navigImage(idx_loop)
                # Reconnecting
                cursor[idx_loop].valueChanged.connect(
                    partial(self.changePosValue, idx_loop, cursor_to_change))

    def createDimensionLabels(self, idx):
        """Create the dimension labels for the selected index.

        :param idx: the selected index
        """
        font = QFont()
        font.setPointSize(9)

        self.label3D.insert(idx, QLabel())
        self.label4D.insert(idx, QLabel())
        self.label5D.insert(idx, QLabel())

        self.label3D[idx].setFont(font)
        self.label4D[idx].setFont(font)
        self.label5D[idx].setFont(font)

        self.label3D[idx].setText('3D: ')
        self.label4D[idx].setText('4D: ')
        self.label5D[idx].setText('5D: ')

    def createFieldValue(self):
        """Create a field where will be displayed the position of a cursor.

        :return: the corresponding field
        """
        fieldValue = QLineEdit()
        fieldValue.setEnabled(False)
        fieldValue.setFixedWidth(50)
        fieldValue.setAlignment(Qt.AlignCenter)
        fieldValue.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        font = QFont()
        font.setPointSize(9)
        fieldValue.setFont(font)
        return fieldValue

    def createLayouts(self):
        """Create the layouts."""

        self.h_box_images = QHBoxLayout()
        self.h_box_images.setSpacing(10)
        self.v_box = QVBoxLayout()
        self.v_box_final = QVBoxLayout()
        self.h_box_slider_3D = QHBoxLayout()
        self.h_box_slider_4D = QHBoxLayout()
        self.h_box_slider_5D = QHBoxLayout()
        self.v_box_sliders = QVBoxLayout()
        self.h_box = QHBoxLayout()
        self.h_box_check_box = QHBoxLayout()
        self.v_box_thumb = QVBoxLayout()
        self.h_box_thumb = QHBoxLayout()

    def create_slider(self, maxm=0, minm=0, pos=0):
        """Generate an horizontal slider.

        :param maxm: slider's maximum
        :param minm: slider's minimum
        :param pos: slider's initial value
        :return: the slider object
        """
        slider = QSlider(Qt.Horizontal)
        slider.setFocusPolicy(Qt.StrongFocus)
        slider.setTickInterval(1)
        slider.setMaximum(maxm)
        slider.setMinimum(minm)
        slider.setValue(pos)
        slider.setEnabled(False)
        return slider

    def displayPosValue(self, idx):
        """Display the position of each cursor for the selected index.

        :param idx: the selected index
        """
        self.txt_slider_3D[idx].setText(
            str(self.slider_3D[idx].value() + 1) + ' / ' +
            str(self.slider_3D[idx].maximum() + 1))
        self.txt_slider_4D[idx].setText(
            str(self.slider_4D[idx].value() + 1) + ' / ' +
            str(self.slider_4D[idx].maximum() + 1))
        self.txt_slider_5D[idx].setText(
            str(self.slider_5D[idx].value() + 1) + ' / ' +
            str(self.slider_5D[idx].maximum() + 1))

    def enableSliders(self, idx):
        """Enable all the horizontal slider.

        :param idx: the slider's index
        """
        self.slider_3D[idx].setEnabled(True)
        self.slider_4D[idx].setEnabled(True)
        self.slider_5D[idx].setEnabled(True)

    def image_to_pixmap(self, im, i):
        """Create a 2D pixmap from a N-D Nifti image.

        :param im: Nifti image
        :param i: index of the slide
        :return: the corresponding pixmap
        """

        # The image to display depends on the dimension of the image
        # In the 3D case, each slice is displayed
        if len(im.shape) == 3:
            im_2D = im.get_data()[:, :, i].copy()

        # In the 4D case, each middle slice of the 3D dimension is displayed
        # for each time in the 4D dimension
        elif len(im.shape) == 4:
            im_3D = im.get_data()[:, :, :, i].copy()
            middle_slice = int(im_3D.shape[2] / 2)
            im_2D = im_3D[:, :, middle_slice]

        # In the 5D case, each first time of the 4D dimension and
        # its middle slice of the 3D dimension is displayed
        elif len(im.shape) == 5:
            im_4D = im.get_data()[:, :, :, :, i].copy()
            im_3D = im_4D[:, :, :, 1]
            middle_slice = int(im_3D.shape[2] / 2)
            im_2D = im_3D[:, :, middle_slice]

        else:
            im_2D = [0]

        # Making some pixel modification to display the image correctly
        im_2D = self.image2DModifications(0, im_2D)

        w, h = im_2D.shape

        im_Qt = QImage(im_2D.data, w, h, QImage.Format_Indexed8)
        pixm = QPixmap.fromImage(im_Qt)

        return pixm

    def image2DModifications(self, idx, im2D=None):
        """Apply modifications to display the image correctly.

        :param idx: the selected index
        :param im2D: image to modify
        """

        display_size = (128, 128)
        display_type = np.uint8  # this MUST be an integer data type
        display_pctl = 0.5  # percentile (0.5%) of values to clip at the low and high end of intensities.
        display_max = np.iinfo(display_type).max
        display_min = np.iinfo(display_type).min

        im2d_provided = im2D is not None
        if not im2d_provided:
            im2D = self.im_2D[idx]

        # Resize image first, for three reasons:
        #  1 - it may slightly changes the intensity scale, so re-scaling should be done after this
        #  2 - rescaling before rotation is slightly faster, specially for large images (> display_size).
        #  3 - rescaling may alter the occurrence of nan or infinite values (e.g. an image may become all-nan)
        # anti_aliasing keyword is defined in skimage since version 0.14.0
        if verCmp(sk.__version__, '0.14.0', 'sup'):
            im2D = resize(im2D,
                          display_size,
                          mode='constant',
                          anti_aliasing=False)
        else:
            im2D = resize(im2D, display_size, mode='constant')

        # Rescale image while handling Nans and infinite values
        im_mask = np.isfinite(im2D)
        if np.any(im_mask):  # if we have any finite value to work with
            im2D -= np.percentile(
                im2D[im_mask],
                display_pctl)  # shift the lower percentile chosen to 0.0
            im_max = np.percentile(
                im2D[im_mask],
                100.0 - display_pctl)  # determine max from upper percentile
            if im_max > 0:  # avoid dividing by zero
                im2D *= (display_max -
                         display_min) / im_max  # re-scale to display range
            im2D += display_min  # shift lowest value to lower limit of display range

        np.clip(
            im2D, display_min, display_max,
            im2D)  # clip all values to display range, remove infinite values
        im2D = im2D.astype(
            display_type
        )  # convert to integer display data type. NaNs get converted to 0.

        im2D = np.rot90(im2D, 3).copy(
        )  # Rotate. Copy array to avoid negative strides (Qt doesn't handle that)

        if im2d_provided:
            return im2D
        else:
            self.im_2D[idx] = im2D

    def indexImage(self, idx):
        """Update all slider values according to the size of the current image.

        :param idx: the selected index
        """
        # Getting the sliders value
        sl3D = self.slider_3D[idx].value()
        sl4D = self.slider_4D[idx].value()
        sl5D = self.slider_5D[idx].value()

        # Depending on the dimension, reading the image data and
        # changing the cursors maximum
        if len(self.img[idx].shape) == 3:
            self.im_2D.insert(idx, self.img[idx].get_data()[:, :, sl3D].copy())
            self.slider_3D[idx].setMaximum(self.img[idx].shape[2] - 1)
            self.slider_4D[idx].setMaximum(0)
            self.slider_5D[idx].setMaximum(0)
        if len(self.img[idx].shape) == 4:
            self.im_2D.insert(
                idx, self.img[idx].get_data()[:, :, sl3D, sl4D].copy())
            self.slider_3D[idx].setMaximum(self.img[idx].shape[2] - 1)
            self.slider_4D[idx].setMaximum(self.img[idx].shape[3] - 1)
            self.slider_5D[idx].setMaximum(0)
        if len(self.img[idx].shape) == 5:
            self.im_2D.insert(
                idx, self.img[idx].get_data()[:, :, sl3D, sl4D, sl5D].copy())
            self.slider_3D[idx].setMaximum(self.img[idx].shape[2] - 1)
            self.slider_4D[idx].setMaximum(self.img[idx].shape[3] - 1)
            self.slider_5D[idx].setMaximum(self.img[idx].shape[4] - 1)

    def navigImage(self, idx):
        """Display the 2D image for the selected index.

        :param idx: the selected index
        """
        self.indexImage(idx)
        self.displayPosValue(idx)

        self.image2DModifications(idx)
        w, h = self.im_2D[idx].shape

        image = QImage(self.im_2D[idx].data, w, h, QImage.Format_Indexed8)
        pixm = QPixmap.fromImage(image)
        self.imageLabel[idx].setPixmap(pixm)

    def openTagsPopUp(self):
        """Open a pop-up to select the legend of the thumbnails."""

        self.popUp = PopUpSelectTag(self.project)
        self.popUp.setWindowTitle("Select the image viewer tag")
        if self.popUp.exec_():
            self.verify_slices(self.file_paths)

    def setThumbnail(self, file_path_base_name, idx):
        """Set the thumbnail tag value under the image frame.

        :param file_path_base_name: basename of the selected path
        :param idx: index of the image
        """
        # Looking for the tag value to display as a legend of the thumbnail
        for scan in self.project.session.get_documents_names(
                COLLECTION_CURRENT):
            if scan == file_path_base_name:
                value = self.project.session.get_value(
                    COLLECTION_CURRENT, scan, self.config.getThumbnailTag())
                if value is not None:
                    self.label_description[idx].setText(
                        str(value)[:self.nb_char_max])
                else:
                    self.label_description[idx].setText(
                        data_browser.not_defined_value[:self.nb_char_max])
                self.label_description[idx].setToolTip(
                    os.path.basename(self.config.getThumbnailTag()))

    def show_slices(self, file_paths):
        """Creates the thumbnails from the selected file paths.

        :param file_paths: the selected file paths
        """

        # If it's the first time that this function is called, the MiniViewer
        # has to be shown
        if self.first_time:
            self.setHidden(False)
            self.first_time = False

        # If the user has willingly hidden the MiniViewer, the Processes are
        # not made
        if self.isHidden():
            pass
        else:
            self.do_nothing = [False] * len(file_paths)

            self.file_paths = file_paths
            self.max_scans = len(file_paths)

            self.setMinimumHeight(220)

            self.clearLayouts()

            self.frame = QFrame(self)
            self.frame_final = QFrame(self)

            # Limiting the legend of the thumbnails
            self.nb_char_max = 60

            font = QFont()
            font.setPointSize(9)

            # Reading the images from the file paths
            for idx, file_path in enumerate(self.file_paths.copy()):
                try:
                    self.img.insert(idx, nib.load(file_path))
                except nib.filebasedimages.ImageFileError:
                    print("Error while trying to display the image " +
                          file_path)
                    self.file_paths.remove(file_path)
                except FileNotFoundError:
                    print("File " + file_path + " not existing")
                    self.file_paths.remove(file_path)

            # If we are in the "cursors" display mode
            if self.check_box_slices.checkState() == Qt.Unchecked:

                # Layout to aligne each thumbnail (image + cursors)
                self.h_box_thumb = QHBoxLayout()

                # idx represents the index of the selected image
                for idx in range(min(self.max_scans, len(self.file_paths))):
                    if not self.do_nothing[idx]:

                        # Creating sliders and labels
                        self.boxSlider(idx)
                        self.enableSliders(idx)
                        self.createDimensionLabels(idx)

                        # Getting the sliders value and reading the image data
                        self.indexImage(idx)

                        # Making some pixel modification to display the image
                        # correctly
                        self.image2DModifications(idx)

                    self.displayPosValue(idx)

                    w, h = self.im_2D[idx].shape

                    im_Qt = QImage(self.im_2D[idx].data, w, h,
                                   QImage.Format_Indexed8)
                    pixm = QPixmap.fromImage(im_Qt)

                    file_path_base_name = os.path.basename(
                        self.file_paths[idx])

                    # imageLabel is the label where the image is displayed
                    # (as a pixmap)
                    self.imageLabel.insert(idx, QLabel(self))
                    self.imageLabel[idx].setPixmap(pixm)
                    self.imageLabel[idx].setToolTip(file_path_base_name)

                    self.label_description.insert(idx, ClickableLabel())
                    self.label_description[idx].setFont(font)
                    self.label_description[idx].clicked.connect(
                        self.openTagsPopUp)

                    # Looking for the tag value to display as a
                    # legend of the thumbnail
                    file_path_base_name = os.path.relpath(
                        self.file_paths[idx], self.project.folder)
                    self.setThumbnail(file_path_base_name, idx)

                    # Layout that corresponds to the 3D dimension
                    self.h_box_slider_3D = QHBoxLayout()
                    self.h_box_slider_3D.addWidget(self.label3D[idx])
                    self.h_box_slider_3D.addWidget(self.txt_slider_3D[idx])
                    self.h_box_slider_3D.addWidget(self.slider_3D[idx])

                    # Layout that corresponds to the 4D dimension
                    self.h_box_slider_4D = QHBoxLayout()
                    self.h_box_slider_4D.addWidget(self.label4D[idx])
                    self.h_box_slider_4D.addWidget(self.txt_slider_4D[idx])
                    self.h_box_slider_4D.addWidget(self.slider_4D[idx])

                    # Layout that corresponds to the 5D dimension
                    self.h_box_slider_5D = QHBoxLayout()
                    self.h_box_slider_5D.addWidget(self.label5D[idx])
                    self.h_box_slider_5D.addWidget(self.txt_slider_5D[idx])
                    self.h_box_slider_5D.addWidget(self.slider_5D[idx])

                    # Layout for the three sliders
                    self.v_box_sliders = QVBoxLayout()
                    self.v_box_sliders.addLayout(self.h_box_slider_3D)
                    self.v_box_sliders.addLayout(self.h_box_slider_4D)
                    self.v_box_sliders.addLayout(self.h_box_slider_5D)

                    # Layout that corresponds to the image + the sliders
                    self.h_box = QHBoxLayout()
                    self.h_box.addWidget(self.imageLabel[idx])
                    self.h_box.addLayout(self.v_box_sliders)

                    # Layout that corresponds to the image and sliders +
                    # the description
                    self.v_box_thumb = QVBoxLayout()
                    self.v_box_thumb.addLayout(self.h_box)
                    self.v_box_thumb.addWidget(self.label_description[idx])

                    # Layout that will contain all the thumbnails
                    self.h_box_thumb.addLayout(self.v_box_thumb)

                self.frame.setLayout(self.h_box_thumb)

            # If we are in the "all slices" display mode
            else:

                self.h_box_images = QHBoxLayout()
                self.h_box_images.setSpacing(10)
                self.v_box_scans = QVBoxLayout()

                # idx represents the index of the selected image
                for idx in range(len(self.file_paths)):
                    file_path_base_name = os.path.relpath(
                        self.file_paths[idx], self.project.folder)

                    self.label_description.insert(idx, ClickableLabel())
                    self.label_description[idx].setFont(font)
                    self.label_description[idx].clicked.connect(
                        self.openTagsPopUp)

                    # Looking for the tag value to display as a legend
                    # of the thumbnail
                    self.setThumbnail(file_path_base_name, idx)

                    # Depending of the dimension of the image,
                    # the legend of each image and the number of images to
                    # display will change
                    if not self.do_nothing[idx]:
                        if len(self.img[idx].shape) == 3:
                            nb_slices = self.img[idx].shape[2]
                            txt = "Slice n°"
                        elif len(self.img[idx].shape) == 4:
                            nb_slices = self.img[idx].shape[3]
                            txt = "Time n°"
                        elif len(self.img[idx].shape) == 5:
                            nb_slices = self.img[idx].shape[4]
                            txt = "Study n°"
                        else:
                            nb_slices = 0

                        # Limiting the number of images to the number
                        # chosen by the user
                        for i in range(
                                min(nb_slices,
                                    int(self.line_edit_nb_slices.text()))):
                            pixm = self.image_to_pixmap(self.img[idx], i)

                            self.v_box = QVBoxLayout()

                            # label corresponds to the label where one image
                            # is displayed
                            label = QLabel(self)
                            label.setPixmap(pixm)
                            label.setToolTip(
                                os.path.basename(self.file_paths[idx]))

                            # Legend of the image (depends on the number
                            # of dimensions)
                            label_info = QLabel()
                            label_info.setFont(font)
                            label_info.setText(txt + str(i + 1))
                            label_info.setAlignment(QtCore.Qt.AlignCenter)

                            self.v_box.addWidget(label)
                            self.v_box.addWidget(label_info)

                            # This layout allows to chain each image
                            self.h_box_images.addLayout(self.v_box)
                        self.v_box_scans.addLayout(self.h_box_images)
                        self.v_box_scans.addWidget(self.label_description[idx])
                self.frame.setLayout(self.v_box_scans)

            # Adding a scroll area if the thumbnails are too large
            self.scroll_area = QScrollArea()
            self.scroll_area.setWidget(self.frame)

            self.h_box_check_box = QHBoxLayout()

            if self.check_box_slices.isChecked():
                self.h_box_check_box.addStretch(1)
                self.label_nb_slices.setHidden(False)
                self.line_edit_nb_slices.setHidden(False)
                self.h_box_check_box.addWidget(self.label_nb_slices)
                self.h_box_check_box.addWidget(self.line_edit_nb_slices)
                self.check_box_cursors.setHidden(True)
            else:
                self.check_box_cursors.setHidden(False)
                self.h_box_check_box.addWidget(self.check_box_cursors)
                self.h_box_check_box.addStretch(1)
                self.label_nb_slices.setHidden(True)
                self.line_edit_nb_slices.setHidden(True)

            self.h_box_check_box.addWidget(self.check_box_slices)

            self.v_box_final.addLayout(self.h_box_check_box)
            self.v_box_final.addWidget(self.scroll_area)

    def update_nb_slices(self):
        """Update the config file and the thumbnails.

        Called when the number of slices to visualize changes.
        """
        nb_slices = self.line_edit_nb_slices.text()
        self.config.setNbAllSlicesMax(nb_slices)
        self.verify_slices(self.file_paths)

    def update_visualization_method(self):
        """Update the config file and the thumbnails.

        Called when the state of the checkbox to show all slices changes.
        """
        if self.check_box_slices.checkState() == Qt.Checked:
            self.config.setShowAllSlices(True)
        elif self.check_box_slices.checkState() == Qt.Unchecked:
            self.config.setShowAllSlices(False)
        self.verify_slices(self.file_paths)

    def verify_slices(self, file_paths):
        """Make 'Show all slices' checkbox unclickable if len(file_paths) > 1.

        :param file_paths: the selected documents
        """
        # Updating the config
        self.config = Config()
        if len(file_paths) > 1:
            self.config.setShowAllSlices(False)
            self.check_box_slices.setCheckState(Qt.Unchecked)
            self.check_box_slices.setCheckable(False)
        else:
            self.check_box_slices.setCheckable(True)
        self.show_slices(file_paths)
class MikochikuAlarm(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.search_ch_id = settings.CHID
        self.old_video_id_list = []
        self.initUI()

    def initUI(self):

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.check_live)
        self.timer.setInterval(40000)
        self.timer.start()

        label = QLabel(self)
        label.setPixmap(QPixmap(resource_path(settings.ICON)))
        label.move(60, 70)

        self.language_cmb = QComboBox(self)
        self.language_cmb.move(180, 122)
        self.language_cmb.addItem("language")
        self.language_cmb.addItem("日本語")
        self.language_cmb.addItem("中文")
        self.language_cmb.addItem("English")
        self.language_cmb.currentTextChanged.connect(self.on_combobox_changed)

        self.alarm_cb = QCheckBox(
            self.get_text(self.get_locale_json(), "alarm"), self)
        self.alarm_cb.move(20, 20)
        self.alarm_cb.toggle()

        # self.loop_cb = QCheckBox('アラームをループ再生する', self)
        # self.loop_cb.move(20, 40)
        # self.loop_cb.toggle()

        self.webbrowser_cb = QCheckBox(
            self.get_text(self.get_locale_json(), "webbrowser"), self)
        self.webbrowser_cb.move(20, 40)
        self.webbrowser_cb.toggle()

        self.alarm_stop = QPushButton(
            self.get_text(self.get_locale_json(), "waiting"), self)
        # self.alarm_stop.setCheckable(True)
        # self.alarm_stop.setEnabled(False)
        self.alarm_stop.move(80, 80)
        self.alarm_stop.clicked[bool].connect(self.stop_alarm)

        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle(self.get_text(self.get_locale_json(), "title"))

        self.show()

    def check_live(self):
        buff_video_id_set = self.get_live_video_id(self.search_ch_id)
        print("buff_video_id_set", buff_video_id_set)
        print("self.old_video_id_list", self.old_video_id_list)
        if buff_video_id_set:
            for getting_video_id in buff_video_id_set:
                if not getting_video_id == "" and not getting_video_id is None:
                    if not getting_video_id in self.old_video_id_list:
                        self.old_video_id_list.append(getting_video_id)
                        if len(self.old_video_id_list) > 30:
                            self.old_video_id_list = self.old_video_id_list[1:]
                        print("")
                        print(self.get_text(self.get_locale_json(), "started"))
                        # self.alarm_stop.setEnabled(False)
                        self.alarm_stop.click()
                        self.alarm_stop.setText(
                            self.get_text(self.get_locale_json(), "stop"))
                        if self.webbrowser_cb.checkState():
                            webbrowser.open(
                                "https://www.youtube.com/watch?v=" +
                                getting_video_id)
                        if self.alarm_cb.checkState():
                            self.alarm_sound()

    def stop_alarm(self):
        pygame.mixer.music.stop()
        self.alarm_stop.setEnabled(True)
        self.alarm_stop.setText(
            self.get_text(self.get_locale_json(), "waiting"))

    def alarm_sound(self):
        # loop = 1
        # if self.loop_cb.checkState():
        loop_count = 5
        pygame.mixer.music.play(loop_count)
        pygame.mixer.music.play(loop_count)

    def get_live_video_id(self, search_ch_id):
        dict_str = ""
        video_id_set = set()
        try:
            session = requests.Session()
            headers = {
                'user-agent':
                'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
            }
            html = session.get("https://www.youtube.com/channel/" +
                               search_ch_id,
                               headers=headers,
                               timeout=10)
            soup = BeautifulSoup(html.text, 'html.parser')
            keyword = 'window["ytInitialData"]'
            for scrp in soup.find_all("script"):
                if keyword in str(scrp):
                    dict_str = str(scrp).split(' = ', 1)[1]
            dict_str = dict_str.replace('false', 'False')
            dict_str = dict_str.replace('true', 'True')

            index = dict_str.find("\n")
            dict_str = dict_str[:index - 1]
            dics = eval(dict_str)
            for section in dics.get("contents", {}).get(
                    "twoColumnBrowseResultsRenderer",
                {}).get("tabs",
                        {})[0].get("tabRenderer",
                                   {}).get("content",
                                           {}).get("sectionListRenderer",
                                                   {}).get("contents", {}):
                for itemsection in section.get("itemSectionRenderer",
                                               {}).get("contents", {}):
                    items = {}
                    if "shelfRenderer" in itemsection:
                        for items in itemsection.get("shelfRenderer",
                                                     {}).get("content",
                                                             {}).values():
                            for item in items.get("items", {}):
                                for videoRenderer in item.values():
                                    for badge in videoRenderer.get(
                                            "badges", {}):
                                        if badge.get(
                                                "metadataBadgeRenderer",
                                            {}).get(
                                                "style", {}
                                            ) == "BADGE_STYLE_TYPE_LIVE_NOW":
                                            video_id_set.add(
                                                videoRenderer.get(
                                                    "videoId", ""))
                    elif "channelFeaturedContentRenderer" in itemsection:
                        for item in itemsection.get(
                                "channelFeaturedContentRenderer",
                            {}).get("items", {}):
                            for badge in item.get("videoRenderer",
                                                  {}).get("badges", {}):
                                if badge.get("metadataBadgeRenderer", {}).get(
                                        "style",
                                        "") == "BADGE_STYLE_TYPE_LIVE_NOW":
                                    video_id_set.add(
                                        item.get("videoRenderer",
                                                 {}).get("videoId", ""))
        except:
            return video_id_set

        return video_id_set

    def on_combobox_changed(self):
        self.set_locale(self.get_locale_cmb())
        print(self.get_locale_json())

    def get_locale_json(self):
        path = ".\\lang\\locale.json"
        with open(path, mode='r') as file:
            dict_json = json.load(file)
            return dict_json["locale"]

    def get_locale_cmb(self):
        if self.language_cmb.currentText() == "日本語":
            return "ja_JP"
        elif self.language_cmb.currentText() == "中文":
            return "zh_CN"
        elif self.language_cmb.currentText() == "English":
            return "en_US"

    def set_locale(self, locale):
        path = ".\\lang\\locale.json"
        with open(path, mode='r') as file:
            dict_json = json.load(file)
            dict_json["locale"] = locale
        with open(path, mode='w') as file:
            json.dump(dict_json, file)

    def get_text(self, locale, content):
        path = ".\\lang\\" + locale + ".json"
        with open(path, encoding="UTF-8") as file:
            dict_json = json.load(file)
        print(dict_json[content])
        return dict_json[content]
Esempio n. 37
0
class DialogGenerateDojoFolder(QDialog):
    def __init__(self, parent, u_info):
        super().__init__()
        self.parent = parent
        self.u_info = u_info
        self.title = 'Create Dojo Folder'
        self.left = 200
        self.top = 200
        self.width = 700
        self.height = 150

        self.initUI()

    def initUI(self):

        lbl = [0, 0, 0]
        self.edit = [0, 0, 0]
        btn = [0, 0, 0]

        content = _GenerateContents(self)
        for i in range(3):
            lbl[i], self.edit[i], btn[i] = content.generate(i)

        ok_import = QPushButton("OK")
        cl_import = QPushButton("Cancel")
        ok_import.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        cl_import.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

        ok_import.clicked.connect(self._ExecuteImport)
        cl_import.clicked.connect(self._Cancel)

        self.em_only = QCheckBox('Use blank segmentation')

        self.edit[1].setEnabled(self.em_only.checkState() == Qt.Unchecked)
        self.em_only.stateChanged.connect(self._CheckEMOnly)

        layout = QGridLayout()

        for i in range(3):
            layout.addWidget(lbl[i], i, 0)
            layout.addWidget(self.edit[i], i, 1, 1, 2)
            layout.addWidget(btn[i], i, 3)

        layout.addWidget(self.em_only, 3, 1, alignment=(Qt.AlignLeft))

        layout.addWidget(ok_import, 3, 2, alignment=(Qt.AlignRight))
        layout.addWidget(cl_import, 3, 3)

        self.setLayout(layout)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.setWindowTitle(self.title)
        self.setWindowIcon(QIcon(path.join(icon_dir, 'Mojo2_16.png')))

        p = self.palette()
        p.setColor(self.backgroundRole(), Qt.white)
        self.setPalette(p)
        self.show()

    def _CheckEMOnly(self):
        self.edit[1].setEnabled(self.em_only.isChecked() == Qt.Unchecked)
#        if self.em_only.isChecked() == Qt.Unchecked:
#            self.edit2.setEnabled(True)
#        else:
#            self.edit2.setEnabled(False)

    def _ExecuteImport(self):  # wxGlade: ImportImagesSegments.<event_handler>
        dir_input_images = self.edit[0].currentText()
        dir_input_ids = self.edit[1].currentText()
        dir_dojo = self.edit[2].currentText()
        self.u_info.SetUserInfo(dir_dojo)

        if len(dir_input_images) == 0:
            print('No input image.')
            return

        ##
        if (self.em_only.isChecked()
                == Qt.Unchecked) and (len(dir_input_ids) != 0):
            ##
            im = ImportImgSeg(self.u_info)
            Flag1 = im.images(dir_input_images)  ###
            Flag2 = im.ids(dir_input_ids)  ###
            #print(Flag1)
            #print(Flag2)
            if Flag1 == False or Flag2 == False:
                print('Error! Dojo files were not created.')
                self.close()
                return False
            print('Dojo files were successfully created.')
            ## File system update
            self._UpdateFileSystem(dir_dojo)
            self.close()
        ##
        else:
            ##
            im = ImportImgSeg(self.u_info)
            Flag1 = im.images(dir_input_images)  ###
            Flag2 = im.ids_dummy(dir_input_images)  ###
            #print(Flag1)
            #print(Flag2)
            if Flag1 == False or Flag2 == False:
                print('Error! Dojo files were not created.')
                self.close()
                return False
            print('Dojo files were successfully created.')
            ## File system update
            self._UpdateFileSystem(dir_dojo)
            ##
            self.close()
        ##
        self.close()
        return False

    def _Cancel(self):  # wxGlade: ImportImagesSegments.<event_handler>
        self.close()
        return False

    def _UpdateFileSystem(self, dir_dojo):
        # Release
        m.UnlockFolder(self.u_info, dir_dojo)
        # Lock again
        m.LockFolder(self.u_info, dir_dojo)
        # Filetype
        self.u_info.open_files_type[dir_dojo] = 'Dojo'
        # Dropdown menu update
        self.parent.UpdateOpenFileMenu()
        # Combo box update
        SyncListQComboBoxExcludeDojoMtifManager.get().removeModel(dir_dojo)
        SyncListQComboBoxOnlyDojoManager.get().addModel(dir_dojo)
Esempio n. 38
0
class ImgScaleView(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.defaultView()
        self.reloadUI()
        self.funType = -1

    def defaultView(self):
        self.setWindowFlags(QtCore.Qt.WindowTitleHint
                            | QtCore.Qt.WindowCloseButtonHint)
        self.resize(viewWid, viewHei)
        self.setFixedSize(viewWid, viewHei)
        self.setStyleSheet('background-color:#fff')
        self.center()
        self.setWindowTitle(zfjTools.baseTitle)

    def initUI(self):
        font = QtGui.QFont()
        font.setPointSize(18)
        margin_top = margin_size
        titleLab = QLabel('图片压缩工具', self)
        titleLab.setStyleSheet('color:#d4237a;')
        titleLab.setAlignment(Qt.AlignCenter)
        titleLab.setGeometry(
            QtCore.QRect(margin_size, margin_top, viewWid - margin_size * 2,
                         40))
        titleLab.setFont(font)
        backMainViewBtn = QtWidgets.QPushButton(self)
        backMainViewBtn.setGeometry(
            QtCore.QRect(margin_size, margin_top + 7.5, 50, 25))
        backMainViewBtn.setObjectName('logInBtn')
        backMainViewBtn.setText(_translate('MainWindow', '返回'))
        backMainViewBtn.setStyleSheet(
            'color:#1667ea;background-color:#fff;border:1px solid #1667ea;')
        backMainViewBtn.clicked.connect(self.backMainViewBtnClick)
        font.setPointSize(14)
        backMainViewBtn.setFont(font)
        margin_top += 40 + margin_size
        oldImgLab = QLabel('请选择图片所在路径:', self)
        oldImgLab.setStyleSheet('color:#000000;')
        oldImgLab.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        oldImgLab.setGeometry(QtCore.QRect(margin_size, margin_top, 135, 30))
        font.setPointSize(14)
        oldImgLab.setFont(font)
        self.oldImgEdit = QtWidgets.QLineEdit(self)
        self.oldImgEdit.setGeometry(
            QtCore.QRect(135 + margin_size * 2, margin_top, 350, 30))
        font.setPointSize(14)
        self.oldImgEdit.setFont(font)
        self.oldImgEdit.setText('/Users/zhangfujie/Desktop/Obfuscated')
        oldImgPathBtn = QtWidgets.QPushButton(self)
        oldImgPathBtn.setGeometry(
            QtCore.QRect(margin_size * 3 + 135 + 350, margin_top, 100, 30))
        oldImgPathBtn.setText(_translate('MainWindow', '选择文件夹'))
        oldImgPathBtn.setStyleSheet(
            'color:#000000;background-color:#efeff3;border:1px solid #efeff3;')
        oldImgPathBtn.clicked.connect(self.oldImgPathBtnClick)
        oldImgPathBtn.setFont(font)
        margin_top += 30 + margin_size
        newImgLab = QLabel('请选择图片保存路径:', self)
        newImgLab.setStyleSheet('color:#000000;')
        newImgLab.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        newImgLab.setGeometry(QtCore.QRect(margin_size, margin_top, 135, 30))
        font.setPointSize(14)
        newImgLab.setFont(font)
        self.newImgEdit = QtWidgets.QLineEdit(self)
        self.newImgEdit.setGeometry(
            QtCore.QRect(135 + margin_size * 2, margin_top, 350, 30))
        font.setPointSize(14)
        self.newImgEdit.setFont(font)
        self.newImgEdit.setText('/Users/zhangfujie/Desktop/Obfuscated/NewImgs')
        newImgPathBtn = QtWidgets.QPushButton(self)
        newImgPathBtn.setGeometry(
            QtCore.QRect(margin_size * 3 + 135 + 350, margin_top, 100, 30))
        newImgPathBtn.setText(_translate('MainWindow', '选择文件夹'))
        newImgPathBtn.setStyleSheet(
            'color:#000000;background-color:#efeff3;border:1px solid #efeff3;')
        newImgPathBtn.clicked.connect(self.newImgPathBtnClick)
        newImgPathBtn.setFont(font)
        margin_top += 30 + margin_size
        line_lab = QLabel(self)
        line_lab.setStyleSheet('background-color:#dcdcdc')
        line_lab.setGeometry(QtCore.QRect(0, margin_top, viewWid, 1))
        margin_top += 1 + margin_size
        smlTitLab = QLabel('请选择图片压缩方式', self)
        smlTitLab.setStyleSheet('color:#d4237a;')
        smlTitLab.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        smlTitLab.setGeometry(QtCore.QRect(margin_size, margin_top, 135, 30))
        smlTitLab.setFont(font)
        textEditWid = (viewWid - margin_size * 3) / 2
        self.textEdit = QTextEdit(self)
        self.textEdit.setStyleSheet('background-color:#262626;color:#fff;')
        self.textEdit.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        self.textEdit.setGeometry(
            QtCore.QRect(textEditWid - margin_size * 5, margin_top,
                         textEditWid + margin_size * 6, 411 - margin_top))
        font.setPointSize(12)
        self.textEdit.setFont(font)
        margin_top += 30 + margin_size
        self.sysBtn = QRadioButton('自动生成@1x,@2x,@3x', self)
        self.sysBtn.setStyleSheet('color:#000;')
        self.sysBtn.setGeometry(
            QtCore.QRect(margin_size * 2, margin_top, 200, 30))
        self.sysBtn.setChecked(False)
        self.sysBtn.toggled.connect(lambda: self.radioBtnClick(self.sysBtn))
        margin_top += 30 + margin_size
        self.userBtn = QRadioButton('手动设置图片尺寸(格式:宽x高)', self)
        self.userBtn.setStyleSheet('color:#000;')
        self.userBtn.setGeometry(
            QtCore.QRect(margin_size * 2, margin_top, 200, 30))
        self.userBtn.setChecked(False)
        self.userBtn.toggled.connect(lambda: self.radioBtnClick(self.userBtn))
        titleArr = ['@1x尺寸:', '@2x尺寸:', '@3x尺寸:']
        self.checkBoxList = []
        self.checkBoxEditList = []
        for index in range(0, 3):
            margin_top += 30 + margin_size
            checkBox = QCheckBox(titleArr[index], self)
            checkBox.setStyleSheet('color:#000;')
            checkBox.stateChanged.connect(self.checkBoxClick)
            checkBox.setGeometry(
                QtCore.QRect(margin_size * 4, margin_top, 80, 30))
            self.checkBoxList.append(checkBox)
            checkBoxEdit = QtWidgets.QLineEdit(self)
            checkBoxEdit.setText('0x0')
            checkBoxEdit.setGeometry(
                QtCore.QRect(margin_size * 4 + 80, margin_top,
                             200 - (margin_size * 4 + 80) + margin_size * 2,
                             30))
            checkBoxEdit.setFont(font)
            checkBoxEdit.setStyleSheet(
                'color:#cc0066;background-color:#efeff3;')
            checkBoxEdit.textChanged.connect(
                lambda: self.checkBoxEditChanged(index))
            self.checkBoxEditList.append(checkBoxEdit)

        margin_top += 30 + margin_size
        self.alphaCheckBox = QCheckBox('移除PNG的alpha通道', self)
        self.alphaCheckBox.setStyleSheet('color:#000;')
        self.alphaCheckBox.stateChanged.connect(self.checkBoxClick)
        self.alphaCheckBox.setGeometry(
            QtCore.QRect(margin_size * 2, margin_top, 200, 30))
        margin_top += 30 + margin_size
        self.imgTypeBox = QCheckBox('webp', self)
        self.imgTypeBox.setStyleSheet('color:#000;')
        self.imgTypeBox.stateChanged.connect(self.checkBoxClick)
        self.imgTypeBox.setGeometry(
            QtCore.QRect(margin_size * 2, margin_top, 200, 30))
        margin_top += 30 + margin_size * 5
        startScaleBtn = QtWidgets.QPushButton(self)
        startScaleBtn.setGeometry(
            QtCore.QRect((viewWid - 160) / 2, margin_top, 160, 40))
        startScaleBtn.setText(_translate('MainWindow', '开始压缩'))
        startScaleBtn.setStyleSheet(
            'background-color:#fff;color:#cc0066;border:1px solid #cc0066;')
        startScaleBtn.clicked.connect(self.startScaleBtnClick)
        font.setPointSize(18)
        startScaleBtn.setFont(font)
        margin_top += 40 + margin_size * 2
        tipsTitLab = QLabel('使用须知', self)
        tipsTitLab.setStyleSheet('color:#d4237a;')
        tipsTitLab.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        tipsTitLab.setGeometry(
            QtCore.QRect(margin_size, margin_top, viewWid - margin_size * 2,
                         30))
        font.setPointSize(14)
        tipsTitLab.setFont(font)
        margin_top += 30
        tipsLabText = '1.选择自动生成@1x、@2x、@3x时,默认把原图作为@3x, @1x和@2x在此基础上向下压缩;\n2.选择手动设置图片尺寸时,为了保证图片的清晰质量,原图尺寸最好大于等于三倍尺寸;'
        tipsLab = QLabel(tipsLabText, self)
        tipsLab.setStyleSheet('color:#87b753;')
        tipsLab.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        tipsLab.setGeometry(
            QtCore.QRect(margin_size, margin_top, viewWid - margin_size * 2,
                         50))
        font.setPointSize(12)
        tipsLab.setFont(font)
        margin_top += 50 + margin_size
        line_lab_1 = QLabel(self)
        line_lab_1.setStyleSheet('background-color:#dcdcdc')
        line_lab_1.setGeometry(QtCore.QRect(0, margin_top, viewWid, 1))
        margin_top += 1 + margin_size
        downLab_wid = (viewWid - margin_size * 3) / 2
        self.accountLab = QLabel(':', self)
        self.accountLab.setStyleSheet('color:#000;')
        self.accountLab.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        self.accountLab.setGeometry(
            QtCore.QRect(margin_size, margin_top, downLab_wid, 30))
        font.setPointSize(13)
        self.accountLab.setFont(font)
        self.timeLab = QLabel(':', self)
        self.timeLab.setStyleSheet('color:#000;')
        self.timeLab.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self.timeLab.setGeometry(
            QtCore.QRect(margin_size * 2 + downLab_wid, margin_top,
                         downLab_wid, 30))
        font.setPointSize(13)
        self.timeLab.setFont(font)
        margin_top += 30 + margin_size

    def backMainViewBtnClick(self):
        personinfo = ZFJPersoninfo()
        if personinfo.mainRootView != None:
            personinfo.mainRootView.show()
            self.close()
        else:
            print('mainRootView')

    def oldImgPathBtnClick(self):
        file_dir = ''
        try:
            file_dir = QFileDialog.getExistingDirectory(
                self, 'open file', '/Users/')
        except Exception as e:
            try:
                file_dir = ','
            finally:
                e = None
                del e

        self.oldImgEdit.setText(file_dir)

    def newImgPathBtnClick(self):
        file_dir = ''
        try:
            file_dir = QFileDialog.getExistingDirectory(
                self, 'open file', '/Users/')
        except Exception as e:
            try:
                file_dir = ','
            finally:
                e = None
                del e

        self.newImgEdit.setText(file_dir)

    def radioBtnClick(self, btn):
        if self.sysBtn.isChecked() == True:
            self.funType = 0
            for checkBox in self.checkBoxList:
                checkBox.setCheckState(Qt.Unchecked)

            for checkBoxEdit in self.checkBoxEditList:
                checkBoxEdit.setText('')

        else:
            self.funType = 1
            for checkBox in self.checkBoxList:
                checkBox.setCheckState(Qt.Checked)

    def checkBoxClick(self):
        if self.sysBtn.isChecked() == True or self.funType == -1:
            for checkBox in self.checkBoxList:
                checkBox.setCheckState(Qt.Unchecked)

    def checkBoxEditChanged(self, index):
        if self.sysBtn.isChecked() == True or self.funType == -1:
            for checkBoxEdit in self.checkBoxEditList:
                checkBoxEdit.setText('0x0')

    def startScaleBtnClick(self):
        oldImgPath = self.oldImgEdit.text()
        if len(oldImgPath) == 0:
            self.megBoxInfor('')
            return
        if os.path.exists(oldImgPath) == False:
            self.megBoxInfor('')
            return
        newImgPath = self.newImgEdit.text()
        if len(newImgPath) == 0:
            self.megBoxInfor('')
            return
        if os.path.exists(newImgPath) == False:
            self.megBoxInfor('')
            return
        sizeTupList = None
        if self.funType == 1:
            checkCount = 0
            for checkBox in self.checkBoxList:
                if checkBox.checkState() == Qt.Checked:
                    checkCount += 1
                    continue

            if checkCount == 0:
                self.megBoxInfor('')
                return
            titleArr = ['@1x', '@2x', '@3x']
            for index in range(0, len(self.checkBoxEditList)):
                checkBox = self.checkBoxList[index]
                checkBoxEdit = self.checkBoxEditList[index]
                checkBoxEditText = checkBoxEdit.text().replace('X', 'x')
                if checkBox.checkState() == Qt.Checked:
                    if 'x' not in checkBoxEditText:
                        self.megBoxInfor('' + titleArr[index] + '(:100x100)')
                        return
                    if zfjTools.is_number(checkBoxEditText.replace(
                            'x', '')) == False:
                        self.megBoxInfor('' + titleArr[index] + '(:100x100)')
                        return
                    width = checkBoxEditText[:checkBoxEditText.find('x')]
                    if len(width) == 0:
                        width = '0'
                    height = checkBoxEditText[checkBoxEditText.find('x') + 1:]
                    if len(height) == 0:
                        height = '0'
                    if int(width) <= 0:
                        self.megBoxInfor(titleArr[index] + '<=0(:100x100)')
                        return
                    if int(height) <= 0:
                        self.megBoxInfor(titleArr[index] + '<=0(:100x100)')
                        return
                    sizeTup = (width, height)
                    sizeTupList.append(sizeTup)
                else:
                    sizeTup = (0, 0)
                    sizeTupList.append(sizeTup)

        else:
            if self.funType == 0:
                sizeTupList = []
            else:
                sizeTupList = None
            isCloseAlpha = False
            if self.alphaCheckBox.checkState() == Qt.Checked:
                isCloseAlpha = True
            isUpDateImgType = False
            if self.imgTypeBox.checkState() == Qt.Checked:
                isUpDateImgType = True
            self.textEdit.clear()
            imageScaleObj.startScaleImg(oldImgPath, newImgPath, sizeTupList,
                                        isCloseAlpha, isUpDateImgType)

    def reloadUI(self):
        personinfo = ZFJPersoninfo()
        self.accountLab.setText(':' + str(personinfo.account))
        self.timeLab.setText(':' + personinfo.expireDate.replace('"', ''))

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def megBoxInfor(self, infor):
        QMessageBox.information(self, '', infor, QMessageBox.Yes)
Esempio n. 39
0
class App(QMainWindow):
    def __init__(self):
        super().__init__()
        self.title = 'kfit'
        self.left = 400
        self.top = 150
        self.width = 1200
        self.height = 800
        self.file_name = ''
        self.xcol_idx = 0
        self.ycol_idx = 1
        self.ngau = 0
        self.nlor = 0
        self.nvoi = 0
        self.nlin = 1
        self.model = None
        self.result = None
        self.curves_df = None
        self.params_df = None
        self.edit_mode = False
        # empty Parameters to hold parameter guesses/constraints
        self.params = Parameters()
        self.guesses = {'value': {}, 'min': {}, 'max': {}}
        self.usr_vals = {'value': {}, 'min': {}, 'max': {}}
        self.usr_entry_widgets = {}
        self.cid = None

        # file import settings
        self.sep = ','
        self.header = 'infer'
        self.index_col = None
        self.skiprows = None
        self.dtype = None
        self.encoding = None

        # keyboard shortcuts
        self.fit_shortcut = QShortcut(QKeySequence('Ctrl+F'), self)
        self.fit_shortcut.activated.connect(self.fit)
        self.reset_shortcut = QShortcut(QKeySequence('Ctrl+R'), self)
        self.reset_shortcut.activated.connect(self.hard_reset)
        self.save_fit = QShortcut(QKeySequence('Ctrl+S'), self)
        self.save_fit.activated.connect(self.export_results)
        self.add_gau = QShortcut(QKeySequence('G'), self)
        self.add_gau.activated.connect(lambda: self.increment('gau', True))
        self.add_gau.activated.connect(self.init_param_widgets)
        self.sub_gau = QShortcut(QKeySequence('Shift+G'), self)
        self.sub_gau.activated.connect(lambda: self.increment('gau', False))
        self.sub_gau.activated.connect(self.init_param_widgets)
        self.add_lor = QShortcut(QKeySequence('L'), self)
        self.add_lor.activated.connect(lambda: self.increment('lor', True))
        self.add_lor.activated.connect(self.init_param_widgets)
        self.sub_lor = QShortcut(QKeySequence('Shift+L'), self)
        self.sub_lor.activated.connect(lambda: self.increment('lor', False))
        self.sub_lor.activated.connect(self.init_param_widgets)
        self.add_voi = QShortcut(QKeySequence('V'), self)
        self.add_voi.activated.connect(lambda: self.increment('voi', True))
        self.add_voi.activated.connect(self.init_param_widgets)
        self.sub_voi = QShortcut(QKeySequence('Shift+V'), self)
        self.sub_voi.activated.connect(lambda: self.increment('voi', False))
        self.sub_voi.activated.connect(self.init_param_widgets)
        self.add_lin = QShortcut(QKeySequence('N'), self)
        self.add_lin.activated.connect(lambda: self.increment('lin', True))
        self.add_lin.activated.connect(self.init_param_widgets)
        self.sub_lin = QShortcut(QKeySequence('Shift+N'), self)
        self.sub_lin.activated.connect(lambda: self.increment('lin', False))
        self.sub_lin.activated.connect(self.init_param_widgets)

        # temporary data
        x = np.linspace(0, 10, 500)
        y = models.gauss(x, 0.5, 4, 0.4) + \
            models.gauss(x, 0.8, 5, 0.2) + \
            models.gauss(x, 0.4, 6, 0.3) + 0.2

        # set data
        self.data = pd.DataFrame([x, y]).T
        self.data.columns = ['x', 'y']
        self.x = self.data['x']
        self.y = self.data['y']
        self.xmin = self.data['x'].min()
        self.xmax = self.data['x'].max()

        self.initUI()

    def initUI(self):
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.setWindowTitle(self.title)
        self.setWindowIcon(QIcon('../images/K.png'))

        # set up the status bar
        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)
        self.status_bar.showMessage('Welcome to kfit!', msg_length)
        self.status_bar.setStyleSheet('background-color: white')

        # Create the Main Widget and Layout
        self.main_layout = QVBoxLayout()
        self.main_widget = QSplitter()
        self.main_widget.setOrientation(Qt.Vertical)
        self.setCentralWidget(self.main_widget)

        # create "top bar" widget
        self.topbar_layout = QHBoxLayout()
        self.topbar_widget = QWidget()
        # fit button
        self.fit_button = QPushButton('Fit', self)
        self.fit_button.setMaximumWidth(100)
        self.fit_button.clicked.connect(self.fit)
        self.fit_button.installEventFilter(self)
        # import button
        self.import_button = QPushButton('Import', self)
        self.import_button.setMaximumWidth(100)
        self.import_button.clicked.connect(self.get_data)
        self.import_button.installEventFilter(self)
        # import settings button
        self.import_settings_button = QPushButton('', self)
        self.import_settings_button.setIcon(
            QIcon.fromTheme('stock_properties'))
        self.import_settings_button.setMaximumWidth(40)
        self.import_settings_button.clicked.connect(
            self.import_settings_dialog)
        self.import_settings_button.installEventFilter(self)
        # reset fit button
        self.reset_button = QPushButton('', self)
        self.reset_button.setIcon(QIcon.fromTheme('view-refresh'))
        self.reset_button.setMaximumWidth(40)
        self.reset_button.clicked.connect(self.hard_reset)
        self.reset_button.installEventFilter(self)
        # save results button
        self.save_button = QPushButton('', self)
        self.save_button.setIcon(QIcon.fromTheme('filesave'))
        self.save_button.setMaximumWidth(40)
        self.save_button.clicked.connect(self.export_results)
        self.save_button.installEventFilter(self)
        # progress bar
        self.progress_bar = QProgressBar()
        # self.progressBar.setMaximumWidth(150)
        self.progress_bar.hide()
        # get column header for x
        self.xlabel = QLabel(self)
        self.xlabel.setText('ColumnIndex(X):')
        self.xlabel.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        # self.xlabel.setMaximumWidth(250)
        self.xline_entry = QLineEdit(self)
        self.xline_entry.setText('0')
        self.xline_entry.setAlignment(Qt.AlignCenter)
        # self.xline_entry.setMaximumWidth(50)
        self.xline_entry.returnPressed.connect(self.column_index_set)
        # get column header for y
        self.ylabel = QLabel(self)
        self.ylabel.setText('ColumnIndex(Y):')
        self.ylabel.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        # self.ylabel.setMaximumWidth(100)
        self.yline_entry = QLineEdit(self)
        self.yline_entry.setText('1')
        self.yline_entry.setAlignment(Qt.AlignCenter)
        # self.yline_entry.setMaximumWidth(50)
        self.yline_entry.returnPressed.connect(self.column_index_set)
        # add topbar widgets to layout
        self.topbar_layout.addSpacing(600)
        self.topbar_layout.addWidget(self.xlabel)
        self.topbar_layout.addWidget(self.xline_entry)
        self.topbar_layout.addWidget(self.ylabel)
        self.topbar_layout.addWidget(self.yline_entry)
        self.topbar_layout.addWidget(self.fit_button)
        self.topbar_layout.addWidget(self.import_button)
        self.topbar_layout.addWidget(self.import_settings_button)
        self.topbar_layout.addWidget(self.reset_button)
        self.topbar_layout.addWidget(self.save_button)
        self.topbar_layout.addWidget(self.progress_bar)
        self.topbar_layout.setAlignment(Qt.AlignRight)
        self.topbar_widget.setLayout(self.topbar_layout)
        self.topbar_widget.setMaximumHeight(75)

        # create tabs widget
        self.tabs = QTabWidget(self)
        self.tab1 = QWidget(self)
        self.tab2 = QTableView(self)
        self.tab3 = QWidget(self)
        self.tabs.addTab(self.tab1, 'Graph')
        self.tabs.addTab(self.tab2, 'Data')
        self.tabs.addTab(self.tab3, 'Output')
        self.tabs.setMinimumHeight(300)

        # create params widget
        self.params_widget = QSplitter()
        self.gau_layout = QVBoxLayout()
        self.gau_layout.setAlignment(Qt.AlignTop)
        self.gau_widget = QWidget()
        self.gau_widget.setLayout(self.gau_layout)
        self.gau_widget.setSizePolicy(QSizePolicy.Expanding,
                                      QSizePolicy.Expanding)
        self.gau_scroll = QScrollArea()
        self.gau_scroll.setWidget(self.gau_widget)
        self.gau_scroll.setWidgetResizable(True)
        self.lor_widget = QWidget()
        self.lor_layout = QVBoxLayout()
        self.lor_layout.setAlignment(Qt.AlignTop)
        self.lor_widget.setLayout(self.lor_layout)
        self.lor_widget.setSizePolicy(QSizePolicy.Expanding,
                                      QSizePolicy.Expanding)
        self.lor_scroll = QScrollArea()
        self.lor_scroll.setWidget(self.lor_widget)
        self.lor_scroll.setWidgetResizable(True)
        self.voi_widget = QWidget()
        self.voi_layout = QVBoxLayout()
        self.voi_layout.setAlignment(Qt.AlignTop)
        self.voi_widget.setLayout(self.voi_layout)
        self.voi_widget.setSizePolicy(QSizePolicy.Expanding,
                                      QSizePolicy.Expanding)
        self.voi_scroll = QScrollArea()
        self.voi_scroll.setWidget(self.voi_widget)
        self.voi_scroll.setWidgetResizable(True)
        self.lin_widget = QWidget()
        self.lin_layout = QVBoxLayout()
        self.lin_layout.setAlignment(Qt.AlignTop)
        self.lin_widget.setLayout(self.lin_layout)
        self.lin_widget.setSizePolicy(QSizePolicy.Expanding,
                                      QSizePolicy.Expanding)
        self.lin_scroll = QScrollArea()
        self.lin_scroll.setWidget(self.lin_widget)
        self.lin_scroll.setWidgetResizable(True)
        self.params_widget.addWidget(self.gau_scroll)
        self.params_widget.addWidget(self.lor_scroll)
        self.params_widget.addWidget(self.voi_scroll)
        self.params_widget.addWidget(self.lin_scroll)
        self.params_widget.setMinimumHeight(180)

        # add everything to main widget
        self.main_widget.addWidget(self.topbar_widget)
        self.main_widget.addWidget(self.tabs)
        self.main_widget.addWidget(self.params_widget)

        # Tab 1 - Graph / Model
        # Graph
        plt.style.use('fivethirtyeight')
        self.tab1.figure = Figure(figsize=(8, 6), dpi=60)
        self.tab1.canvas = FigureCanvas(self.tab1.figure)
        self.tab1.toolbar = NavigationToolbar(self.tab1.canvas, self)
        # tristate checkbox for edit mode
        self.emode_box = QCheckBox()
        self.emode_box.setTristate(True)
        self.emode_box.setIcon(QIcon.fromTheme('stock_edit'))
        self.emode_box.stateChanged.connect(self.toggle_edit_mode)
        self.emode_box.installEventFilter(self)
        # tweaking the toolbar layout
        self.tab1.toolbar.setIconSize(QSize(18, 18))
        spacer = QWidget()
        spacer.setFixedWidth(20)
        self.tab1.toolbar.addWidget(spacer)
        self.tab1.toolbar.addWidget(self.emode_box)
        self.tab1.toolbar.locLabel.setAlignment(Qt.AlignRight | Qt.AlignCenter)
        graph_layout = QVBoxLayout()
        graph_layout.addWidget(self.tab1.toolbar)
        graph_layout.addWidget(self.tab1.canvas)

        # The "Set Model" layout
        model_layout = QGridLayout()
        widget_setgau = QWidget()
        layout_setgau = QHBoxLayout()
        layout_setgau.setSizeConstraint(QLayout.SetFixedSize)
        widget_setgau.setLayout(layout_setgau)
        widget_setlor = QWidget()
        layout_setlor = QHBoxLayout()
        layout_setlor.setSizeConstraint(QLayout.SetFixedSize)
        widget_setlor.setLayout(layout_setlor)
        widget_setvoi = QWidget()
        layout_setvoi = QHBoxLayout()
        layout_setvoi.setSizeConstraint(QLayout.SetFixedSize)
        widget_setvoi.setLayout(layout_setvoi)
        widget_setlin = QWidget()
        layout_setlin = QHBoxLayout()
        layout_setlin.setSizeConstraint(QLayout.SetFixedSize)
        widget_setlin.setLayout(layout_setlin)
        model_layout.addWidget(widget_setgau, 0, 0)
        model_layout.addWidget(widget_setlor, 0, 1)
        model_layout.addWidget(widget_setvoi, 0, 2)
        model_layout.addWidget(widget_setlin, 0, 3)

        # specify number of gaussian curves
        gauss_label = QLabel(self)
        gauss_label.setText('Gaussians')
        gauss_label.setAlignment(Qt.AlignVCenter)
        gauss_button_add = QPushButton('', self)
        gauss_button_add.setIcon(QIcon.fromTheme('list-add'))
        gauss_button_add.clicked.connect(lambda: self.increment('gau', True))
        gauss_button_add.clicked.connect(self.init_param_widgets)
        gauss_button_sub = QPushButton('', self)
        gauss_button_sub.setIcon(QIcon.fromTheme('list-remove'))
        gauss_button_sub.clicked.connect(lambda: self.increment('gau', False))
        gauss_button_sub.clicked.connect(self.init_param_widgets)
        layout_setgau.addWidget(gauss_label)
        layout_setgau.addWidget(gauss_button_add)
        layout_setgau.addWidget(gauss_button_sub)
        # specify number of lorentzian curves
        lorentz_label = QLabel(self)
        lorentz_label.setText('Lorentzians')
        lorentz_label.setAlignment(Qt.AlignVCenter)
        lorentz_button_add = QPushButton('', self)
        lorentz_button_add.setIcon(QIcon.fromTheme('list-add'))
        lorentz_button_add.clicked.connect(lambda: self.increment('lor', True))
        lorentz_button_add.clicked.connect(self.init_param_widgets)
        lorentz_button_sub = QPushButton('', self)
        lorentz_button_sub.setIcon(QIcon.fromTheme('list-remove'))
        lorentz_button_sub.clicked.connect(
            lambda: self.increment('lor', False))
        lorentz_button_sub.clicked.connect(self.init_param_widgets)
        layout_setlor.addWidget(lorentz_label)
        layout_setlor.addWidget(lorentz_button_add)
        layout_setlor.addWidget(lorentz_button_sub)
        # specify number of voigt curves
        voigt_label = QLabel(self)
        voigt_label.setText('Pseudo-Voigts')
        voigt_label.setAlignment(Qt.AlignVCenter)
        voigt_button_add = QPushButton('', self)
        voigt_button_add.setIcon(QIcon.fromTheme('list-add'))
        voigt_button_add.clicked.connect(lambda: self.increment('voi', True))
        voigt_button_add.clicked.connect(self.init_param_widgets)
        voigt_button_sub = QPushButton('', self)
        voigt_button_sub.setIcon(QIcon.fromTheme('list-remove'))
        voigt_button_sub.clicked.connect(lambda: self.increment('voi', False))
        voigt_button_sub.clicked.connect(self.init_param_widgets)
        layout_setvoi.addWidget(voigt_label)
        layout_setvoi.addWidget(voigt_button_add)
        layout_setvoi.addWidget(voigt_button_sub)
        # specify number of lines
        line_label = QLabel(self)
        line_label.setText('Lines:')
        line_label.setAlignment(Qt.AlignVCenter)
        line_button_add = QPushButton('', self)
        line_button_add.setIcon(QIcon.fromTheme('list-add'))
        line_button_add.clicked.connect(lambda: self.increment('lin', True))
        line_button_add.clicked.connect(self.init_param_widgets)
        line_button_sub = QPushButton('', self)
        line_button_sub.setIcon(QIcon.fromTheme('list-remove'))
        line_button_sub.clicked.connect(lambda: self.increment('lin', False))
        line_button_sub.clicked.connect(self.init_param_widgets)
        layout_setlin.addWidget(line_label)
        layout_setlin.addWidget(line_button_add)
        layout_setlin.addWidget(line_button_sub)

        graph_layout.addLayout(model_layout)
        self.tab1.setLayout(graph_layout)
        self.plot()

        # Tab 2 - Data Table
        self.table_model = PandasModel(self.data)
        self.tab2.setModel(self.table_model)
        self.tab2.resizeColumnsToContents()

        # Tab 3 - Output
        self.tab3_widget = QPlainTextEdit()
        tab3_layout = QVBoxLayout()
        tab3_layout.addWidget(self.tab3_widget)
        self.tab3.setLayout(tab3_layout)

        self.init_param_widgets()
        self.show()

    def export_results(self):
        self.process_results()
        # open file dialog
        exp_file_name, _ = QFileDialog.getSaveFileName(
            self,
            'QFileDialog.getSaveFileName()',
            'fit_results.csv',
            'CSV files (*.csv)',
        )
        if exp_file_name:
            self.process_results()
            self.curves_df.to_csv(exp_file_name)
            # NOTE: if user chooses a file extension other than .csv, or does
            # not use a file extension, this should still work, but I haven't
            # tested too rigorously yet
            self.params_df.to_csv('{}.params.csv'.format(
                exp_file_name[:exp_file_name.find('.csv')]))
            self.status_bar.showMessage(
                'Exported fit results to: ' + exp_file_name, 2 * msg_length)
        else:
            self.status_bar.showMessage('Export canceled.', 2 * msg_length)
            return

    def process_results(self):
        if self.result is not None:
            self.params_df = pd.DataFrame.from_dict(self.result.best_values,
                                                    orient='index')
            self.params_df.index.name = 'parameter'
            self.params_df.columns = ['value']
            curves_dict = {
                'data': self.y,
                'total_fit': self.result.best_fit,
            }
            components = self.result.eval_components()
            for i, comp in enumerate(components):
                curves_dict[comp[:comp.find('_')]] = components[comp]
            self.curves_df = pd.DataFrame.from_dict(curves_dict)
            self.curves_df.index = self.x
            self.curves_df.index.name = self.data.columns[self.xcol_idx]
        else:
            self.status_bar.showMessage('No fit results to export!',
                                        msg_length)

    def eventFilter(self, object, event):
        if event.type() == QEvent.Enter:
            if object is self.reset_button:
                self.status_bar.showMessage("Reset fit")
            if object is self.import_settings_button:
                self.status_bar.showMessage("File import settings")
            if object is self.import_button:
                self.status_bar.showMessage("Import .csv file")
            if object is self.fit_button:
                self.status_bar.showMessage("Fit data")
            if object is self.emode_box:
                self.status_bar.showMessage("Toggle edit mode")
            if object is self.save_button:
                self.status_bar.showMessage("Export fit results")
            return True
        elif event.type() == QEvent.Leave:
            self.status_bar.showMessage(None)
        return False

    def init_model(self):
        # increment() ensures nlin >= 1
        self.model = models.line_mod(self.nlin)
        if self.ngau != 0:
            self.model += models.gauss_mod(self.ngau)
        if self.nlor != 0:
            self.model += models.lor_mod(self.nlor)
        if self.nvoi != 0:
            self.model += models.voigt_mod(self.nvoi)
        self.status_bar.showMessage(
            "Model updated: " +
            str([self.ngau, self.nlor, self.nvoi, self.nlin]), msg_length)

    def init_param_widgets(self):
        self.init_model()
        self.usr_entry_widgets = {'value': {}, 'min': {}, 'max': {}}
        labels = {}
        rnd = 3  # decimals to round to in placeholder text
        self.clear_fit_layouts()

        for param_name in self.model.param_names:
            # set param label text
            labels[param_name] = QLabel()
            labels[param_name].setText(param_name)

            # make qlineedit widgets
            for key in self.usr_entry_widgets:
                self.usr_entry_widgets[key][param_name] = QLineEdit()
                if param_name in self.usr_vals[key]:
                    self.usr_entry_widgets[key][param_name]\
                        .setPlaceholderText(
                            str(round(self.usr_vals[key][param_name], rnd))
                        )
                else:
                    self.usr_entry_widgets[key][param_name]\
                        .setPlaceholderText(key)
                # set up connections
                # connect() expects a callable func, hence the lambda
                self.usr_entry_widgets[key][param_name].returnPressed.connect(
                    lambda: self.update_usr_vals(self.usr_entry_widgets))

            # add widgets to respective layouts
            sublayout1 = QVBoxLayout()
            sublayout2 = QHBoxLayout()
            sublayout1.addWidget(labels[param_name])
            for key in self.usr_entry_widgets:
                sublayout2.addWidget(self.usr_entry_widgets[key][param_name])
            if param_name.find('gau') != -1:
                self.gau_layout.addLayout(sublayout1)
                self.gau_layout.addLayout(sublayout2)
            if param_name.find('lor') != -1:
                self.lor_layout.addLayout(sublayout1)
                self.lor_layout.addLayout(sublayout2)
            if param_name.find('voi') != -1:
                self.voi_layout.addLayout(sublayout1)
                self.voi_layout.addLayout(sublayout2)
            if param_name.find('lin') != -1:
                self.lin_layout.addLayout(sublayout1)
                self.lin_layout.addLayout(sublayout2)

        # Resize all of the LineEntry widgets
        for key in self.usr_entry_widgets:
            for param, widget in self.usr_entry_widgets[key].items():
                widget.setMaximumWidth(150)

        if self.result is not None:
            self.set_params()
            self.update_param_widgets()

    def update_usr_vals(self, entry):
        # get text input from each usr_entry_widget
        for val_type, param_dict in self.usr_entry_widgets.items():
            for param, param_widget in param_dict.items():
                try:
                    self.usr_vals[val_type][param] = \
                        float(param_widget.text())
                except Exception:
                    pass

    def update_param_widgets(self):
        rnd = 3
        # the 'value' placeholder text is the result for that param
        # taken from self.result
        # the 'min' and 'max' text is from either the self.guesses
        # or from self.usr_vals
        for param in self.params:
            if param in self.result.best_values:
                self.usr_entry_widgets['value'][param].setPlaceholderText(
                    str(round(self.result.best_values[param], rnd)))
                self.usr_entry_widgets['min'][param].setPlaceholderText(
                    str(round(self.params[param].min, rnd)))
                self.usr_entry_widgets['max'][param].setPlaceholderText(
                    str(round(self.params[param].max, rnd)))

    def guess_params(self):
        for comp in self.model.components:
            if comp.prefix.find('gau') != -1 or \
                    comp.prefix.find('lor') != -1 or \
                    comp.prefix.find('voi') != -1:

                # need to define explicitly to make proper guesses
                c = comp.prefix + 'center'
                a = comp.prefix + 'amplitude'
                s = comp.prefix + 'sigma'
                f = comp.prefix + 'fraction'

                self.guesses['value'][c] = \
                    self.data.iloc[:, self.xcol_idx].mean()
                self.guesses['value'][a] = \
                    self.data.iloc[:, self.ycol_idx].mean()
                self.guesses['value'][s] = \
                    self.data.iloc[:, self.xcol_idx].std()
                self.guesses['min'][c] = None
                self.guesses['min'][a] = 0
                self.guesses['min'][s] = 0
                self.guesses['max'][c] = None
                self.guesses['max'][a] = None
                self.guesses['max'][s] = None

                if comp.prefix.find('voi') != -1:
                    self.guesses['value'][f] = 0.5
                    self.guesses['min'][f] = 0
                    self.guesses['max'][f] = 1
            else:
                slope = comp.prefix + 'slope'
                intc = comp.prefix + 'intercept'
                for p in [slope, intc]:
                    self.guesses['value'][p] = \
                        self.data.iloc[:, self.ycol_idx].mean()
                    self.guesses['min'][p] = None
                    self.guesses['max'][p] = None

    def set_params(self):
        self.params = Parameters()
        self.guess_params()
        self.update_usr_vals(self.usr_entry_widgets)
        vals = {}

        # fill params with any user-entered values
        # fill in blanks with guesses
        for param_name in self.model.param_names:
            for val_type in ['value', 'min', 'max']:
                if param_name in self.usr_vals[val_type]:
                    vals[val_type] = self.usr_vals[val_type][param_name]
                    # print('param: ' + param_name + ', type: ' +\
                    #         val_type + ', set_by: user')
                else:
                    vals[val_type] = self.guesses[val_type][param_name]
                    # print('param: ' + param_name + ', type: ' +\
                    #         val_type + ', set_by: guess')
            self.params.add(name=param_name,
                            value=vals['value'],
                            vary=True,
                            min=vals['min'],
                            max=vals['max'])

    def set_xy_range(self):
        self.x = self.data.iloc[:, self.xcol_idx]
        self.y = self.data.iloc[:, self.ycol_idx]
        self.xmin, self.xmax = self.ax.get_xlim()
        range_bool = (self.x >= self.xmin) & (self.x <= self.xmax)
        self.x = self.x[range_bool].values
        self.y = self.y[range_bool].values

    def reset_xy_range(self):
        self.xmin = np.min(self.x)
        self.xmax = np.max(self.x)

    def fit(self):
        self.emode_box.setCheckState(0)
        self.toggle_edit_mode()
        self.set_xy_range()
        self.set_params()
        self.result = self.model.fit(data=self.y,
                                     params=self.params,
                                     x=self.x,
                                     method='least_squares')
        self.tab3_widget.clear()
        self.tab3_widget.insertPlainText(self.result.fit_report())
        self.plot()
        # overwrite widgets to clear input (not ideal method..)
        self.init_param_widgets()
        # update widgets with new placeholder text
        self.update_param_widgets()

    def column_index_set(self):
        # make sure user enters index that can be converted to int
        try:
            idx_x = int(self.xline_entry.text())
        except ValueError:
            self.status_bar.showMessage(idx_type_error_msg, msg_length)
            self.xline_entry.setText(None)
            return
        try:
            idx_y = int(self.yline_entry.text())
        except ValueError:
            self.status_bar.showMessage(idx_type_error_msg, msg_length)
            self.yline_entry.setText(None)
            return
        self.xcol_idx = idx_x
        self.ycol_idx = idx_y
        self.result = None
        # make sure user enters an index that's in the data range
        try:
            self.x = self.data.iloc[:, self.xcol_idx]
        except IndexError:
            self.status_bar.showMessage(idx_range_error_msg, msg_length)
            self.xline_entry.setText(None)
            return
        try:
            self.y = self.data.iloc[:, self.ycol_idx]
        except IndexError:
            self.status_bar.showMessage(idx_range_error_msg, msg_length)
            self.yline_entry.setText(None)
            return
        self.xmin = np.min(self.x)
        self.xmax = np.max(self.x)
        self.plot()
        self.status_bar.showMessage(
            'ColumnIndex(X) = ' + str(idx_x) + ', ' + 'ColumnIndex(Y) = ' +
            str(idx_y), msg_length)

    def toggle_edit_mode(self):
        # first toggle off the zoom or pan button
        # so they don't interfere with edit_mode cursor style
        if self.tab1.toolbar._active == 'ZOOM':
            self.tab1.toolbar.zoom()
        if self.tab1.toolbar._active == 'PAN':
            self.tab1.toolbar.pan()
        states = {
            0: 'Edit mode off',
            1: 'Edit mode on | copy x-value',
            2: 'Edit mode on | copy y-value',
        }
        self.status_bar.showMessage(states[self.emode_box.checkState()],
                                    msg_length)
        if self.emode_box.checkState() == 0:
            self.mpl_cursor = None
            self.tab1.canvas.mpl_disconnect(self.cid)
        if self.emode_box.checkState() == 1:
            self.mpl_cursor = Cursor(self.ax, lw=1, c='red', linestyle='--')
            self.cid = self.tab1.canvas.mpl_connect('button_press_event',
                                                    self.get_coord_click)
        if self.emode_box.checkState() == 2:
            self.cid = self.tab1.canvas.mpl_connect('button_press_event',
                                                    self.get_coord_click)

    def get_coord_click(self, event):
        self.x_edit, self.y_edit = round(event.xdata, 3), round(event.ydata, 3)
        if self.emode_box.checkState() == 1:
            pyperclip.copy(self.x_edit)
            self.status_bar.showMessage(
                'Copied X=' + str(self.x_edit) + ' to clipboard!', msg_length)
        if self.emode_box.checkState() == 2:
            pyperclip.copy(self.y_edit)
            self.status_bar.showMessage(
                'Copied Y=' + str(self.y_edit) + ' to clipboard!', msg_length)

    def close_app(self):
        sys.exit()

    def get_data(self):
        self.emode_box.setCheckState(0)
        self.toggle_edit_mode()
        # reset column indices
        self.xcol_idx = 0
        self.ycol_idx = 1
        # open file dialog
        self.file_name, _ = QFileDialog.getOpenFileName(
            self, 'Open File', '', 'CSV files (*.csv);; All Files (*)')
        if self.file_name:
            # this message isn't showing up...
            # TODO: needs to be threaded
            self.status_bar.showMessage('Importing: ' + self.file_name,
                                        msg_length)
            try:
                df = tools.to_df(self.file_name,
                                 sep=self.sep,
                                 header=self.header,
                                 index_col=self.index_col,
                                 skiprows=self.skiprows,
                                 dtype=self.dtype,
                                 encoding=self.encoding)
                df.iloc[:, self.xcol_idx]
                df.iloc[:, self.ycol_idx]
            except Exception:
                self.status_bar.showMessage(file_import_error_msg,
                                            2 * msg_length)
                return
        else:
            self.status_bar.showMessage('Import canceled.', msg_length)
            return

        self.data = df
        self.table_model = PandasModel(self.data)
        self.tab2.setModel(self.table_model)
        self.tab2.resizeColumnsToContents()
        # clear any previous fit result
        self.result = None
        # reset x, y, and xlim
        self.x = self.data.iloc[:, self.xcol_idx].values
        self.y = self.data.iloc[:, self.ycol_idx].values
        self.xmin = self.data.iloc[:, self.xcol_idx].min()
        self.xmax = self.data.iloc[:, self.xcol_idx].max()
        self.plot()
        self.status_bar.showMessage('Import finished.', msg_length)

    def import_settings_dialog(self):
        self.dialog_window = QDialog()
        self.dialog_window.setWindowTitle('File Import Settings')
        toplevel = QVBoxLayout()
        dialog_layout = QHBoxLayout()
        label_layout = QVBoxLayout()
        entry_layout = QVBoxLayout()
        button_layout = QVBoxLayout()
        label1 = QLabel(self.dialog_window)
        label1.setText('sep')
        label2 = QLabel(self.dialog_window)
        label2.setText('header')
        label3 = QLabel(self.dialog_window)
        label3.setText('skiprows')
        label4 = QLabel(self.dialog_window)
        label4.setText('dtype')
        label5 = QLabel(self.dialog_window)
        label5.setText('encoding')
        for lbl in [label1, label2, label3, label4, label5]:
            label_layout.addWidget(lbl)
        self.sep_edit = QLineEdit(self.dialog_window)
        self.head_edit = QLineEdit(self.dialog_window)
        self.skipr_edit = QLineEdit(self.dialog_window)
        self.dtype_edit = QLineEdit(self.dialog_window)
        self.enc_edit = QLineEdit(self.dialog_window)
        self.sep_edit.setText(self.sep)
        self.head_edit.setText(self.header)
        # if value is None, show text as 'None'
        if self.skiprows is not None:
            self.skipr_edit.setText(self.skiprows)
        else:
            self.skipr_edit.setText('None')
        if self.dtype is not None:
            self.dtype_edit.setText(self.dtype)
        else:
            self.dtype_edit.setText('None')
        if self.encoding is not None:
            self.enc_edit.setText(self.encoding)
        else:
            self.enc_edit.setText('None')

        # add widgets to layout
        for ewidget in [
                self.sep_edit, self.head_edit, self.skipr_edit,
                self.dtype_edit, self.enc_edit
        ]:
            ewidget.setAlignment(Qt.AlignCenter)
            entry_layout.addWidget(ewidget)

        button1 = QPushButton('Set', self.dialog_window)
        button2 = QPushButton('Set', self.dialog_window)
        button3 = QPushButton('Set', self.dialog_window)
        button4 = QPushButton('Set', self.dialog_window)
        button5 = QPushButton('Set', self.dialog_window)
        for btn in [button1, button2, button3, button4, button5]:
            btn.clicked.connect(self.set_import_settings)
            button_layout.addWidget(btn)

        reflabel = QLabel(self.dialog_window)
        reflabel.setText(
            "for help, refer to <a href='https://pandas.pydata.org/" +
            "pandas-docs/stable/reference/api/" +
            "pandas.read_csv.html'>pandas.read_csv()</a>")
        reflabel.setOpenExternalLinks(True)
        reflabel.setAlignment(Qt.AlignCenter)
        for lo in [label_layout, entry_layout, button_layout]:
            dialog_layout.addLayout(lo)
        toplevel.addLayout(dialog_layout)
        toplevel.addSpacing(25)
        toplevel.addWidget(reflabel)
        self.dialog_window.setLayout(toplevel)
        self.dialog_window.setWindowModality(Qt.ApplicationModal)
        self.dialog_window.exec_()

    def set_import_settings(self):
        self.sep = self.sep_edit.text()
        self.header = self.head_edit.text()
        # convert 'None' entries to None
        if self.skipr_edit.text() == 'None':
            self.skiprows = None
        else:
            self.skiprows = self.skipr_edit.text()
        if self.dtype_edit.text() == 'None':
            self.dtype = None
        else:
            self.dtype = self.dtype_edit.text()
        if self.enc_edit.text() == 'None':
            self.encoding = None
        else:
            self.encoding = self.enc_edit.text()

    def plot(self):
        self.tab1.figure.clear()
        self.ax = self.tab1.figure.add_subplot(111, label=self.file_name)
        self.ax.scatter(self.x,
                        self.y,
                        s=100,
                        c='None',
                        edgecolors='black',
                        linewidth=1,
                        label='data')
        if self.result is not None:
            yfit = self.result.best_fit
            self.ax.plot(self.x, yfit, c='r', linewidth=2.5)
            cmap = cm.get_cmap('gnuplot')
            components = self.result.eval_components()
            for i, comp in enumerate(components):
                self.ax.plot(self.x,
                             components[comp],
                             linewidth=2.5,
                             linestyle='--',
                             c=cmap(i / len(components)),
                             label=comp[:comp.find('_')])
        self.ax.set_xlabel(self.data.columns[self.xcol_idx], labelpad=15)
        self.ax.set_ylabel(self.data.columns[self.ycol_idx], labelpad=15)
        self.ax.set_xlim([self.xmin, self.xmax])
        self.ax.legend(loc='upper right')
        self.tab1.figure.subplots_adjust(bottom=0.15, left=0.06, right=0.94)
        self.tab1.canvas.draw()

    def clear_layout(self, layout):
        if layout:
            while layout.count():
                item = layout.takeAt(0)
                widget = item.widget()
                if widget:
                    widget.deleteLater()
                else:
                    self.clear_layout(item.layout())
                layout.removeItem(item)

    def clear_fit_layouts(self):
        for layout in [
                self.gau_layout, self.lor_layout, self.voi_layout,
                self.lin_layout
        ]:
            self.clear_layout(layout)

    def hard_reset(self):
        self.clear_fit_layouts()
        self.ngau = 0
        self.nlor = 0
        self.nvoi = 0
        self.nlin = 1
        self.init_model()
        self.params = Parameters()
        self.result = None
        self.params_df = None
        self.curves_df = None
        self.guesses = {'value': {}, 'min': {}, 'max': {}}
        self.usr_vals = {'value': {}, 'min': {}, 'max': {}}
        self.init_param_widgets()
        self.plot()

    def increment(self, val, add):
        if add:
            if val == 'gau':
                self.ngau += 1
            if val == 'lor':
                self.nlor += 1
            if val == 'voi':
                self.nvoi += 1
            if val == 'lin':
                self.nlin += 1
        if not add:
            if val == 'gau':
                self.ngau -= 1
            if val == 'lor':
                self.nlor -= 1
            if val == 'voi':
                self.nvoi -= 1
            if val == 'lin':
                self.nlin -= 1

        # make sure value doesn't go below zero
        if self.ngau < 0:
            self.ngau = 0
        if self.nlor < 0:
            self.nlor = 0
        if self.nvoi < 0:
            self.nvoi = 0
        if self.nlin < 1:
            self.nlin = 1
Esempio n. 40
0
class PrecisionRotate(ToolInstance):

    help = "https://github.com/QChASM/SEQCROW/wiki/Rotate-Tool"
    SESSION_ENDURING = True
    SESSION_SAVE = True

    def __init__(self, session, name):
        super().__init__(session, name)

        self.tool_window = MainToolWindow(self)

        self.settings = _PrecisionRotateSettings(session, name)

        self.bonds = {}
        self.bond_centers = {}
        self.groups = {}
        self.perpendiculars = {}
        self.perp_centers = {}
        self.manual_center = {}

        self._build_ui()

        self._show_rot_vec = self.session.triggers.add_handler(
            SELECTION_CHANGED, self.show_rot_vec)
        global_triggers = get_triggers()
        self._changes = global_triggers.add_handler("changes done",
                                                    self.show_rot_vec)

        self.show_rot_vec()

    def _build_ui(self):
        layout = QGridLayout()

        layout.addWidget(QLabel("center of rotation:"), 0, 0, 1, 1,
                         Qt.AlignLeft | Qt.AlignVCenter)

        self.cor_button = QComboBox()
        self.cor_button.addItems(
            ["automatic", "select atoms", "view's center of rotation"])
        layout.addWidget(self.cor_button, 0, 1, 1, 1, Qt.AlignTop)

        self.set_cor_selection = QPushButton("set selection")
        self.cor_button.currentTextChanged.connect(
            lambda t, widget=self.set_cor_selection: widget.setEnabled(
                t == "select atoms"))
        self.set_cor_selection.clicked.connect(self.manual_cor)
        layout.addWidget(self.set_cor_selection, 0, 2, 1, 1, Qt.AlignTop)
        self.set_cor_selection.setEnabled(False)

        layout.addWidget(QLabel("rotation vector:"), 1, 0, 1, 1,
                         Qt.AlignLeft | Qt.AlignVCenter)

        self.vector_option = QComboBox()
        self.vector_option.addItems([
            "axis", "view axis", "bond", "perpendicular to plane",
            "centroid of atoms", "custom"
        ])
        layout.addWidget(self.vector_option, 1, 1, 1, 1, Qt.AlignVCenter)

        vector = QWidget()
        vector.setToolTip("vector will be normalized before rotating")
        vector_layout = QHBoxLayout(vector)
        vector_layout.setContentsMargins(0, 0, 0, 0)
        self.vector_x = QDoubleSpinBox()
        self.vector_y = QDoubleSpinBox()
        self.vector_z = QDoubleSpinBox()
        self.vector_z.setValue(1.0)
        for c, t in zip([self.vector_x, self.vector_y, self.vector_z],
                        [" x", " y", " z"]):
            c.setSingleStep(0.01)
            c.setRange(-100, 100)
            # c.setSuffix(t)
            c.valueChanged.connect(self.show_rot_vec)
            vector_layout.addWidget(c)

        layout.addWidget(vector, 1, 2, 1, 1, Qt.AlignTop)
        vector.setVisible(self.vector_option.currentText() == "custom")
        self.vector_option.currentTextChanged.connect(
            lambda text, widget=vector: widget.setVisible(text == "custom"))

        self.view_axis = QComboBox()
        self.view_axis.addItems(["z", "y", "x"])
        layout.addWidget(self.view_axis, 1, 2, 1, 1, Qt.AlignTop)
        self.view_axis.setVisible(
            self.vector_option.currentText() == "view axis")
        self.vector_option.currentTextChanged.connect(
            lambda text, widget=self.view_axis: widget.setVisible(text ==
                                                                  "view axis"))

        self.axis = QComboBox()
        self.axis.addItems(["z", "y", "x"])
        layout.addWidget(self.axis, 1, 2, 1, 1, Qt.AlignTop)
        self.axis.setVisible(self.vector_option.currentText() == "axis")
        self.vector_option.currentTextChanged.connect(
            lambda text, widget=self.axis: widget.setVisible(text == "axis"))

        self.bond_button = QPushButton("set selected bond")
        self.bond_button.clicked.connect(self.set_bonds)
        layout.addWidget(self.bond_button, 1, 2, 1, 1, Qt.AlignTop)
        self.bond_button.setVisible(self.vector_option.currentText() == "bond")
        self.vector_option.currentTextChanged.connect(
            lambda text, widget=self.bond_button: widget.setVisible(text ==
                                                                    "bond"))

        self.perp_button = QPushButton("set selected atoms")
        self.perp_button.clicked.connect(self.set_perpendicular)
        layout.addWidget(self.perp_button, 1, 2, 1, 1, Qt.AlignTop)
        self.perp_button.setVisible(
            self.vector_option.currentText() == "perpendicular to plane")
        self.vector_option.currentTextChanged.connect(
            lambda text, widget=self.perp_button: widget.setVisible(
                text == "perpendicular to plane"))

        self.group_button = QPushButton("set selected atoms")
        self.group_button.clicked.connect(self.set_group)
        layout.addWidget(self.group_button, 1, 2, 1, 1, Qt.AlignTop)
        self.group_button.setVisible(
            self.vector_option.currentText() == "centroid of atoms")
        self.vector_option.currentTextChanged.connect(
            lambda text, widget=self.group_button: widget.setVisible(
                text == "centroid of atoms"))

        layout.addWidget(QLabel("angle:"), 2, 0, 1, 1,
                         Qt.AlignLeft | Qt.AlignVCenter)

        self.angle = QDoubleSpinBox()
        self.angle.setRange(-360, 360)
        self.angle.setSingleStep(5)
        self.angle.setSuffix("°")
        layout.addWidget(self.angle, 2, 1, 1, 1,
                         Qt.AlignLeft | Qt.AlignVCenter)

        layout.addWidget(QLabel("preview rotation axis:"), 3, 0, 1, 1,
                         Qt.AlignLeft | Qt.AlignVCenter)
        self.display_rot_vec = QCheckBox()
        self.display_rot_vec.setCheckState(Qt.Checked)
        self.display_rot_vec.stateChanged.connect(self.show_rot_vec)
        layout.addWidget(self.display_rot_vec, 3, 1, 1, 1,
                         Qt.AlignLeft | Qt.AlignVCenter)

        rotate_button = QPushButton("rotate selected atoms")
        rotate_button.clicked.connect(self.do_rotate)
        layout.addWidget(rotate_button, 4, 0, 1, 3, Qt.AlignTop)
        self.rotate_button = rotate_button

        self.status_bar = QStatusBar()
        self.status_bar.setSizeGripEnabled(False)
        layout.addWidget(self.status_bar, 5, 0, 1, 3, Qt.AlignTop)

        self.vector_option.currentTextChanged.connect(self.show_auto_status)
        self.cor_button.currentIndexChanged.connect(
            lambda *args: self.show_auto_status("select atoms"))

        self.cor_button.currentIndexChanged.connect(self.show_rot_vec)
        self.set_cor_selection.clicked.connect(self.show_rot_vec)
        self.vector_option.currentIndexChanged.connect(self.show_rot_vec)
        self.axis.currentIndexChanged.connect(self.show_rot_vec)
        self.view_axis.currentIndexChanged.connect(self.show_rot_vec)
        self.bond_button.clicked.connect(self.show_rot_vec)
        self.perp_button.clicked.connect(self.show_rot_vec)
        self.group_button.clicked.connect(self.show_rot_vec)

        layout.setRowStretch(0, 0)
        layout.setRowStretch(1, 0)
        layout.setRowStretch(2, 0)
        layout.setRowStretch(3, 0)
        layout.setRowStretch(4, 0)
        layout.setRowStretch(5, 1)

        layout.setColumnStretch(0, 0)
        layout.setColumnStretch(1, 1)
        layout.setColumnStretch(2, 1)

        self.tool_window.ui_area.setLayout(layout)

        self.tool_window.manage(None)

    def manual_cor(self, *args):
        selection = selected_atoms(self.session)

        models = {}
        for atom in selection:
            if atom.structure not in models:
                models[atom.structure] = [atom]
            else:
                models[atom.structure].append(atom)

        self.manual_center = {}
        for model in models:
            atoms = models[model]
            coords = np.array([atom.coord for atom in atoms])
            self.manual_center[model] = np.mean(coords, axis=0)

    def show_auto_status(self, text):
        if self.cor_button.currentText() == "automatic":
            if text == "bond":
                self.status_bar.showMessage(
                    "center set to one of the bonded atoms")
            elif text == "perpendicular to plane":
                self.status_bar.showMessage("center set to centroid of atoms")
            else:
                self.status_bar.showMessage(
                    "center set to centroid of rotating atoms")

        elif self.cor_button.currentText() == "select atoms":
            self.status_bar.showMessage(
                "center set to centroid of specified atoms")

        else:
            self.status_bar.showMessage(
                "center set to view's center of rotation")

    def set_bonds(self, *args):
        bonds = selected_bonds(self.session)
        if len(bonds) == 0:
            self.session.logger.error("no bonds selected")
            return

        models = [bond.structure for bond in bonds]
        if any(models.count(m) > 1 for m in models):
            self.session.logger.error(
                "multiple bonds selected on the same structure")
            return

        self.bonds = {
            model: (bond.atoms[0].coord - bond.atoms[1].coord)
            for model, bond in zip(models, bonds)
        }
        self.bond_centers = {
            model: bond.atoms[1].coord
            for model, bond in zip(models, bonds)
        }

    def set_perpendicular(self, *args):
        atoms = selected_atoms(self.session)
        if len(atoms) == 0:
            self.session.logger.error("no atoms selected")
            return

        self.perpendiculars = {}
        self.perp_centers = {}

        models = set(atom.structure for atom in atoms)
        for model in models:
            atom_coords = []
            for atom in atoms:
                if atom.structure is model:
                    atom_coords.append(atom.coord)

            if len(atom_coords) < 3:
                self.session.logger.error("fewer than 3 atoms selected on %s" %
                                          model.atomspec)
                continue

            xyz = np.array(atom_coords)
            xyz -= np.mean(atom_coords, axis=0)
            R = np.dot(xyz.T, xyz)
            u, s, vh = np.linalg.svd(R, compute_uv=True)
            vector = u[:, -1]

            self.perpendiculars[model] = vector
            self.perp_centers[model] = np.mean(atom_coords, axis=0)

    def set_group(self, *args):
        atoms = selected_atoms(self.session)
        if len(atoms) == 0:
            self.session.logger.error("no atoms selected")
            return

        self.groups = {}

        models = set(atom.structure for atom in atoms)
        for model in models:
            atom_coords = []
            for atom in atoms:
                if atom.structure is model:
                    atom_coords.append(atom.coord)

            self.groups[model] = np.mean(atom_coords, axis=0)

    def do_rotate(self, *args):
        selection = selected_atoms(self.session)

        models = {}
        for atom in selection:
            if atom.structure not in models:
                models[atom.structure] = [atom]
            else:
                models[atom.structure].append(atom)

        if len(models.keys()) == 0:
            return

        if self.vector_option.currentText() == "axis":
            if self.axis.currentText() == "z":
                vector = np.array([0., 0., 1.])
            elif self.axis.currentText() == "y":
                vector = np.array([0., 1., 0.])
            elif self.axis.currentText() == "x":
                vector = np.array([1., 0., 0.])

        elif self.vector_option.currentText() == "view axis":
            if self.view_axis.currentText() == "z":
                vector = self.session.view.camera.get_position().axes()[2]
            elif self.view_axis.currentText() == "y":
                vector = self.session.view.camera.get_position().axes()[1]
            elif self.view_axis.currentText() == "x":
                vector = self.session.view.camera.get_position().axes()[0]

        elif self.vector_option.currentText() == "bond":
            vector = self.bonds

        elif self.vector_option.currentText() == "perpendicular to plane":
            vector = self.perpendiculars

        elif self.vector_option.currentText() == "centroid of atoms":
            vector = self.groups

        elif self.vector_option.currentText() == "custom":
            x = self.vector_x.value()
            y = self.vector_y.value()
            z = self.vector_z.value()
            vector = np.array([x, y, z])

        angle = np.deg2rad(self.angle.value())

        center = {}
        for model in models:
            atoms = models[model]
            coords = np.array([atom.coord for atom in atoms])
            center[model] = np.mean(coords, axis=0)

        if self.cor_button.currentText() == "automatic":
            if self.vector_option.currentText() == "perpendicular to plane":
                center = self.perp_centers

            elif self.vector_option.currentText() == "bond":
                center = self.bond_centers

        elif self.cor_button.currentText() == "select atoms":
            center = self.manual_center

        else:
            center = self.session.main_view.center_of_rotation

        for model in models:
            if isinstance(vector, dict):
                if model not in vector.keys():
                    continue
                else:
                    v = vector[model]

            else:
                v = vector

            if isinstance(center, dict):
                if model not in center.keys():
                    continue
                else:
                    c = center[model]

            else:
                c = center

            if self.vector_option.currentText(
            ) == "centroid of atoms" and self.cor_button.currentText(
            ) != "automatic":
                v = v - c

            v = v / np.linalg.norm(v)
            q = np.hstack(([np.cos(angle / 2)], v * np.sin(angle / 2)))

            q /= np.linalg.norm(q)
            qs = q[0]
            qv = q[1:]

            xyz = np.array([a.coord for a in models[model]])
            xyz -= c
            xprod = np.cross(qv, xyz)
            qs_xprod = 2 * qs * xprod
            qv_xprod = 2 * np.cross(qv, xprod)

            xyz += qs_xprod + qv_xprod + c
            for t, coord in zip(models[model], xyz):
                t.coord = coord

    def show_rot_vec(self, *args):
        for model in self.session.models.list(type=Generic3DModel):
            if model.name == "rotation vector":
                model.delete()

        if self.display_rot_vec.checkState() == Qt.Unchecked:
            return

        selection = selected_atoms(self.session)

        if len(selection) == 0:
            return

        models = {}
        for atom in selection:
            if atom.structure not in models:
                models[atom.structure] = [atom]
            else:
                models[atom.structure].append(atom)

        if len(models.keys()) == 0:
            return

        if self.vector_option.currentText() == "axis":
            if self.axis.currentText() == "z":
                vector = np.array([0., 0., 1.])
            elif self.axis.currentText() == "y":
                vector = np.array([0., 1., 0.])
            elif self.axis.currentText() == "x":
                vector = np.array([1., 0., 0.])

        elif self.vector_option.currentText() == "view axis":
            if self.view_axis.currentText() == "z":
                vector = self.session.view.camera.get_position().axes()[2]
            elif self.view_axis.currentText() == "y":
                vector = self.session.view.camera.get_position().axes()[1]
            elif self.view_axis.currentText() == "x":
                vector = self.session.view.camera.get_position().axes()[0]

        elif self.vector_option.currentText() == "bond":
            vector = self.bonds

        elif self.vector_option.currentText() == "perpendicular to plane":
            vector = self.perpendiculars

        elif self.vector_option.currentText() == "centroid of atoms":
            vector = self.groups

        elif self.vector_option.currentText() == "custom":
            x = self.vector_x.value()
            y = self.vector_y.value()
            z = self.vector_z.value()
            vector = np.array([x, y, z])

        angle = np.deg2rad(self.angle.value())

        center = {}
        for model in models:
            atoms = models[model]
            coords = np.array([atom.coord for atom in atoms])
            center[model] = np.mean(coords, axis=0)

        if self.cor_button.currentText() == "automatic":
            if self.vector_option.currentText() == "perpendicular to plane":
                center = self.perp_centers

            elif self.vector_option.currentText() == "bond":
                center = self.bond_centers

        elif self.cor_button.currentText() == "select atoms":
            center = self.manual_center

        else:
            center = self.session.main_view.center_of_rotation

        for model in models:
            if isinstance(vector, dict):
                if model not in vector.keys():
                    continue
                else:
                    v = vector[model]

            else:
                v = vector

            if isinstance(center, dict):
                if model not in center.keys():
                    continue
                else:
                    c = center[model]

            else:
                c = center

            if self.vector_option.currentText(
            ) == "centroid of atoms" and self.cor_button.currentText(
            ) != "automatic":
                v = v - c

            if np.linalg.norm(v) == 0:
                continue

            residues = []
            for atom in models[model]:
                if atom.residue not in residues:
                    residues.append(atom.residue)

            v_c = c + v

            s = ".color red\n"
            s += ".arrow %10.6f %10.6f %10.6f   %10.6f %10.6f %10.6f   0.2 0.4 0.7\n" % (
                *c, *v_c)

            stream = BytesIO(bytes(s, 'utf-8'))
            bild_obj, status = read_bild(self.session, stream,
                                         "rotation vector")

            self.session.models.add(bild_obj, parent=model)

    def delete(self):
        self.session.triggers.remove_handler(self._show_rot_vec)
        global_triggers = get_triggers()
        global_triggers.remove_handler(self._changes)

        for model in self.session.models.list(type=Generic3DModel):
            if model.name == "rotation vector":
                model.delete()

        return super().delete()

    def close(self):
        self.session.triggers.remove_handler(self._show_rot_vec)
        global_triggers = get_triggers()
        global_triggers.remove_handler(self._changes)

        for model in self.session.models.list(type=Generic3DModel):
            if model.name == "rotation vector":
                model.delete()

        return super().close()
Esempio n. 41
0
class TagStructuresWidget(QWidget):
    def __init__(self, app):
        super().__init__()
        self.images_paths = []
        self.selected_image_path = ""
        self.app = app

        self.files_list = QListWidget()
        self.structures_list = QListWidget()
        self.image_widget = TaggableImageWidget()
        self.highlighter_checkbox = QCheckBox("Wskaż wybraną strukturę")
        self.init_ui()

    def init_ui(self):
        self.image_widget.set_highlighter_pixmap(
            QPixmap("./resources/arrow.png"))
        self.image_widget.hide_highlighter()
        self.files_list.itemClicked.connect(self.on_files_list_item_clicked)
        self.files_list.itemActivated.connect(self.on_files_list_item_clicked)

        self.structures_list.itemChanged.connect(
            self.on_structure_name_changed)
        self.structures_list.itemClicked.connect(
            self.on_structure_name_clicked)
        self.structures_list.itemActivated.connect(
            self.on_structure_name_clicked)
        self.image_widget.on_tag_added.connect(self.on_tag_added)
        self.highlighter_checkbox.stateChanged.connect(
            self.set_hightlighter_visibility_state)

        self.grid = QGridLayout()
        self.grid.setColumnStretch(0, 1)
        self.grid.setColumnStretch(1, 3)

        self.lists_tab = QTabWidget()
        self.lists_tab.addTab(self.files_list, "Zdjęcia")
        self.lists_tab.addTab(self.structures_list, "Struktury")

        self.grid.addWidget(self.lists_tab, 0, 0)

        self.grid.addWidget(self.image_widget, 0, 1)

        back_btn = QPushButton("Zapisz i powróć")
        back_btn.clicked.connect(self.save_and_go_home)

        save_btn = QPushButton("Zapisz")
        save_btn.clicked.connect(self.app.save_workspace_structures)

        btn_layout = QHBoxLayout()
        btn_layout.addWidget(back_btn)
        btn_layout.addWidget(save_btn)

        self.grid.addLayout(btn_layout, 1, 0)
        self.grid.addWidget(self.highlighter_checkbox, 1, 1)

        self.setLayout(self.grid)

    def load_images_paths(self):
        self.images_paths = load_files_paths(self.app.workspace_path,
                                             ("jpeg", "jpg", "png"))
        self.files_list.clear()

        for path in self.images_paths:
            self.files_list.addItem(path)

    def on_files_list_item_clicked(self, item):
        self.selected_image_path = item.text()
        image_path = os.path.join(self.app.workspace_path,
                                  self.selected_image_path)
        self.image_widget.set_pixmap(QPixmap(image_path))
        self.image_widget.hide_highlighter()
        self.image_widget.clear_tags()
        label_id = 0

        self.structures_list.clear()
        for tagdata in self.app.workspace_structures.setdefault(
                self.selected_image_path, []):
            label_id += 1
            self.add_tag(label_id, tagdata)

    def on_tag_added(self, x, y):
        text, ok = QInputDialog.getText(self, 'Wprowadź strukturę',
                                        'Pol, Łac, Ang:')
        if ok:
            structures = self.app.workspace_structures[
                self.selected_image_path]
            tagdata = {'text': text, 'x': x, 'y': y}
            structures.append(tagdata)

            label_id = len(
                self.app.workspace_structures[self.selected_image_path])
            self.add_tag(label_id, tagdata)

    def on_structure_name_changed(self, item):
        item_id = self.structures_list.indexFromItem(item).row()
        if len(item.text()) > 0:
            self.update_structure_name(item_id, item)
        else:
            self.delete_structure(item_id, item)

    def on_structure_name_clicked(self, item):
        item_id = self.structures_list.indexFromItem(item).row()
        self.image_widget.highlight_tag_at(item_id)

        if self.highlighter_checkbox.checkState() == Qt.Checked:
            self.image_widget.show_highlighter()

    def update_structure_name(self, item_id, item):
        # update tag
        tag = self.image_widget.tag_at(item_id)
        tag.setToolTip(item.text())
        # update structure text
        structures = self.app.workspace_structures[self.selected_image_path]
        structures[item_id]['text'] = item.text()

    def delete_structure(self, item_id, item):
        # delete from structures
        structures = self.app.workspace_structures[self.selected_image_path]
        del structures[item_id]
        # update list and tags, so IDs can be restored
        mocked_item = QListWidgetItem()
        mocked_item.setText(self.selected_image_path)
        self.on_files_list_item_clicked(mocked_item)

    def save_and_go_home(self):
        self.app.save_workspace_structures()
        self.app.go_home()

    def add_tag(self, label_id, tagdata):
        item_widget = QListWidgetItem()
        item_widget.setText(tagdata['text'])
        item_widget.setFlags(item_widget.flags() | Qt.ItemIsEditable)
        self.structures_list.addItem(item_widget)

        tag_widget = TagWidget(str(label_id), tagdata['text'], tagdata['x'],
                               tagdata['y'])
        tag_widget.adjust_to_size(self.image_widget.image().size(), 0.015 / 2)

        self.image_widget.addWidget(tag_widget)

    def set_hightlighter_visibility_state(self, state):
        if len(self.structures_list.selectedItems()) > 0 and state:
            self.image_widget.show_highlighter()
        else:
            self.image_widget.hide_highlighter()
Esempio n. 42
0
class _SingleRoiCtrlWidget(QWidget):
    """_SingleRoiCtrlWidget class.

    Widget which controls a single ROI.
    """
    # (idx, x, y, w, h) where idx starts from 1
    roi_geometry_change_sgn = pyqtSignal(object)

    _pos_validator = QIntValidator(-10000, 10000)
    _size_validator = QIntValidator(1, 10000)

    INVALID_GEOM = RectRoiGeom.INVALID

    def __init__(self, roi: RectROI, *, parent=None):
        super().__init__(parent=parent)
        self._roi = roi

        self._activate_cb = QCheckBox("On")
        self._lock_cb = QCheckBox("Lock")

        self._width_le = SmartLineEdit()
        self._width_le.setValidator(self._size_validator)
        self._height_le = SmartLineEdit()
        self._height_le.setValidator(self._size_validator)
        self._px_le = SmartLineEdit()
        self._px_le.setValidator(self._pos_validator)
        self._py_le = SmartLineEdit()
        self._py_le.setValidator(self._pos_validator)

        self._line_edits = (self._width_le, self._height_le, self._px_le,
                            self._py_le)

        self.initUI()
        self.initConnections()

        self.disableAllEdit()

    def initUI(self):
        layout = QHBoxLayout()
        idx = self._roi.index

        label = QLabel(f"ROI{idx}: ")
        palette = label.palette()
        palette.setColor(palette.WindowText,
                         FColor.mkColor(config['GUI_ROI_COLORS'][idx - 1]))
        label.setPalette(palette)
        layout.addWidget(label)

        layout.addWidget(self._activate_cb)
        layout.addWidget(self._lock_cb)
        layout.addWidget(QLabel("w: "))
        layout.addWidget(self._width_le)
        layout.addWidget(QLabel("h: "))
        layout.addWidget(self._height_le)
        layout.addWidget(QLabel("x: "))
        layout.addWidget(self._px_le)
        layout.addWidget(QLabel("y: "))
        layout.addWidget(self._py_le)

        self.setLayout(layout)
        # left, top, right, bottom
        self.layout().setContentsMargins(2, 1, 2, 1)

    def initConnections(self):
        self._width_le.value_changed_sgn.connect(self.onRoiSizeEdited)
        self._height_le.value_changed_sgn.connect(self.onRoiSizeEdited)
        self._px_le.value_changed_sgn.connect(self.onRoiPositionEdited)
        self._py_le.value_changed_sgn.connect(self.onRoiPositionEdited)

        self._roi.sigRegionChangeFinished.connect(
            self.onRoiGeometryChangeFinished)

        self._activate_cb.stateChanged.connect(self.onToggleRoiActivation)
        self._activate_cb.stateChanged.emit(self._activate_cb.checkState())
        self._lock_cb.stateChanged.connect(self.onLock)

    @pyqtSlot(int)
    def onToggleRoiActivation(self, state):
        if state == Qt.Checked:
            self._roi.show()
            self.enableAllEdit()
            x, y = [int(v) for v in self._roi.pos()]
            w, h = [int(v) for v in self._roi.size()]
        else:
            self._roi.hide()
            self.disableAllEdit()
            x, y, w, h = self.INVALID_GEOM

        self.roi_geometry_change_sgn.emit((self._roi.index, x, y, w, h))

    @pyqtSlot(object)
    def onRoiPositionEdited(self, value):
        x, y = [int(v) for v in self._roi.pos()]
        w, h = [int(v) for v in self._roi.size()]

        if self.sender() == self._px_le:
            x = int(self._px_le.text())
        elif self.sender() == self._py_le:
            y = int(self._py_le.text())

        # If 'update' == False, the state change will be remembered
        # but not processed and no signals will be emitted.
        self._roi.setPos((x, y), update=False)
        # trigger sigRegionChanged which moves the handler(s)
        # finish=False -> sigRegionChangeFinished will not emit, which
        # otherwise triggers infinite recursion
        self._roi.stateChanged(finish=False)

        if not self._activate_cb.isChecked():
            x, y, w, h = self.INVALID_GEOM

        self.roi_geometry_change_sgn.emit((self._roi.index, x, y, w, h))

    @pyqtSlot(object)
    def onRoiSizeEdited(self, value):
        x, y = [int(v) for v in self._roi.pos()]
        w, h = [int(v) for v in self._roi.size()]
        if self.sender() == self._width_le:
            w = int(self._width_le.text())
        elif self.sender() == self._height_le:
            h = int(self._height_le.text())

        # If 'update' == False, the state change will be remembered
        # but not processed and no signals will be emitted.
        self._roi.setSize((w, h), update=False)
        # trigger sigRegionChanged which moves the handler(s)
        # finish=False -> sigRegionChangeFinished will not emit, which
        # otherwise triggers infinite recursion
        self._roi.stateChanged(finish=False)

        if not self._activate_cb.isChecked():
            x, y, w, h = self.INVALID_GEOM

        self.roi_geometry_change_sgn.emit((self._roi.index, x, y, w, h))

    @pyqtSlot(object)
    def onRoiGeometryChangeFinished(self, roi):
        """Connect to the signal from an ROI object."""
        x, y = [int(v) for v in roi.pos()]
        w, h = [int(v) for v in roi.size()]
        self.updateParameters(x, y, w, h)
        # inform widgets outside this window

        if not self._activate_cb.isChecked():
            x, y, w, h = self.INVALID_GEOM

        self.roi_geometry_change_sgn.emit((roi.index, x, y, w, h))

    def notifyRoiParams(self):
        # fill the QLineEdit(s) and Redis
        self._roi.sigRegionChangeFinished.emit(self._roi)

    def updateParameters(self, x, y, w, h):
        self.roi_geometry_change_sgn.disconnect()
        self._px_le.setText(str(x))
        self._py_le.setText(str(y))
        self._width_le.setText(str(w))
        self._height_le.setText(str(h))
        self.roi_geometry_change_sgn.connect(Mediator().onRoiGeometryChange)

    def setEditable(self, editable):
        for w in self._line_edits:
            w.setDisabled(not editable)

    @pyqtSlot(int)
    def onLock(self, state):
        self._roi.setLocked(state == Qt.Checked)
        self.setEditable(not state == Qt.Checked)

    def disableAllEdit(self):
        self.setEditable(False)
        self._lock_cb.setDisabled(True)

    def enableAllEdit(self):
        self._lock_cb.setDisabled(False)
        self.setEditable(True)
Esempio n. 43
0
class BuildPage(QWidget):
    """ The GUI for the build page of a project. """

    # The page's label.
    label = "Build"

    def __init__(self):
        """ Initialise the page. """

        super().__init__()

        self.project = None

        # Create the page's GUI.
        layout = QGridLayout()

        self._log_viewer = QPlainTextEdit(
                whatsThis="This displays the messages generated when building "
                        "the application.",
                readOnly=True)
        layout.addWidget(self._log_viewer, 0, 0, 5, 1)

        build = QPushButton("Build",
                whatsThis="Build the application and optionally run "
                        "<tt>qmake</tt>, <tt>make</tt> and the application "
                        "itself.",
                clicked=self._build)
        layout.addWidget(build, 0, 1)

        optimisation = QGroupBox("Optimisations")
        optimisation_layout = QVBoxLayout()

        self._opt1_button = QCheckBox("No asserts",
                whatsThis="The compiled Python code will not contain any "
                        "<tt>assert</tt> statements.",
                checked=True, stateChanged=self._opt1_changed)
        optimisation_layout.addWidget(self._opt1_button)
        self._opt2_button = QCheckBox("No docstrings",
                whatsThis="The compiled Python code will not contain any "
                        "docstrings.",
                checked=True, stateChanged=self._opt2_changed)
        optimisation_layout.addWidget(self._opt2_button)

        optimisation.setLayout(optimisation_layout)
        layout.addWidget(optimisation, 1, 1)

        options = QGroupBox("Build Options")
        options_layout = QGridLayout()

        self._clean_button = QCheckBox("Clean before building",
                whatsThis="The build directory will be deleted and recreated "
                        "before starting a new build.",
                checked=True)
        options_layout.addWidget(self._clean_button, 0, 0, 1, 2)
        self._verbose_button = QCheckBox("Verbose output",
                whatsThis="Additional messages will be displayed during the "
                        "build process.")
        options_layout.addWidget(self._verbose_button, 1, 0, 1, 2)
        options_layout.addWidget(QLabel("Resource files"), 2, 0)
        self._resources_edit = QSpinBox(
                whatsThis="The number of Qt <tt>.qrc</tt> files that will be "
                        "generated. Increasing this number reduces the size "
                        "of each file meaning <tt>rcc</tt> requires less "
                        "memory.",
                minimum=1)
        options_layout.addWidget(self._resources_edit, 2, 1)
        options_layout.addWidget(QLabel("Timeout"), 3, 0)
        self._timeout_edit = QSpinBox(
                whatsThis="The number of seconds to wait for build processes "
                        "to run before timing out.",
                minimum=1)
        self._timeout_edit.setValue(30)
        options_layout.addWidget(self._timeout_edit, 3, 1)

        options.setLayout(options_layout)
        layout.addWidget(options, 2, 1)

        steps = QGroupBox("Additional Build Steps")
        steps_layout = QVBoxLayout()

        self._run_qmake_button = QCheckBox("Run qmake",
                whatsThis="Run <tt>qmake</tt> after successfully generating "
                        "the application code.",
                stateChanged=self._run_qmake_changed)
        steps_layout.addWidget(self._run_qmake_button)
        self._run_make_button = QCheckBox("Run make",
                whatsThis="Run <tt>make</tt> after successfully running "
                        "<tt>qmake</tt>.",
                stateChanged=self._run_make_changed)
        steps_layout.addWidget(self._run_make_button)
        self._run_application_button = QCheckBox("Run application",
                whatsThis="Run the application after successfully running "
                        "<tt>make</tt>.",
                stateChanged=self._run_application_changed)
        steps_layout.addWidget(self._run_application_button)

        steps.setLayout(steps_layout)
        layout.addWidget(steps, 3, 1)

        layout.setRowStretch(4, 1)

        self.setLayout(layout)

    def _build(self, _):
        """ Invoked when the user clicks the build button. """

        project = self.project

        # Check the prerequisites.  Note that we don't disable the button if
        # these are missing because (as they are spread across the GUI) the
        # user would have difficulty knowing what needed fixing.
        if project.python_target_include_dir == '':
            self._missing_prereq("target Python include directory")
            return

        if project.python_target_library == '':
            self._missing_prereq("target Python library")
            return

        logger = LoggingMessageHandler(bool(self._verbose_button.checkState()),
                self._log_viewer)
        builder = Builder(project, logger)

        logger.clear()
        logger.status_message("Generating code...")

        if self._opt2_button.checkState():
            opt = 2
        elif self._opt1_button.checkState():
            opt = 1
        else:
            opt = 0

        nr_resources = self._resources_edit.value()

        try:
            builder.build(opt, nr_resources,
                    clean=bool(self._clean_button.checkState()))
        except UserException as e:
            logger.user_exception(e)
            handle_user_exception(e, self.label, self)
            return

        logger.status_message("Code generation succeeded.")

        timeout = self._timeout_edit.value() * 1000

        if self._run_qmake_button.checkState() != Qt.Unchecked:
            qmake = os.path.expandvars(project.qmake)

            if qmake == '':
                QMessageBox.warning(self, self.label,
                    "qmake cannot be run because its name has not been set.")
            else:
                logger.status_message("Running qmake...")

                try:
                    builder.run([qmake], "qmake failed.", in_build_dir=True,
                            timeout=timeout)
                except UserException as e:
                    logger.user_exception(e)
                    handle_user_exception(e, self.label, self)
                    return

                logger.status_message("qmake succeeded.")

        if self._run_make_button.checkState() != Qt.Unchecked:
            make = 'nmake' if sys.platform == 'win32' else 'make'

            logger.status_message("Running {0}...".format(make))

            try:
                builder.run([make], "{0} failed.".format(make),
                        in_build_dir=True, timeout=timeout)
            except UserException as e:
                logger.user_exception(e)
                handle_user_exception(e, self.label, self)
                return

            logger.status_message("{0} succeeded.".format(make))

        if self._run_application_button.checkState() != Qt.Unchecked:
            build_dir = project.path_from_user(project.build_dir)
            exe_name = project.get_executable_basename()

            if sys.platform == 'win32':
                application = build_dir + '/Release/' + exe_name + '.exe'
            elif sys.platform == 'darwin' and project.application_is_bundle:
                application = '/'.join([build_dir, exe_name + '.app',
                        'Contents', 'MacOS', exe_name])
            else:
                application = build_dir + '/' + exe_name

            logger.status_message("Running {0}...".format(exe_name))

            try:
                builder.run([application], "{0} failed.".format(application))
            except UserException as e:
                logger.user_exception(e)
                handle_user_exception(e, self.label, self)
                return

            logger.status_message("{0} succeeded.".format(exe_name))

    def _missing_prereq(self, missing):
        """ Tell the user about a missing prerequisite. """

        QMessageBox.warning(self, self.label,
                "The project cannot be built because the name of the {0} has "
                        "not been set.".format(missing))

    def _opt1_changed(self, state):
        """ Invoked when the user clicks on the no asserts button. """

        if state == Qt.Unchecked:
            self._opt2_button.setCheckState(Qt.Unchecked)

    def _opt2_changed(self, state):
        """ Invoked when the user clicks on the no docstrings button. """

        if state == Qt.Checked:
            self._opt1_button.setCheckState(Qt.Checked)

    def _run_qmake_changed(self, state):
        """ Invoked when the user clicks on the run qmake button. """

        if state == Qt.Unchecked:
            self._run_make_button.setCheckState(Qt.Unchecked)

    def _run_make_changed(self, state):
        """ Invoked when the user clicks on the run make button. """

        if state == Qt.Unchecked:
            self._run_application_button.setCheckState(Qt.Unchecked)
        else:
            self._run_qmake_button.setCheckState(Qt.Checked)

    def _run_application_changed(self, state):
        """ Invoked when the user clicks on the run application button. """

        if state != Qt.Unchecked:
            self._run_make_button.setCheckState(Qt.Checked)
Esempio n. 44
0
class BRFOptionsPanel(QWidget):
    """A Panel where the options to plot the graph are displayed."""

    sig_graphconf_changed = QSignal()

    def __init__(self, parent=None):
        super(BRFOptionsPanel, self).__init__(parent)
        self.__initGUI__()
        self.setVisible(False)

    def __initGUI__(self):
        # ---- Line and Markers Style Widgets

        self._errorbar = QCheckBox('Show error bars')
        self._errorbar.setCheckState(Qt.Checked)
        self._errorbar.stateChanged.connect(self._graphconf_changed)

        self._drawline = QCheckBox('Draw line')
        self._drawline.setCheckState(Qt.Unchecked)
        self._drawline.stateChanged.connect(self._graphconf_changed)

        self._markersize = {}
        self._markersize['label'] = QLabel('Marker size :')
        self._markersize['widget'] = QSpinBox()
        self._markersize['widget'].setValue(5)
        self._markersize['widget'].setRange(0, 25)
        self._markersize['widget'].valueChanged.connect(
                self._graphconf_changed)

        # ---- Y-Axis Options Widgets

        self._ylim = {}
        self._ylim['min'] = QDoubleSpinBox()
        self._ylim['min'].setValue(0)
        self._ylim['min'].setDecimals(1)
        self._ylim['min'].setSingleStep(0.1)
        self._ylim['min'].setRange(-10, 10)
        self._ylim['min'].setEnabled(True)
        self._ylim['min'].valueChanged.connect(self._graphconf_changed)
        self._ylim['max'] = QDoubleSpinBox()
        self._ylim['max'].setValue(1)
        self._ylim['max'].setDecimals(1)
        self._ylim['max'].setSingleStep(0.1)
        self._ylim['max'].setRange(-10, 10)
        self._ylim['max'].setEnabled(True)
        self._ylim['max'].valueChanged.connect(self._graphconf_changed)
        self._ylim['scale'] = QDoubleSpinBox()
        self._ylim['scale'].setValue(0.2)
        self._ylim['scale'].setDecimals(2)
        self._ylim['scale'].setSingleStep(0.05)
        self._ylim['scale'].setRange(0.01, 1)
        self._ylim['scale'].setEnabled(True)
        self._ylim['scale'].valueChanged.connect(self._graphconf_changed)
        self._ylim['auto'] = QCheckBox('')
        self._ylim['auto'].setCheckState(Qt.Checked)
        self._ylim['auto'].stateChanged.connect(self.axis_autocheck_changed)

        # ---- X-Axis Options Widgets

        self._xlim = {}
        self._xlim['units'] = QComboBox()
        self._xlim['units'].addItems(['Hours', 'Days'])
        self._xlim['units'].setCurrentIndex(1)
        self._xlim['units'].currentIndexChanged.connect(
                self.time_units_changed)
        self._xlim['min'] = QSpinBox()
        self._xlim['min'].setValue(0)
        self._xlim['min'].setSingleStep(1)
        self._xlim['min'].setRange(0, 9999)
        self._xlim['min'].setEnabled(True)
        self._xlim['min'].valueChanged.connect(self._graphconf_changed)
        self._xlim['max'] = QSpinBox()
        self._xlim['max'].setValue(1)
        self._xlim['max'].setSingleStep(1)
        self._xlim['max'].setRange(1, 9999)
        self._xlim['max'].setEnabled(True)
        self._xlim['max'].valueChanged.connect(self._graphconf_changed)
        self._xlim['scale'] = QDoubleSpinBox()
        self._xlim['scale'].setValue(1)
        self._xlim['scale'].setDecimals(1)
        self._xlim['scale'].setSingleStep(0.1)
        self._xlim['scale'].setRange(0.1, 99)
        self._xlim['scale'].setEnabled(True)
        self._xlim['scale'].valueChanged.connect(self._graphconf_changed)
        self._xlim['auto'] = QCheckBox('')
        self._xlim['auto'].setCheckState(Qt.Checked)
        self._xlim['auto'].stateChanged.connect(self.axis_autocheck_changed)

        self.axis_autocheck_changed()

        # ---- Axis Options Layout

        axlayout = QGridLayout()

        row = 0
        axlayout.addWidget(QLabel('y-axis limits:'), 0, 0, 1, 2)
        row += 1
        axlayout.addWidget(QLabel('   Minimum :'), row, 0)
        axlayout.addWidget(self._ylim['min'], row, 1)
        row += 1
        axlayout.addWidget(QLabel('   Maximum :'), row, 0)
        axlayout.addWidget(self._ylim['max'], row, 1)
        row += 1
        axlayout.addWidget(QLabel('   Scale :'), row, 0)
        axlayout.addWidget(self._ylim['scale'], row, 1)
        row += 1
        axlayout.addWidget(QLabel('   Auto :'), row, 0)
        axlayout.addWidget(self._ylim['auto'], row, 1)
        row += 1
        axlayout.setRowMinimumHeight(row, 15)
        row += 1
        axlayout.addWidget(QLabel('x-axis limits:'), row, 0, 1, 2)
        row += 1
        axlayout.addWidget(QLabel('   Time units :'), row, 0)
        axlayout.addWidget(self._xlim['units'], row, 1)
        row += 1
        axlayout.addWidget(QLabel('   Minimum :'), row, 0)
        axlayout.addWidget(self._xlim['min'], row, 1)
        row += 1
        axlayout.addWidget(QLabel('   Maximum :'), row, 0)
        axlayout.addWidget(self._xlim['max'], row, 1)
        row += 1
        axlayout.addWidget(QLabel('   Scale :'), row, 0)
        axlayout.addWidget(self._xlim['scale'], row, 1)
        row += 1
        axlayout.addWidget(QLabel('   Auto :'), row, 0)
        axlayout.addWidget(self._xlim['auto'], row, 1)

        axlayout.setColumnStretch(3, 100)
        axlayout.setContentsMargins(0, 0, 0, 0)  # (left, top, right, bottom)

        # ---- Graph Panel Layout

        layout = QGridLayout(self)
        layout.setContentsMargins(10, 0, 10, 0)  # (l, t, r, b)

        row = 0
        layout.addWidget(self._errorbar, row, 1, 1, 2)
        row += 1
        layout.addWidget(self._drawline, row, 1, 1, 2)
        row += 1
        layout.addWidget(self._markersize['label'], row, 1)
        layout.addWidget(self._markersize['widget'], row, 2)
        row += 1
        layout.addWidget(HSep(), row, 1, 1, 2)
        row += 1
        layout.addLayout(axlayout, row, 1, 1, 2)
        row += 1
        layout.setRowMinimumHeight(row, 15)
        layout.setRowStretch(row, 100)

    def _graphconf_changed(self):
        """
        Emits a signal to indicate that the graph configuration has changed.
        """
        self.sig_graphconf_changed.emit()

    # ---- Graph Panel Properties

    @property
    def time_units(self):
        if self._xlim['auto'].checkState() == Qt.Checked:
            return 'auto'
        else:
            return self._xlim['units'].currentText().lower()

    @property
    def xmin(self):
        if self._xlim['auto'].checkState() == Qt.Checked:
            return None
        else:
            if self.time_units == 'hours':
                return self._xlim['min'].value()/24
            else:
                return self._xlim['min'].value()

    @property
    def xmax(self):
        if self._xlim['auto'].checkState() == Qt.Checked:
            return None
        else:
            if self.time_units == 'hours':
                return self._xlim['max'].value()/24
            else:
                return self._xlim['max'].value()

    @property
    def xscale(self):
        if self._xlim['auto'].checkState() == Qt.Checked:
            return None
        else:
            if self.time_units == 'hours':
                return self._xlim['scale'].value()/24
            else:
                return self._xlim['scale'].value()

    @property
    def ymin(self):
        if self._ylim['auto'].checkState() == Qt.Checked:
            return None
        else:
            return self._ylim['min'].value()

    @property
    def ymax(self):
        if self._ylim['auto'].checkState() == Qt.Checked:
            return None
        else:
            return self._ylim['max'].value()

    @property
    def yscale(self):
        if self._ylim['auto'].checkState() == Qt.Checked:
            return None
        else:
            return self._ylim['scale'].value()

    @property
    def show_ebar(self):
        return self._errorbar.checkState() == Qt.Checked

    @property
    def draw_line(self):
        return self._drawline.checkState() == Qt.Checked

    @property
    def markersize(self):
        return self._markersize['widget'].value()

    # ---- Handlers

    def time_units_changed(self):
        """ Handles when the time_units combobox selection changes."""
        for xlim in [self._xlim['min'], self._xlim['max'],
                     self._xlim['scale']]:
            xlim.blockSignals(True)
            if self._xlim['units'].currentText() == 'Hours':
                xlim.setValue(xlim.value()*24)
            elif self._xlim['units'].currentText() == 'Days':
                xlim.setValue(xlim.value()/24)
            xlim.blockSignals(False)

        self._graphconf_changed()

    def axis_autocheck_changed(self):
        """
        Handles when the Auto checkbox state change for the
        limits of the y-axis or the x-axis.
        """
        self._ylim['min'].setEnabled(not self._ylim['auto'].isChecked())
        self._ylim['max'].setEnabled(not self._ylim['auto'].isChecked())
        self._ylim['scale'].setEnabled(not self._ylim['auto'].isChecked())

        self._xlim['units'].setEnabled(not self._xlim['auto'].isChecked())
        self._xlim['min'].setEnabled(not self._xlim['auto'].isChecked())
        self._xlim['max'].setEnabled(not self._xlim['auto'].isChecked())
        self._xlim['scale'].setEnabled(not self._xlim['auto'].isChecked())

        self._graphconf_changed()