コード例 #1
0
    def __init__(self):
        super().__init__()
        self.setMaximumHeight(70)
        optLayout = QHBoxLayout()

        self.select = QPushButton('Select')
        self.start = QPushButton('Start Bid')
        self.cancel = QPushButton('Reset')
        self.save = QPushButton('Save')

        self.select.setStyleSheet("""
            QPushButton{
                background-color: rgb(70, 72, 74);
                border-radius: 3px;
                font: 14pt;
            }
        """)

        self.start.setStyleSheet("""
            QPushButton {
                background-color: rgb(70, 72, 74);
                border-radius: 3px;
                color: Green;
                font-size: 16pt;
            }
        """)
        self.start.setEnabled(False)

        self.cancel.setStyleSheet("""
            QPushButton {
                background-color: rgb(70, 72, 74);
                border-radius: 3px;
                color: rgb(153, 0, 0);
                font: 16pt;
            }
        """)
        self.cancel.setEnabled(False)

        self.save.setStyleSheet("""
            QPushButton {
                background-color: rgb(70, 72, 74);
                border-radius: 3px;
                color: rgb(0, 0, 153);
                font: 14pt;              
            }
        """)

        optLayout.addWidget(self.select)
        optLayout.addSpacing(300)
        optLayout.addWidget(self.start)
        optLayout.addWidget(self.cancel)
        optLayout.addSpacing(300)
        optLayout.addWidget(self.save)

        optLayout.sizeHint()

        self.setLayout(optLayout)
        self.show()
コード例 #2
0
    def initUI(self):
        # general settings
        self.setWindowTitle('DaisyLiteGUI v1.0')

        # main layout
        mainlayout = QHBoxLayout()

        # get widgets
        self.camerasection = CameraSection(self, self.camera)
        self.manualmovement = ManualMovementSection(self, self.camera, self.DD)

        # add widgets to main layout
        mainlayout.addWidget(self.camerasection)
        mainlayout.addWidget(self.manualmovement)

        # check if DD plugged in, disable manual movement section if so
        # and display warning
        if not self.DDconnected:
            self.manualmovement.setEnabled(False)
            warning_dialog = QMessageBox.warning(
                self, 'DaisyDriver Warning',
                'Warning: No DaisyDriver Detected.', QMessageBox.Ok)

        # set mainlayout as widget layout
        self.setLayout(mainlayout)

        # set window geometry
        self.setFixedSize(mainlayout.sizeHint())
        self.move(0, 0)
コード例 #3
0
def rendersearchlist():
#     mydic_list1 has all the search history. You can iterate with the keywords
#     for i in mydic_list1 
    for i in range(len(mydic_list1)):
        layout = QHBoxLayout()
        layout.setSizeConstraint(QLayout.SetMinimumSize)
        
        item = QListWidgetItem(mpg.listWidget_2)
        # SAAD DB DONE COMMENTED BELOW in main  
        label = QLabel(str(i+1)+ ") " + mydic_list1[i] )
        label.setStyleSheet("height:fit-content;font-size:12pt;font-family: Segoe UI;font-style: normal;font-weight:100")
        label.setWordWrap(True);
        
        
        

        layout.addWidget(label)
        
        widget = QWidget()
        widget.setStyleSheet("height:fit-content;width:100%");
        widget.setLayout(layout);
        
        item.setSizeHint(layout.sizeHint())
        
        mpg.listWidget_2.addItem(item)
        mpg.listWidget_2.setItemWidget(item,widget)
コード例 #4
0
 def addPattern(self, str=""):
     w = QWidget()
     l = QHBoxLayout()
     l.addWidget(QLabel("▹"))
     edit = QLineEdit(str)
     edit.textEdited.connect(lambda: Entries.setCurrentUnsaved())
     l.addWidget(edit)
     l.addStretch()
     w.setLayout(l)
     item = QListWidgetItem()
     item.setSizeHint(l.sizeHint())
     self.keywordList.addItem(item)
     self.keywordList.setItemWidget(item, w)
コード例 #5
0
	def __init__(self, parent=None):
		super(CoordApp, self).__init__(parent)

		self.setWindowTitle('Mouse coordinates')

		container = QWidget()
		layout = QHBoxLayout()
		container.setLayout(layout)
		self.setCentralWidget(container)

		self.label = CoordWidget()
		self.label.selectionChanged.connect(self._showSelectionInfo)
		layout.addWidget(self.label)

		help = QPushButton('&?')
		help.clicked.connect(self.showHelp)
		layout.addWidget(help)

		self.follower = MouseFollower()
		self.follower.mouseMoved.connect(self.label.showCoords)
		# disable grabbing here to avoid confusion
		self.follower.clickWhileGrabbed.connect(self.follower.toggleGrab)
		self.follower.clickWhileGrabbed.connect(self._showGrabInfo)
		layout.addWidget(self.follower)

		self.statusBar() # creates it

		self.resize(layout.sizeHint())

		## shortcuts
		self.copyAction = QAction(self)
		self.copyAction.setShortcut(QKeySequence(QKeySequence.Copy))
		self.copyAction.triggered.connect(self.copyToClibpoard)
		self.addAction(self.copyAction)

		self.toggleGrabAction = QAction(self)
		self.toggleGrabAction.setShortcut(QKeySequence(Qt.Key_G))
		self.toggleGrabAction.triggered.connect(self.follower.toggleGrab)
		self.toggleGrabAction.triggered.connect(self._showGrabInfo)
		self.addAction(self.toggleGrabAction)

		self.toggleFollowAction = QAction(self)
		self.toggleFollowAction.setShortcut(QKeySequence(Qt.Key_Space))
		self.toggleFollowAction.triggered.connect(self.follower.toggleFollow)
		self.addAction(self.toggleFollowAction)

		self.toggleAlwaysOnTopAction = QAction(self)
		self.toggleAlwaysOnTopAction.setShortcut(QKeySequence(Qt.Key_A))
		self.toggleAlwaysOnTopAction.triggered.connect(self.toggleAlwaysOnTop)
		self.addAction(self.toggleAlwaysOnTopAction)
コード例 #6
0
ファイル: coordapp.py プロジェクト: thet0mmy/attic
    def __init__(self, parent=None):
        super(CoordApp, self).__init__(parent)

        self.setWindowTitle('Mouse coordinates')

        container = QWidget()
        layout = QHBoxLayout()
        container.setLayout(layout)
        self.setCentralWidget(container)

        self.label = CoordWidget()
        self.label.selectionChanged.connect(self._showSelectionInfo)
        layout.addWidget(self.label)

        help = QPushButton('&?')
        help.clicked.connect(self.showHelp)
        layout.addWidget(help)

        self.follower = MouseFollower()
        self.follower.mouseMoved.connect(self.label.showCoords)
        # disable grabbing here to avoid confusion
        self.follower.clickWhileGrabbed.connect(self.follower.toggleGrab)
        self.follower.clickWhileGrabbed.connect(self._showGrabInfo)
        layout.addWidget(self.follower)

        self.statusBar()  # creates it

        self.resize(layout.sizeHint())

        ## shortcuts
        self.copyAction = QAction(self)
        self.copyAction.setShortcut(QKeySequence(QKeySequence.Copy))
        self.copyAction.triggered.connect(self.copyToClibpoard)
        self.addAction(self.copyAction)

        self.toggleGrabAction = QAction(self)
        self.toggleGrabAction.setShortcut(QKeySequence(Qt.Key_G))
        self.toggleGrabAction.triggered.connect(self.follower.toggleGrab)
        self.toggleGrabAction.triggered.connect(self._showGrabInfo)
        self.addAction(self.toggleGrabAction)

        self.toggleFollowAction = QAction(self)
        self.toggleFollowAction.setShortcut(QKeySequence(Qt.Key_Space))
        self.toggleFollowAction.triggered.connect(self.follower.toggleFollow)
        self.addAction(self.toggleFollowAction)

        self.toggleAlwaysOnTopAction = QAction(self)
        self.toggleAlwaysOnTopAction.setShortcut(QKeySequence(Qt.Key_A))
        self.toggleAlwaysOnTopAction.triggered.connect(self.toggleAlwaysOnTop)
        self.addAction(self.toggleAlwaysOnTopAction)
コード例 #7
0
def renderselllist():

    for i in mydic_list:
        if (i["uploaded_by"] == cu and i["status"] == "For Sale"):
            #             EVERYTHING HERE with i
            #             pass
            #         pass

            #    for i in range(len(mydic_list)):
            layout = QHBoxLayout()
            layout.setSizeConstraint(QLayout.SetMinimumSize)
            print(i["short_description"])
            print(i)

            item = QListWidgetItem(mpg.listWidget_3)
            # SAAD DB DONE COMMENTED
            label = QLabel(
                str(i + 1) + ") Title: " + i['short_description'] + "\n" +
                "Uploaded By: " + str(i['uploaded_by']) + "\n" + "Rating: " +
                str(i['rating']) + "/5")

            # label = QLabel(str(i+1)+ ") Title:" + i['short_description'] + "\n" + "     Request By: " + i['requested_by'] +"\n" +"     Rating: " + str(i['rating']) + "/5")
            label.setStyleSheet(
                "height:fit-content;font-size:12pt;font-family: Segoe UI;font-style: normal;font-weight:100"
            )
            label.setWordWrap(True)

            # label2 = QLabel("No of comments " + str(len(i['comments'])) + '\nStatus: ' + i['status'])

            label2 = QLabel("Data Size: " + i['data_size'] + '\nStatus: ' +
                            i['status'])
            label2.setStyleSheet(
                "height:fit-content;font-size:12pt;font-family: Segoe UI;text-align:right"
            )
            label2.setAlignment(QtCore.Qt.AlignCenter)
            label2.setWordWrap(True)

            layout.addWidget(label)
            layout.addWidget(label2)

            widget = QWidget()
            widget.setStyleSheet("height:fit-content;width:100%")
            widget.setLayout(layout)

            item.setSizeHint(layout.sizeHint())

            mpg.listWidget_3.addItem(item)
            mpg.listWidget_3.setItemWidget(item, widget)
コード例 #8
0
    def __init__(self, parent=None):
        super(Winform, self).__init__(parent)
        self.setWindowTitle("水平布局管理例子")

        # 水平布局按照从左到右的顺序进行添加按钮部件。
        hlayout = QHBoxLayout()

        hlayout.addWidget(QPushButton(str(1)))
        hlayout.addWidget(QPushButton(str(2)))
        hlayout.addWidget(QPushButton(str(3)))
        btn4 = QPushButton(str(4))
        hlayout.addWidget(btn4)
        hlayout.addWidget(QPushButton(str(5)))
        # hlayout.setContentsMargins(0,0,0,0)

        #设置控件间的间距
        hlayout.setSpacing(0)
        self.setLayout(hlayout)
        print("btn4:", hlayout.sizeHint())
コード例 #9
0
    def renderListItem(self, i):
        layout = QHBoxLayout()
        layout.setSizeConstraint(QLayout.SetMinimumSize)

        item = QListWidgetItem(self.ItemListView)
        label = QLabel(
            str(i + 1) + ") " + item_list[i]['short_description'] + "\n" +
            "Uploaded By: " + str(item_list[i]['uploaded_by']) + "\n" +
            "Rating: " + str(item_list[i]['rating']) + "/5")
        label.setStyleSheet(
            "height:fit-content;font-size:12pt;font-style: normal;font-weight:100;"
        )
        #  label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)
        label.setWordWrap(True)

        label2 = QLabel("Data Size: " + item_list[i]['data_size'] +
                        '\nStatus: ' + item_list[i]['status'])
        label2.setStyleSheet(
            "height:fit-content;font-size:12pt;text-align:right;")
        #             label2.setStyleSheet("color: white; background: red;,text-align:right;");
        label2.setAlignment(QtCore.Qt.AlignCenter)
        #             label2.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Ignored)
        #  label2.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)

        label2.setWordWrap(True)

        layout.addWidget(label)
        layout.addWidget(label2)

        widget = QWidget()
        widget.setStyleSheet("height:fit-content;,width:100%")
        widget.setLayout(layout)

        item.setSizeHint(layout.sizeHint())

        self.ItemListView.addItem(item)
        self.ItemListView.setItemWidget(item, widget)
コード例 #10
0
ファイル: pager.py プロジェクト: Max-Mobility/sd-programmer
class Pager(QWidget):
    finished = pyqtSignal()
    changed = pyqtSignal(int)

    def __init__(self, parent=None):
        QWidget.__init__(self, parent=parent)

        lay = QVBoxLayout(self)

        self.stack = QStackedWidget()
        self.stack.currentChanged.connect(self.onChanged)

        self.nextButton = QPushButton("Next")
        self.nextButton.clicked.connect(self.onNext)
        self.finishButton = QPushButton("Finish")
        self.finishButton.clicked.connect(self.onFinish)
        self.previousButton = QPushButton("Previous")
        self.previousButton.clicked.connect(self.onPrevious)
        self.disableControls()
        self.btnLayout = QHBoxLayout()
        self.btnLayout.addWidget(self.previousButton)
        self.btnLayout.addWidget(self.nextButton)
        self.btnLayout.addWidget(self.finishButton)

        lay.addWidget(self.stack)
        lay.addLayout(self.btnLayout)

    # events
    @pyqtSlot()
    def onNext(self):
        index = self.stack.currentIndex()
        top = self.stack.count() - 1
        index += 1
        if index >= top:
            index = top
        self.stack.setCurrentIndex(index)

    @pyqtSlot()
    def onPrevious(self):
        index = self.stack.currentIndex()
        bottom = 0
        index -= 1
        if index <= bottom:
            index = bottom
        self.stack.setCurrentIndex(index)

    @pyqtSlot()
    def onFinish(self):
        self.disableFinish()
        self.disablePrevious()
        self.enableNext()
        self.finished.emit()
        self.stack.setCurrentIndex(0)

    @pyqtSlot(int)
    def onChanged(self, index):
        self.disableControls()
        self.changed.emit(index)
        widget = self.stack.widget(index)
        widget.onEnter()
        if widget.nextEnabled:
            self.enableNext()
        if widget.previousEnabled:
            self.enablePrevious()

    @pyqtSlot()
    def onPageFinished(self):
        self.disableControls()

        index = self.stack.currentIndex()
        top = self.stack.count() - 1
        bottom = 0

        self.enableNext()
        if index >= top:
            self.disableNext()
            self.enableFinish()

        self.enablePrevious()
        if index <= bottom:
            self.disablePrevious()

    # previous/next/finish controls
    def enableNext(self):
        self.nextButton.show()

    def enableFinish(self):
        self.finishButton.show()

    def enablePrevious(self):
        self.previousButton.show()

    def enableControls(self):
        self.enableNext()
        self.enableFinish()
        self.enablePrevious()

    def disableNext(self):
        self.nextButton.hide()

    def disableFinish(self):
        self.finishButton.hide()

    def disablePrevious(self):
        self.previousButton.hide()

    def disableControls(self):
        self.disableNext()
        self.disableFinish()
        self.disablePrevious()

    # for adding widgets and controlling page
    def addPage(self, pageWidget):
        pageWidget.setPager(self)
        self.stack.addWidget(pageWidget)
        pageWidget.finished.connect(self.onPageFinished)

    def getButtonHeight(self):
        return self.btnLayout.sizeHint().height()

    def clearPages(self):
        self.stack.clear()

    def setPageIndex(self, index):
        self.stack.setCurrentIndex(index)
コード例 #11
0
class Calendar(QWidget):
    def __init__(self,
                 parent=None,
                 year=int(time.strftime('%Y', time.localtime(time.time()))),
                 month=int(time.strftime('%m', time.localtime(time.time())))):
        super().__init__(parent)

        # Set Schedule Layout Components ===============
        self.scheduleLayout = QVBoxLayout()
        # -------------------------------
        self.titleBox = QHBoxLayout()
        self.titleLabel = QLabel("title: ")
        self.titleLineEdit = QLineEdit()
        # -------------------------------
        self.placeBox = QHBoxLayout()
        self.placeLabel = QLabel("place: ")
        self.placeLineEdit = QLineEdit()
        # -------------------------------
        self.dateBox = QHBoxLayout()
        self.dateLabel = QLabel("time:")
        self.fromHour = QSpinBox()
        self.fromMin = QSpinBox()
        self.toHour = QSpinBox()
        self.toMin = QSpinBox()
        # -------------------------------
        self.discription = QHBoxLayout()
        self.contentLabel = QLabel("content: ")
        self.content = QTextEdit()
        # -------------------------------
        self.modifyBtn = Button("Modifying", self.modifying)
        # ==============================================

        self.displayCalendar = MyCalendar()
        self.startDay = 0
        self.maxDay = 0
        self.currentYear = year
        self.currentMonth = month
        self.currentDay = 0
        self.firstClick = True
        self.displayCalendar.loadHoliday()
        self.today = time.localtime()

        if os.name == 'nt':
            self.fileRoot = ".\schedules\schedules.txt"

        else:
            self.fileRoot = "./schedules/schedules.txt"

        try:
            scheduleFile = open(self.fileRoot, "rb")
            self.displayCalendar.schedule = pickle.load(scheduleFile)
            print(self.displayCalendar.schedule)

        except EOFError:
            pass

        # main layout
        self.mainLayout = QHBoxLayout()

        # Left side Layout ================================
        self.leftLayout = QVBoxLayout()

        # Stacked Widget Part -----------------------------
        # Setting Stacked Widget(like a switching Tabs)
        self.setSchedule = QWidget()
        self.lunaDate = QWidget()

        # Design And Setting Actions each Tab. if want to Append any action, plz input the action in here.
        self.setScheduleUI()
        self.lunaDateUI()

        # Appending tabs in Stack
        self.Stack = QStackedWidget()
        self.Stack.addWidget(self.setSchedule)
        self.Stack.addWidget(self.lunaDate)

        # Switching Button layout Design And binding button with action.
        self.tabLayout = QHBoxLayout()
        self.tabLayout.addWidget(Button("스케쥴러", lambda: self.display(0)))
        self.tabLayout.addWidget(Button("음력", lambda: self.display(1)))

        for i in range(self.tabLayout.count()):
            self.tabLayout.itemAt(i).widget().setStyleSheet('font-size: 8pt')

        self.leftLayout.addLayout(self.tabLayout)
        # -------------------------------------------------

        # handling Year & month ----------------------------------
        self.moveMonth = QHBoxLayout()

        self.previousBtn = Button("<", self.previousMonth)

        # showing Year and month using Combobox(Year range: 1980 ~ 2040, Month range: 1, 12)
        self.yearCombo = QComboBox()
        self.yearCombo.addItems([str(x) for x in range(1980, 2041)])
        self.yearCombo.setCurrentText(str(self.currentYear))

        self.monthCombo = QComboBox()
        self.monthCombo.addItems([str(x) for x in range(1, 13)])
        self.monthCombo.setCurrentText(str(self.currentMonth))

        self.nextBtn = Button(">", self.nextMonth)

        self.moveMonth.addStretch()
        self.moveMonth.addWidget(self.previousBtn)
        self.moveMonth.addWidget(self.yearCombo)
        self.moveMonth.addWidget(self.monthCombo)
        self.moveMonth.addWidget(self.nextBtn)
        self.moveMonth.addStretch()
        self.leftLayout.addLayout(self.moveMonth)
        self.leftLayout.addStretch()
        # -------------------------------------------------

        # Set Day of Week ---------------------------------
        self.weekDayLayout = QHBoxLayout()
        enumDays = ["일", "월", "화", "수", "목", "금", "토"]

        for i in enumDays:
            label = QLabel(i)
            label.setAlignment(Qt.AlignCenter)
            self.weekDayLayout.addWidget(label)

        self.leftLayout.addLayout(self.weekDayLayout)
        # -------------------------------------------------

        # grid layout to appending date Buttons
        self.calendarGrid = QGridLayout()
        self.calendarGrid.setSizeConstraint(QLayout.SetFixedSize)
        self.leftLayout.addLayout(self.calendarGrid)
        self.leftLayout.addStretch(7)

        # showing status
        self.statusLabel = QLabel("btn Status")
        self.leftLayout.addWidget(self.statusLabel)
        # ==================================================

        # Set grid
        self.displayCalendar.setCalander(self.currentYear, self.currentMonth)
        self.renderDate(self.displayCalendar.getCalander())

        # Set ComboBox Changing Event
        self.yearCombo.currentTextChanged.connect(
            lambda: self.selectionChanged())
        self.monthCombo.currentTextChanged.connect(
            lambda: self.selectionChanged())

        self.mainLayout.addLayout(self.leftLayout)
        self.mainLayout.addWidget(self.Stack)
        self.Stack.setCurrentIndex(0)  # default Tab -> set calendar
        self.setLayout(self.mainLayout)
        self.setWindowTitle("Calendar")

    def renderDate(self, newCalendar):
        # =========== Append Day Buttons ===============
        self.clearLayout(self.calendarGrid)
        todayYear = self.today.tm_year
        todayMonth = self.today.tm_mon
        todayDay = self.today.tm_mday
        toggle = True

        for i in newCalendar:
            print(i)

        # Enroll button
        for row, column in enumerate(newCalendar):
            for col, day in enumerate(column):
                btn = Button(str(day), self.btnEvent)

                # deactivate button condition
                if toggle:
                    if day != 1:
                        btn.setEnabled(False)

                    else:
                        toggle = False

                else:
                    if (row == len(newCalendar) - 1) and (day // 10 == 0):
                        btn.setEnabled(False)

                # set today button color
                if (self.currentYear, self.currentMonth,
                        day) == (todayYear, todayMonth, todayDay):
                    btn.setStyleSheet('font-style: italic;')

                # if this day have any event represent event
                key = '-'.join(
                    [str(self.currentYear),
                     str(self.currentMonth),
                     str(day)])
                if key in self.displayCalendar.schedule.keys(
                ) and btn.isEnabled():
                    btn.setStyleSheet('color: blue;')
                    btn.setStyleSheet('background-color: skyblue;')
                    btn.setToolTip(
                        self.displayCalendar.schedule[key].getTitle())

                for restMonth, restDay, title in self.displayCalendar.holidays:
                    if restMonth == self.currentMonth and restDay == day and btn.isEnabled(
                    ):
                        if key in self.displayCalendar.schedule.keys(
                        ) and btn.isEnabled():
                            btn.setStyleSheet(
                                'background-color: skyblue; color: red;')
                            btn.setToolTip(title)

                        else:
                            btn.setStyleSheet('color: red;')
                            btn.setToolTip(title)
                            break

                # 공휴일은 빨간색으로 설정해준다.
                if col == 0 and btn.isEnabled():
                    btn.setStyleSheet('color: red;')

                self.calendarGrid.addWidget(btn, row, col)
        # ===============================================
        self.displayCalendar.enrollHoliday(self.currentYear)
        self.displayCalendar.loadHoliday()

    def btnEvent(self):
        # self.showingWidget(self.scheduleLayout)

        self.setFixedSize(self.mainLayout.sizeHint())

        btn = self.sender()
        self.statusLabel.setText("Day: " + btn.text() + " is Clicked.")
        self.currentDay = btn.text()

        target = "-".join([
            str(self.currentYear),
            str(self.currentMonth),
            str(self.currentDay)
        ])
        targetEvent = self.displayCalendar.schedule.get(target)

        if not targetEvent:
            self.titleLineEdit.setText("None")
            self.placeLineEdit.clear()
            self.fromHour.setValue(0)
            self.fromMin.setValue(0)
            self.toHour.setValue(0)
            self.toMin.setValue(0)
            self.content.clear()

        else:
            self.titleLineEdit.setText(targetEvent.getTitle())
            self.placeLineEdit.setText(targetEvent.getPlace())

            timeSet = targetEvent.getDate().split(",")
            self.fromHour.setValue(int(timeSet[0]))
            self.fromMin.setValue(int(timeSet[1]))
            self.toHour.setValue(int(timeSet[2]))
            self.toMin.setValue(int(timeSet[3]))

            self.content.setText(targetEvent.getDescription())

    def modifying(self):
        newEvent = MyEvent()
        eventList = [
            self.titleLineEdit.text(),
            self.placeLineEdit.text(),
            ",".join([
                str(self.fromHour.value()),
                str(self.fromMin.value()),
                str(self.toHour.value()),
                str(self.toMin.value())
            ]),
            self.content.toPlainText(),
        ]

        newEvent.setEvent(*eventList)

        target = "-".join([
            str(self.currentYear),
            str(self.currentMonth),
            str(self.currentDay)
        ])
        self.displayCalendar.schedule[target] = newEvent
        self.statusLabel.setText("modified")

    # rendering previous month calendar
    def previousMonth(self):
        if self.currentMonth is 1:
            self.currentYear -= 1
            self.yearCombo.setCurrentText(str(self.currentYear))
            self.currentMonth = 12
            self.monthCombo.setCurrentText(str(self.currentMonth))

        else:
            self.currentMonth -= 1
            self.monthCombo.setCurrentText(str(self.currentMonth))

    # rendering next month calendar
    def nextMonth(self):
        if self.currentMonth is 12:
            self.currentYear += 1
            self.yearCombo.setCurrentText(str(self.currentYear))
            self.currentMonth = 1
            self.monthCombo.setCurrentText(str(self.currentMonth))
        else:
            self.currentMonth += 1
            self.monthCombo.setCurrentText(str(self.currentMonth))

    def selectionChanged(self):
        self.currentYear = int(self.yearCombo.currentText())
        self.currentMonth = int(self.monthCombo.currentText())

        self.displayCalendar.setYear(self.currentYear)
        self.displayCalendar.setMonth(self.currentMonth)
        self.displayCalendar.setCalander(self.currentYear, self.currentMonth)
        self.renderDate(self.displayCalendar.getCalander())

    def clearLayout(self, layout):
        while layout.count():
            child = layout.takeAt(0)
            if child.widget():
                child.widget().deleteLater()

    def closeEvent(self, event):
        keys = []
        myEvent = self.displayCalendar.schedule

        for target in myEvent.keys():
            title = myEvent[target].title
            place = myEvent[target].place

            description = myEvent[target].description

            if (title, place, description) == ('', '', ''):
                keys.append(target)

        for target in keys:
            del self.displayCalendar.schedule[target]

        with open(self.fileRoot, "wb") as file:
            pickle.dump(self.displayCalendar.schedule, file)

    def setScheduleUI(self):
        # Schedules layout ==================================
        self.titleBox.addWidget(self.titleLabel)
        self.titleBox.addWidget(self.titleLineEdit)

        self.placeBox.addWidget(self.placeLabel)
        self.placeBox.addWidget(self.placeLineEdit)

        self.fromHour.setRange(0, 24)
        self.toHour.setRange(0, 24)
        self.fromMin.setRange(0, 59)
        self.toMin.setRange(0, 59)

        self.fromHour.valueChanged.connect(
            lambda: self.toHour.setRange(self.fromHour.value(), 24))
        # self.toHour.valueChanged.connect(lambda: self.fromHour.setRange(0, self.toHour.value()))

        self.fromMin.valueChanged.connect(
            lambda: self.toMin.setRange(self.fromMin.value(), 59))
        # self.toMin.valueChanged.connect(lambda: self.fromMin.setRange(0, self.toMin.value()))

        self.dateBox.addWidget(self.dateLabel)
        self.dateBox.addWidget(self.fromHour)
        self.dateBox.addWidget(self.fromMin)
        self.dateBox.addWidget(QLabel("    ~ "))
        self.dateBox.addWidget(self.toHour)
        self.dateBox.addWidget(self.toMin)

        self.contentLabel.setAlignment(Qt.AlignTop)
        self.discription.addWidget(self.contentLabel)
        self.discription.addWidget(self.content)

        self.scheduleLayout.addLayout(self.titleBox)
        self.scheduleLayout.addLayout(self.placeBox)
        self.scheduleLayout.addLayout(self.dateBox)
        self.scheduleLayout.addLayout(self.discription)
        # modifying schedule Button
        self.scheduleLayout.addWidget(self.modifyBtn)
        self.setSchedule.setLayout(self.scheduleLayout)

    def lunaDateUI(self):
        month_31 = [1, 3, 5, 7, 8, 10, 12]

        layout = QVBoxLayout()
        #layout.addWidget(QLabel("Luna Date"))
        topLayout = QHBoxLayout()
        self.yearSpinner = QSpinBox()
        self.yearSpinner.setRange(1980, 2040)
        self.monthSpinner = QSpinBox()
        self.monthSpinner.setRange(1, 12)
        self.daySpinner = QSpinBox()

        self.yearSpinner.setValue(self.today.tm_year)
        self.monthSpinner.setValue(self.today.tm_mon)
        self.daySpinner.setValue(self.today.tm_mday)

        self.monthSpinner.valueChanged.connect(
            lambda: self.daySpinner.setRange(
                1,
                self.displayCalendar.getMaxday(self.yearSpinner.value(),
                                               self.monthSpinner.value())))

        self.modeComboBox = QComboBox()
        self.modeComboBox.addItems(["양력 -> 음력", "음력 -> 양력"])
        convertBtn = Button("convert", self.lunarBtnEvent)
        resetBtn = Button("reset", self.lunarBtnEvent)

        bottomLayout = QVBoxLayout()
        titleBox = QHBoxLayout()
        solarBox = QHBoxLayout()
        lunarBox = QHBoxLayout()
        self.todayLabel = QLabel("오늘의 날짜정보")
        self.todayLabel.setStyleSheet('color: red; font-size: 18px;')
        solarLabel = QLabel("양력날짜")
        solarLabel.setStyleSheet('color: gray;')
        todaySolarDay = "%04d-%02d-%02d" % (
            self.today.tm_year, self.today.tm_mon, self.today.tm_mday)
        self.solarDateLabel = QLabel(todaySolarDay)
        lunarLabel = QLabel("음력날짜")
        lunarLabel.setStyleSheet('color: gray;')
        self.lunarDateLabel = QLabel(
            self.displayCalendar.calculator.getToLunarDate(
                self.today.tm_year, self.today.tm_mon, self.today.tm_mday))

        titleBox.addWidget(self.todayLabel)
        solarBox.addWidget(solarLabel)
        solarBox.addWidget(self.solarDateLabel)
        lunarBox.addWidget(lunarLabel)
        lunarBox.addWidget(self.lunarDateLabel)
        bottomLayout.addLayout(titleBox)
        bottomLayout.addLayout(solarBox)
        bottomLayout.addLayout(lunarBox)

        topLayout.addWidget(self.yearSpinner)
        topLayout.addWidget(self.monthSpinner)
        topLayout.addWidget(self.daySpinner)
        topLayout.addWidget(self.modeComboBox)
        topLayout.addWidget(convertBtn)
        topLayout.addWidget(resetBtn)

        layout.addStretch()
        layout.addLayout(bottomLayout)
        layout.addLayout(topLayout)
        layout.addStretch()
        self.lunaDate.setLayout(layout)

    def display(self, i):
        self.Stack.setCurrentIndex(i)

    def hidingWidget(self, layout):
        for i in range(layout.count()):
            item = layout.itemAt(i)

            if item.widget() is not None:
                layout.itemAt(i).widget().hide()

            elif item.layout() is not None:
                self.hidingWidget(layout.itemAt(i).layout())

    def showingWidget(self, layout):
        for i in range(layout.count()):
            item = layout.itemAt(i)
            if item.widget() is not None:
                layout.itemAt(i).widget().show()
            elif item.layout() is not None:
                self.showingWidget(layout.itemAt(i).layout())

    def lunarBtnEvent(self):
        btn = self.sender()
        key = btn.text()

        if key == 'reset':
            self.todayLabel.setText('오늘의 날짜정보')
            self.todayLabel.setStyleSheet('color: red; font-size: 18px;')

        elif key == 'convert':
            if self.modeComboBox.currentIndex() is 0:
                self.todayLabel.setText("양력 {}년 {}월 {}일".format(
                    self.yearSpinner.value(), self.monthSpinner.value(),
                    self.daySpinner.value()))
                self.todayLabel.setStyleSheet(
                    'font-weight: bold; color: black; font-size: 12px;')
                lunarDate = self.displayCalendar.calculator.getToLunarDate(
                    self.yearSpinner.value(), self.monthSpinner.value(),
                    self.daySpinner.value())
                self.solarDateLabel.setText(
                    str(self.yearSpinner.value()) + "-" +
                    str(self.monthSpinner.value()) + "-" +
                    str(self.daySpinner.value()))
                self.lunarDateLabel.setText(lunarDate)
            else:
                self.todayLabel.setText("음력 {}년 {}월 {}일".format(
                    self.yearSpinner.value(), self.monthSpinner.value(),
                    self.daySpinner.value()))
                self.todayLabel.setStyleSheet(
                    'font-weight: bold; color: black; font-size: 12px;')
                solarDate = self.displayCalendar.calculator.toSolarDate(
                    self.yearSpinner.value(), self.monthSpinner.value(),
                    self.daySpinner.value())
                self.solarDateLabel.setText(
                    str(solarDate[0]) + "-" + str(solarDate[1]) + "-" +
                    str(solarDate[2]))
                self.lunarDateLabel.setText(
                    str(self.yearSpinner.value()) + "-" +
                    str(self.monthSpinner.value()) + "-" +
                    str(self.daySpinner.value()))
コード例 #12
0
class Appication(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle(APP_TITLE)
        self.initUI()

    def initUI(self):
        self.init_menu()

        self.upload_file_label = QLabel('Upload data file:')
        self.upload_file_label.setSizePolicy(QSizePolicy.Minimum,
                                             QSizePolicy.Minimum)
        self.upload_file_label.setAlignment(Qt.AlignTop)
        self.upload_file_label.setContentsMargins(0, 7, 0, 0)

        self.choose_data_button = QPushButton('Choose file')
        self.choose_data_button.setSizePolicy(QSizePolicy.Minimum,
                                              QSizePolicy.Minimum)
        self.choose_data_button.clicked.connect(self.show_files_dialog)

        self.data_fname_label = QLabel('No file chosen')
        self.data_fname_label.setSizePolicy(QSizePolicy.MinimumExpanding,
                                            QSizePolicy.Minimum)
        self.data_fname_label.setAlignment(Qt.AlignTop)
        self.data_fname_label.setContentsMargins(0, 7, 0, 0)

        self.classify_button = QPushButton('Classify')
        self.classify_button.setSizePolicy(QSizePolicy.Minimum,
                                           QSizePolicy.Fixed)
        self.classify_button.setEnabled(False)
        self.classify_button.clicked.connect(self.plot_results)

        self.buttons_vlayout = QVBoxLayout()
        self.buttons_vlayout.addWidget(self.choose_data_button)
        self.buttons_vlayout.addWidget(self.classify_button)

        self.pred_hlayout = QHBoxLayout()
        self.pred_hlayout.setAlignment(Qt.AlignTop)
        self.pred_hlayout.addWidget(self.upload_file_label)
        self.pred_hlayout.addLayout(self.buttons_vlayout)
        self.pred_hlayout.addWidget(self.data_fname_label)

        self.canvas = PlotCanvas()
        self.nav_toolbar = NavigationToolbar(self.canvas, self)
        self.addToolBar(QtCore.Qt.BottomToolBarArea, self.nav_toolbar)

        self.scroll_area = QScrollArea()
        self.scroll_area.setAlignment(Qt.AlignTop)
        self.scroll_area.setSizePolicy(QSizePolicy.MinimumExpanding,
                                       QSizePolicy.Maximum)
        self.scroll_area.setFixedHeight(
            int(FIG_H * DPI) +
            self.scroll_area.horizontalScrollBar().sizeHint().height() + 2)
        self.scroll_area.setWidget(self.canvas)

        self.stat_results_group = QGroupBox('Classification results')
        self.init_stat_results()
        self.stat_results_group.setLayout(self.stat_results_layout)

        self.main_layout = QVBoxLayout()
        self.main_layout.setAlignment(Qt.AlignTop)
        self.main_layout.addLayout(self.pred_hlayout)
        self.main_layout.addWidget(self.scroll_area)
        self.main_layout.addWidget(self.stat_results_group)

        self.central_widget = QWidget()
        self.central_widget.setLayout(self.main_layout)
        self.setCentralWidget(self.central_widget)

        self.statusBar()
        self.showMaximized()

    def init_stat_results(self):
        self.stat_results_layout = QGridLayout()
        self.stat_results_layout.setAlignment(Qt.AlignLeft | Qt.AlignTop)

        self.stat_results_labels = {
            'nor': QLabel('NOR - normal beats:'),
            'pab': QLabel('PAB - paced beats:'),
            'vfw': QLabel('VFW - ventricular flutter wave beats:'),
            'veb': QLabel('VEB - ventricular escape beats:'),
            'rbb': QLabel('RBB - right bundle branch block beats:'),
            'lbb': QLabel('LBB - left bundle branch block beats:'),
            'pvc': QLabel('PVC - premature ventricular contraction beats:'),
            'apc': QLabel('APC - atrial premature contraction beats:')
        }
        self.stat_results_counts = dict(
            zip(self.stat_results_labels.keys(), [
                QLabel('-')
                for i in range(len(self.stat_results_labels.keys()))
            ]))

        ind = 0
        for c, label in self.stat_results_labels.items():
            self.stat_results_labels[c].setSizePolicy(QSizePolicy.Fixed,
                                                      QSizePolicy.Fixed)
            self.stat_results_layout.addWidget(label, ind % 4, ind // 4 * 2,
                                               Qt.AlignRight)

            self.stat_results_counts[c].setContentsMargins(0, 0, 120, 0)
            self.stat_results_layout.addWidget(self.stat_results_counts[c],
                                               ind % 4, (ind // 4 * 2) + 1)
            ind += 1

    def resume_stat_results(self):
        ind = 0
        for c, _ in self.stat_results_labels.items():
            self.stat_results_counts[c].setText('-')
            ind += 1

    def set_stat_results(self, pred_classes):
        classes, counts = np.unique(pred_classes, return_counts=True)
        for i, c in enumerate(classes):
            self.stat_results_counts[c].setText(str(counts[i]))

    def init_menu(self):
        self.conf_action = QAction('&Configure', self)
        self.conf_action.triggered.connect(self.show_configure)

        self.main_menu = self.menuBar()
        self.settings_menu = self.main_menu.addMenu('&Settings')
        self.settings_menu.addAction(self.conf_action)

    def show_files_dialog(self):
        self.data_fname = QFileDialog.getOpenFileName(
            self,
            'Choose data file',
            filter="ECG format files "
            "(*.txt *.ecg *.cmp *.ano *.edf *.hea *.atr *.dat)")[0]
        if self.data_fname != '':
            self.data_fname_label.setText(
                self.data_fname[self.data_fname.rfind('/') + 1:])

        self.classify_button.setEnabled(self.data_fname != '')

    def define_analysis(self):
        global analysis_obj

        if analysis_obj is None:
            analysis_obj = analysis.CNNAnalysis(self.statusBar())
            self.statusBar().showMessage('Model loaded, ready to classify')

    def plot_results(self):
        self.classify_button.setEnabled(False)
        self.resume_stat_results()

        self.statusBar().showMessage('Predicting...')
        analysis_res = analysis_obj.analyze(self.data_fname)
        if analysis_res is None:
            self.statusBar().showMessage('Error occured, ready to classify')
            return
        pred_classes, signals, fields, qrs_inds = analysis_res

        self.canvas = PlotCanvas(width=len(signals) // 120,
                                 height=FIG_H * signals.shape[1])
        self.canvas.plot_analysis_res(signals, fields, pred_classes, qrs_inds)

        self.removeToolBar(self.nav_toolbar)
        self.nav_toolbar = NavigationToolbar(self.canvas, self)
        self.addToolBar(QtCore.Qt.BottomToolBarArea, self.nav_toolbar)

        self.scroll_area.setWidget(self.canvas)
        self.scroll_area.setFixedHeight(min(
            self.height() - self.statusBar().height() - \
            self.nav_toolbar.sizeHint().height() - self.stat_results_layout.sizeHint().height() - \
            self.pred_hlayout.sizeHint().height() - self.menuBar().height() - \
            QApplication.style().pixelMetric(QStyle.PM_TitleBarHeight) - 25,
            int(FIG_H * DPI * signals.shape[1]) + self.scroll_area.horizontalScrollBar().sizeHint().height() + 2))

        self.set_stat_results(pred_classes)
        self.statusBar().showMessage('Predicting completed, ready to classify')

    def show_stat_results(self):
        pass

    @staticmethod
    def show_configure():
        ConfDialog()
コード例 #13
0
ファイル: gui.py プロジェクト: ChristopherLBruce/PyLEDStrip
class ledStrip(QWidget):
    """
	[description]

	**Arguments:**

		None

	**Keword Arguments:**

		None

	**Author:**

		Chris Bruce, [email protected], 12/3/2018
	"""

    TITLE = "LED Strip Simluation"
    VERSION = 1.0
    SIZE = [300, 400]

    PIXEL_MIN = 8
    PIXEL_MAX = 256
    PIXEL_NUM = 32

    PIXEL_SIZE_MIN = 8
    PIXEL_SIZE_MAX = 64

    STRIP_COLOR = const.grey  # default RGB value for the strip
    PIXEL_COLOR = Color(12, 12, 12)  # default RGB value for LED pixel

    #STYLE_SHEET			= "QWidget{ background-color: rgb{} };".format( str( STRIP_COLOR ) )
    STYLE_SHEET = "QWidget{ background-color:white};"

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

        self.app = app

        self.pixels = []  # array of LED pixels
        self.pixel_size = 32  # size of each LED pixel
        self.pixel_space = 16  # size of space between each LED pixel

        self.paused = False
        self.testing = False

        self._init_gui()

    def _init_gui(self):
        """
		[description]

		**Arguments:**

			None

		**Keword Arguments:**

			None

		**Author:**

			Chris Bruce, [email protected], 12/3/2018
		"""

        self.setWindowTitle('{} - ver. {}'.format(self.TITLE, self.VERSION))
        self.main_layout = QVBoxLayout()
        self.main_layout.setSpacing(self.pixel_space)
        self.setLayout(self.main_layout)

        self.setAutoFillBackground(True)
        self._strip_color()

        # size_policy = QSizePolicy( )
        # size_policy.setHorizontalPolicy( QSizePolicy.Minimum )
        # self.setSizePolicy( size_policy )

        self.main_layout.addWidget(self._create_strip())
        self.main_layout.addWidget(self._create_controls())

        self._update_gui()

    def _create_controls(self):
        """
		[description]

		**Arguments:**

			None

		**Keword Arguments:**

			None

		**Returns:**

			:``[type]``: [description]

		**Author:**

			Chris Bruce, [email protected], 12/3/2018
		"""

        widget = QWidget()  #QGroupBox( 'Settings:' )
        layout = QHBoxLayout()
        widget.setLayout(layout)

        label_num = QLabel('LEDs:')
        spin_num = QSpinBox()
        spin_num.setRange(self.PIXEL_MIN, self.PIXEL_MAX)
        spin_num.setFixedWidth(64)
        spin_num.setValue(self.PIXEL_NUM)
        spin_num.valueChanged.connect(self._on_spin_num_changed)

        label_size = QLabel('Size:')
        spin_size = QSpinBox()
        spin_size.setRange(self.PIXEL_SIZE_MIN, self.PIXEL_SIZE_MAX)
        spin_size.setFixedWidth(64)
        spin_size.setValue(self.pixel_size)
        spin_size.valueChanged.connect(self._on_spin_size_changed)

        label_space = QLabel('Space:')
        spin_space = QSpinBox()
        spin_space.setRange(0, 256)
        spin_space.setFixedWidth(64)
        spin_space.setValue(self.pixel_space)
        spin_space.valueChanged.connect(self._on_spin_space_changed)

        self.tests = QComboBox()
        for test in sorted(tests.keys()):
            self.tests.addItem(test)
        # self.tests.setCurrentText( 'Soft Fade' )

        btn_start = QPushButton('Start')
        btn_start.pressed.connect(self._on_btn_start_pressed)

        btn_pause = QPushButton('Pause')
        btn_pause.pressed.connect(self._on_btn_pause_pressed)

        btn_stop = QPushButton('Stop')
        btn_stop.pressed.connect(self._on_btn_stop_pressed)

        layout.addStretch()
        layout.addWidget(label_num)
        layout.addWidget(spin_num)
        layout.addWidget(label_size)
        layout.addWidget(spin_size)
        layout.addWidget(label_space)
        layout.addWidget(spin_space)
        layout.addWidget(self.tests)
        layout.addWidget(btn_start)
        layout.addWidget(btn_pause)
        layout.addWidget(btn_stop)
        layout.addStretch()

        return widget

    def _create_pixel(self, color):
        """
		[description]

		**Arguments:**

			:``color``: `[type]` [description]

		**Keword Arguments:**

			None

		**Returns:**

			:``[type]``: [description]

		**Author:**

			Chris Bruce, [email protected], 12/3/2018
		"""

        pixel = QFrame()
        pixel.setFixedSize(QSize(self.pixel_size, self.pixel_size))
        pixel.setFrameShape(QFrame.Box)
        pixel.setFrameShadow(QFrame.Raised)
        pixel.setLineWidth(0)
        pixel.setMidLineWidth(self.pixel_size / 8)

        pixel.setStyleSheet("background-color: rgb{}".format(color))

        return pixel

    def _create_strip(self):
        """
		[description]

		**Arguments:**

			None

		**Keword Arguments:**

			None

		**Returns:**

			:``[type]``: [description]

		**Author:**

			Chris Bruce, [email protected], 12/3/2018
		"""

        self.strip_widget = QWidget()
        self.strip_layout = QHBoxLayout()
        self.strip_layout.setSpacing(self.pixel_space)
        self.strip_widget.setLayout(self.strip_layout)

        for i in range(self.PIXEL_NUM):
            pixel = self._create_pixel(self.PIXEL_COLOR)
            self.pixels.append(pixel)
            self.strip_layout.addWidget(pixel)

        return self.strip_widget

    def _strip_color(self, color=STRIP_COLOR):
        """
		Change the color of the strip

		**Arguments:**

			None

		**Keword Arguments:**

			None

		**Returns:**

			:``[type]``: [description]

		**Author:**

			Chris Bruce, [email protected], 12/3/2018
		"""

        p = self.palette()
        p.setColor(self.backgroundRole(), QColor(*color))
        self.setPalette(p)

        return color

    def _update_size(self):
        self.strip_widget.setFixedSize(self.strip_layout.sizeHint())
        self.setFixedSize(self.main_layout.sizeHint())

        self._center()

        return True

    def _center(self):
        qtRectangle = self.frameGeometry()
        centerPoint = QDesktopWidget().availableGeometry().center()
        qtRectangle.moveCenter(centerPoint)
        self.move(qtRectangle.topLeft())

        return qtRectangle.topLeft()

    def _update_gui(self):
        self._update_size()
        self._center()

        return True

    def _on_spin_num_changed(self, value):
        """
		Change the color of the strip

		**Arguments:**

			None

		**Keword Arguments:**

			None

		**Returns:**

			:``[type]``: [description]

		**Author:**

			Chris Bruce, [email protected], 12/3/2018
		"""

        num_pixels = self.numPixels()

        if value > num_pixels:
            for _ in range(value - num_pixels):
                pixel = self._create_pixel(self.PIXEL_COLOR)
                self.pixels.append(pixel)
                self.strip_layout.addWidget(pixel)
        elif value < len(self.pixels):
            for _ in range(num_pixels - value):
                pixel = self.pixels[-1]
                self.strip_layout.removeWidget(pixel)
                self.pixels.pop()
                pixel.deleteLater()

        self._update_gui()

    def _on_spin_size_changed(self, value):
        """
		Change the color of the strip

		**Arguments:**

			None

		**Keword Arguments:**

			None

		**Returns:**

			:``[type]``: [description]

		**Author:**

			Chris Bruce, [email protected], 12/3/2018
		"""

        for pixel in self.pixels:
            self.pixel_size = value
            pixel.setFixedSize(QSize(self.pixel_size, self.pixel_size))
            pixel.setMidLineWidth(self.pixel_size / 8)

        self._update_gui()

    def _on_spin_space_changed(self, value):
        """
		Change the color of the strip

		**Arguments:**

			None

		**Keword Arguments:**

			None

		**Returns:**

			:``[type]``: [description]

		**Author:**

			Chris Bruce, [email protected], 12/3/2018
		"""

        self.pixel_space = value
        self.strip_layout.setSpacing(self.pixel_space)

        self._update_gui()

    def _on_btn_start_pressed(self):
        self.testing = True
        sel_test = self.tests.currentText()
        test_func = tests[sel_test]

        return test_func(self)

    def _on_btn_pause_pressed(self):
        self.paused = not self.paused

        return True

    def _on_btn_stop_pressed(self):
        self.testing = False

        return True

    def numPixels(self):
        """
		[description]

		**Arguments:**

			None

		**Keword Arguments:**

			None

		**Returns:**

			:``[type]``: [description]

		**Author:**

			Chris Bruce, [email protected], 12/3/2018
		"""

        return len(self.pixels)

    def setPixelColor(self, i, color):
        """
		[description]

		**Arguments:**

			:``i``: `[type]` [description]
			:``color``: `[type]` [description]

		**Keword Arguments:**

			None

		**Returns:**

			:``[type]``: [description]

		**Author:**

			Chris Bruce, [email protected], 12/3/2018
		"""

        if color == 0:
            color = self.PIXEL_COLOR

        if i > (self.numPixels() - 1):
            i -= self.numPixels()

        pixel = self.pixels[i]
        pixel.setStyleSheet("background-color: rgb{}".format(color))

        return True

    def show(self):
        """
		Extends QWidget's .show( ) so it can function similuarly as NeoPixel calls

		**Author:**

			Chris Bruce, [email protected], 12/3/2018
		"""

        super(ledStrip, self).show()

        # extended functionality
        self.app.processEvents()

    def closeEvent(self, event):
        print("Closing")
        self._on_btn_stop_pressed()
        self.destroy()
        self.app.exit()
コード例 #14
0
class WrapperWidget(QWidget):
    def __init__(self, plugin):
        super().__init__()

        self.plugin = plugin

        self.setLayout(QHBoxLayout())
        self.layout().setContentsMargins(0, 0, 0, 0)
        self.layout().addStretch()

        self.inner_layout = QVBoxLayout()
        self.inner_layout.setContentsMargins(0, 0, 0, 0)

        self.label_layout = QHBoxLayout()
        self.temperature_min = QLabel("", parent=self)
        self.temperature_max = QLabel("", parent=self)
        self.temperature_max.setAlignment(Qt.AlignRight | Qt.AlignVCenter)

        self.thermal_image = ThermalImage(80, 60, self.plugin, self)
        self.inner_layout.addStretch()
        self.inner_layout.addWidget(self.thermal_image)

        self.label_layout.addWidget(self.temperature_min)
        self.label_layout.addWidget(self.temperature_max)
        self.inner_layout.addLayout(self.label_layout)
        self.thermal_image_bar = ThermalImageBar(80, 20, self.thermal_image,
                                                 self.plugin, self)
        self.inner_layout.addWidget(self.thermal_image_bar)
        self.inner_layout.addStretch()

        self.layout().addLayout(self.inner_layout)

        self.layout().addStretch()

        self.setWindowTitle(
            'Thermal Image - Thermal Imaging Bricklet - Brick Viewer ' +
            BRICKV_VERSION)

        self.height_offset = 20 + self.label_layout.sizeHint().height(
        ) + 2 * self.inner_layout.spacing()

        self.setMinimumSize(
            400, 300 + self.height_offset)  # To keep pixel size at least 5

    def resizeEvent(self, event):
        super().resizeEvent(event)

        pixel_size = min(self.width() // 80,
                         (self.height() - self.height_offset) // 60)

        if pixel_size % 2 == 0:
            pixel_size -= 1

        pixel_size = max(5, pixel_size)
        self.label_layout.sizeHint().height()
        self.thermal_image.scale_factor_changed(pixel_size)

    def closeEvent(self, _event):
        self.plugin.thermal_image_wrapper = None
        self.plugin.button_detach_image.setEnabled(True)

    def minimumSizeHint(self):
        return QSize(500, 500)

    def sizeHint(self):
        return QSize(500, 500)
コード例 #15
0
ファイル: gui_base.py プロジェクト: chafla/dontfeelgoodinc
class GuiWindow(QMainWindow):
    def __init__(self, controller, base_img_fp: str):
        super(GuiWindow, self).__init__()
        # self.app = QApplication([])

        self.img_manager = ImageManager(base_img_fp)

        self._file_path = base_img_fp

        self._anim_thread = None
        self._anim_worker = None
        self.animation_widget = None

        self._current_chunk_size = 0

        self.setWindowTitle("Don't Feel Good Inc.")

        self.controller = controller
        self.create_content()
        self.show()

    def create_content(self):
        self.snap_sound = PyQt5.QtMultimedia.QSound("snap_ex.wav")

        # Build the components first

        # Build a textbox for the filepath.

        self.outer_widget = PyQt5.QtWidgets.QWidget(
            self)  # Dummy outer widget needed so that we can add others to it

        # This is the frame to hold the options.
        self.main_frame = PyQt5.QtWidgets.QGroupBox(
            self.outer_widget
        )  # Specifying parent=self locks it within the current window
        # self.main_frame.setTitle("Parameters")

        # The main layout for the param box and the image
        self.main_layout_wide = QHBoxLayout(self.main_frame)

        self.input_frame = QWidget(self.outer_widget)

        self.main_layout_wide.addWidget(self.input_frame)

        self.input_frame_layout = QVBoxLayout(self.input_frame)

        # Now, adding the parts back in...

        self.textbox = QLabel(self.input_frame)
        self.textbox.setText(self._file_path)

        self.load_file_button = PyQt5.QtWidgets.QPushButton(self.input_frame)
        self.load_file_button.setText("Browse for file")

        self.load_file_button.clicked.connect(self.on_load)

        self.gain_slider_label = PyQt5.QtWidgets.QLabel(self.input_frame)
        self.gain_slider_label.setText("Custom adjustment")

        self.gain_slider = PyQt5.QtWidgets.QSlider(Qt.Horizontal,
                                                   self.input_frame)
        self.gain_slider.valueChanged.connect(self.on_gain_slider_adjust)

        # size slider

        self.chunk_slider_label = PyQt5.QtWidgets.QLabel(self.input_frame)
        self.chunk_slider_label.setText("Chunk size")

        self.chunk_size_slider = PyQt5.QtWidgets.QSlider(
            Qt.Horizontal, self.input_frame)

        # Start this in the middle so we don't get a div/0

        self.chunk_size_slider.setSliderPosition(40)

        self.chunk_size_slider.valueChanged.connect(
            self.on_chunk_slider_adjust)

        # This needs to be controlled with a single button press as it'll involve reloading the object
        self.chunk_size_button = PyQt5.QtWidgets.QPushButton(
            "Apply chunk size", self.input_frame)

        self.chunk_size_button.clicked.connect(self.on_chunk_click)

        # self.go_button = PyQt5.QtWidgets.QPushButton("*snap*", self.input_frame)
        #
        # self.go_button.clicked.connect(self.on_snap)

        self.full_snap_button = PyQt5.QtWidgets.QPushButton(
            "*snap*", self.input_frame)

        self.full_snap_button.clicked.connect(self.display_animation)

        self.reset_button = PyQt5.QtWidgets.QPushButton(
            "Use the time stone (reset)", self.input_frame)

        self.reset_button.clicked.connect(self.on_reset)

        self.input_frame_layout.addWidget(self.textbox)
        self.input_frame_layout.addWidget(self.load_file_button)
        self.input_frame_layout.addWidget(self.chunk_slider_label)
        self.input_frame_layout.addWidget(self.chunk_size_slider)
        self.input_frame_layout.addWidget(self.chunk_size_button)
        self.input_frame_layout.addWidget(self.gain_slider_label)
        self.input_frame_layout.addWidget(self.gain_slider)
        # self.input_frame_layout.addWidget(self.go_button)
        self.input_frame_layout.addWidget(self.full_snap_button)
        self.input_frame_layout.addWidget(self.reset_button)

        # Trying something else out

        self.image_frame = QFrame(self)

        # Creating the second container

        self.image_widget = ImageWidget(self._file_path, self.outer_widget)

        self.main_layout_wide.addWidget(self.image_widget)

        # self.main_layout.addLayout(self.main_frame)

        self.setCentralWidget(self.outer_widget)

        self.setFixedSize(self.main_layout_wide.sizeHint())

        self.on_chunk_click()

        # Make sure we're ready to handle an animation if the need arises
        # AnimationReadyEmitter.trigger.connect(self.display_animation)

        # self.main_frame.show()

    def on_load(self):
        dlg = QFileDialog()
        dlg.setFileMode(QFileDialog.ExistingFile)
        new_path, _ = dlg.getOpenFileName(None, "Open file",
                                          "%userprofile%\\Pictures\\")
        if new_path == ("", ""):
            return
        if not os.path.exists(new_path):
            self.textbox.setStyleSheet("color: rgb(255, 0, 0);")
        else:
            self.textbox.setStyleSheet("color: rgb(0, 0, 0);")

            self._file_path = new_path
            self.textbox.setText(self._file_path)
            self.img_manager = ImageManager(new_path)
            q_pixmap = PyQt5.QtGui.QPixmap(self._file_path)

            self.image_widget.setPixmap(q_pixmap)
            self.image_widget.resize(q_pixmap.width(), q_pixmap.height())
            self.main_frame.resize(self.main_layout_wide.sizeHint())
            self.setFixedSize(self.main_layout_wide.sizeHint())

    def display_animation(self):
        self.snap_sound.play()
        self._anim_worker = AnimWorker(self.img_manager, True)
        self._anim_thread = QThread()
        self._anim_worker.moveToThread(self._anim_thread)

        self._anim_worker.anim_done.connect(self.on_animation_complete)

        self._anim_thread.started.connect(self._anim_worker.work)

        self.full_snap_button.setDisabled(True)

        self._anim_thread.start()

    @pyqtSlot(str)
    def on_animation_complete(self, file_path: str):
        """Replace the original image widget until the movie completes, and then change it back"""
        self.animation_widget = AnimationWidget(file_path, self.outer_widget)
        self.full_snap_button.setDisabled(False)

        # self.main_layout_wide.replaceWidget(self.image_widget, self.animation_widget)
        prev_image_ix = self.main_layout_wide.indexOf(self.image_widget)
        # self.main_layout_wide.removeWidget(self.image_widget)
        self.image_widget.hide()  # FIXME Yuck
        self.main_layout_wide.addWidget(self.animation_widget, Qt.Horizontal)
        self.animation_widget.movie.finished.connect(
            self.replace_original_img_widget)
        # self.animation_widget.movie.setScaledSize(QSize(900, 900))
        self.animation_widget.movie.start()
        self.animation_widget.show()

    @pyqtSlot()
    def replace_original_img_widget(self):
        self.animation_widget.movie.stop()  # This is needed to
        self.animation_widget.hide()
        self.image_widget.show()
        self.main_layout_wide.removeWidget(self.animation_widget)
        self.main_layout_wide.insertWidget(1, self.image_widget)
        self.main_layout_wide.replaceWidget(self.animation_widget,
                                            self.image_widget)

    def on_snap(self):
        self.snap_sound.play()
        self.reload_image()

    def on_full_snap(self):
        for i in reversed(range(1, 101)):
            self.gain_slider.setSliderPosition(i)
            self.reload_image()
            sleep(3 / i**2)
            # sleep(1)

    def reload_image(self):
        """
        Reload the image within the current frame, asking the underlying functions to recalculate
        based on its current values.
        """
        img = self.img_manager.update_image()

        q_image = PyQt5.QtGui.QImage.fromData(img.read())
        q_pixmap = PyQt5.QtGui.QPixmap.fromImage(q_image)

        self.image_widget.setPixmap(q_pixmap)

    def on_gain_slider_adjust(self):
        new_value = self.gain_slider.value()
        # TODO Scale this
        print(new_value)
        self.img_manager.gain = new_value
        if self.img_manager.chunk_size > 10:
            self.reload_image()

    def on_chunk_slider_adjust(self):
        if self.chunk_size_slider.value() != self._current_chunk_size:
            self.chunk_size_button.setDisabled(False)

    def on_chunk_click(self):
        new_value = self.chunk_size_slider.value(
        ) + 1  # Make sure it's never equal to 0
        self.img_manager.chunk_size = new_value
        self.chunk_size_button.setDisabled(True)

    def on_reset(self):
        self.img_manager.reset()
        self.gain_slider.setValue(0)
        q_pixmap = PyQt5.QtGui.QPixmap(self._file_path)

        self.image_widget.setPixmap(q_pixmap)
コード例 #16
0
class SendFundsDestination(QtWidgets.QWidget):
    resized_signal = QtCore.pyqtSignal()

    def __init__(self, parent, parent_dialog, app_config,
                 hw_session: HwSessionInfo):
        QtWidgets.QWidget.__init__(self, parent)
        self.app_config = app_config
        self.parent_dialog = parent_dialog
        self.hw_session = hw_session
        self.recipients: List[SendFundsDestinationItem] = []
        self.change_addresses: List[Tuple[str, str]] = [
        ]  # List[Tuple[address, bip32 path]]
        self.change_controls_visible = True
        self.address_widget_width = None
        self.inputs_total_amount = 0.0
        self.fee_amount = 0.0
        self.inputs_count = 0
        self.values_unit = OUTPUT_VALUE_UNIT_AMOUNT
        self.tm_calculate_change_value = QTimer(self)
        self.tm_calculate_change_value.timeout.connect(
            self.on_tm_calculate_change_value)
        self.current_file_name = ''
        self.current_file_encrypted = False
        self.recent_data_files = []  # recent used data files
        self.setupUi(self)

    def setupUi(self, Form):
        self.setSizePolicy(
            QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding,
                                  QtWidgets.QSizePolicy.MinimumExpanding))

        self.lay_main = QtWidgets.QVBoxLayout(Form)
        self.lay_main.setContentsMargins(6, 6, 6, 6)
        self.lay_main.setSpacing(3)

        # 'totals' area:
        self.lbl_totals = QLabel(Form)
        self.lbl_totals.setTextInteractionFlags(
            QtCore.Qt.LinksAccessibleByMouse | QtCore.Qt.TextSelectableByMouse)
        self.lay_main.addWidget(self.lbl_totals)

        # output definition data file labels:
        self.lay_data_file = QHBoxLayout()
        self.lay_data_file.setContentsMargins(0, 0, 0, 6)
        self.lay_main.addItem(self.lay_data_file)
        self.lbl_data_file_name = QLabel(Form)
        self.lay_data_file.addWidget(self.lbl_data_file_name)
        self.lbl_data_file_badge = QLabel(Form)
        self.lay_data_file.addWidget(self.lbl_data_file_badge)
        self.lbl_data_file_name.setTextInteractionFlags(
            QtCore.Qt.LinksAccessibleByMouse | QtCore.Qt.TextSelectableByMouse)
        self.lbl_data_file_badge.setTextInteractionFlags(
            QtCore.Qt.LinksAccessibleByMouse | QtCore.Qt.TextSelectableByMouse)
        self.lay_data_file.addStretch()

        # actions/options area:
        self.lay_actions = QHBoxLayout()
        self.lay_actions.setSpacing(6)
        self.lay_actions.setContentsMargins(0, 0, 0, 0)
        self.lay_main.addItem(self.lay_actions)
        self.btn_add_recipient = QPushButton(Form)
        self.btn_add_recipient.clicked.connect(
            partial(self.add_dest_address, 1))
        self.btn_add_recipient.setAutoDefault(False)
        self.btn_add_recipient.setText("Add recipient")
        self.lay_actions.addWidget(self.btn_add_recipient)
        #
        self.btn_actions = QPushButton(Form)
        self.btn_actions.clicked.connect(partial(self.add_dest_address, 1))
        self.btn_actions.setAutoDefault(False)
        self.btn_actions.setText("Actions")
        self.lay_actions.addWidget(self.btn_actions)

        # context menu for the 'Actions' button
        self.mnu_actions = QMenu()
        self.btn_actions.setMenu(self.mnu_actions)
        a = self.mnu_actions.addAction("Load from file...")
        a.triggered.connect(self.on_read_from_file_clicked)
        self.mnu_recent_files = self.mnu_actions.addMenu('Recent files')
        self.mnu_recent_files.setVisible(False)
        a = self.mnu_actions.addAction("Save to encrypted file...")
        a.triggered.connect(partial(self.save_to_file, True))
        a = self.mnu_actions.addAction("Save to plain CSV file...")
        a.triggered.connect(partial(self.save_to_file, False))
        a = self.mnu_actions.addAction("Clear recipients")
        a.triggered.connect(self.clear_outputs)

        self.lbl_output_unit = QLabel(Form)
        self.lbl_output_unit.setText('Values as')
        self.lay_actions.addWidget(self.lbl_output_unit)
        self.cbo_output_unit = QComboBox(Form)
        self.cbo_output_unit.addItems(['amount', 'percentage'])
        self.cbo_output_unit.setCurrentIndex(0)
        self.cbo_output_unit.currentIndexChanged.connect(
            self.on_cbo_output_unit_change)
        self.lay_actions.addWidget(self.cbo_output_unit)
        self.lay_actions.addStretch(0)

        # scroll area for send to (destination) addresses
        self.scroll_area = QtWidgets.QScrollArea()
        self.scroll_area.setWidgetResizable(True)
        self.scroll_area.setMinimumHeight(30)
        self.scroll_area.setSizePolicy(
            QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                  QtWidgets.QSizePolicy.MinimumExpanding))
        self.scroll_area.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.lay_main.addWidget(self.scroll_area)

        self.scroll_area_widget = QtWidgets.QWidget()
        self.scroll_area_widget.setSizePolicy(
            QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                  QtWidgets.QSizePolicy.MinimumExpanding))
        self.lay_scroll_area = QtWidgets.QVBoxLayout()
        self.lay_scroll_area.setContentsMargins(0, 0, 0, 0)
        self.lay_scroll_area.setSpacing(0)
        self.scroll_area_widget.setLayout(self.lay_scroll_area)
        self.scroll_area.setWidget(self.scroll_area_widget)

        # grid layout for destination addresses and their corresponding controls:
        self.lay_addresses = QtWidgets.QGridLayout()
        self.lay_addresses.setSpacing(3)
        self.lay_addresses.setContentsMargins(0, 0, 0, 0)
        self.lay_scroll_area.addLayout(self.lay_addresses)
        self.lay_scroll_area.addStretch(0)

        # controls for the 'change' address/amount (it's placed in the last row of the addresses grid layout):
        self.lbl_change_address = QLabel(self.scroll_area_widget)
        self.lbl_change_address.setText('Change address')
        self.lbl_change_address.setAlignment(QtCore.Qt.AlignRight
                                             | QtCore.Qt.AlignTrailing
                                             | QtCore.Qt.AlignVCenter)
        self.lay_addresses.addWidget(self.lbl_change_address, 0, 0)
        # the 'change' address combobox:
        self.cbo_change_address = QtWidgets.QComboBox(self.scroll_area_widget)
        width = self.cbo_change_address.fontMetrics().width(
            'XvqNXF23dRBksxjW3VQGrBtJw7vkhWhenQ')
        self.address_widget_width = width + 40
        # combobox width on macos needs to be tweaked:
        self.cbo_change_address.setFixedWidth(
            self.address_widget_width + {'darwin': 5}.get(sys.platform, 0))
        self.lay_addresses.addWidget(self.cbo_change_address, 0, 1)
        self.lbl_change_amount = QLabel(self.scroll_area_widget)
        self.set_change_value_label()
        self.lay_addresses.addWidget(self.lbl_change_amount, 0, 2)
        # read only editbox for the amount of the change:
        self.edt_change_amount = QLineEdit(self.scroll_area_widget)
        self.edt_change_amount.setFixedWidth(100)
        self.edt_change_amount.setReadOnly(True)
        self.edt_change_amount.setStyleSheet('background-color:lightgray')
        self.lay_addresses.addWidget(self.edt_change_amount, 0, 3)
        # label dedicated to the second-unit value (e.g percentage if the main unit is set to (Dash) amount value)
        self.lbl_second_unit = QLabel(self.scroll_area_widget)
        self.lay_addresses.addWidget(self.lbl_second_unit, 0, 4)
        # spacer
        spacer = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Expanding,
                                       QtWidgets.QSizePolicy.Minimum)
        self.lay_addresses.addItem(spacer, 0, 5)

        # the last row of the grid layout is dedicated to 'fee' controls
        self.lbl_fee = QLabel(self.scroll_area_widget)
        self.lbl_fee.setText('Fee [Dash]')
        self.lbl_fee.setAlignment(QtCore.Qt.AlignRight
                                  | QtCore.Qt.AlignTrailing
                                  | QtCore.Qt.AlignVCenter)
        self.lay_addresses.addWidget(self.lbl_fee, 1, 0)

        # the fee value editbox with the 'use default' button:
        self.lay_fee_value = QHBoxLayout()
        self.lay_fee_value.setContentsMargins(0, 0, 0, 0)
        self.lay_fee_value.setSpacing(0)
        self.lay_addresses.addItem(self.lay_fee_value, 1, 1)
        self.edt_fee_value = QLineEdit(self.scroll_area_widget)
        self.edt_fee_value.setFixedWidth(100)
        self.edt_fee_value.textChanged.connect(self.on_edt_fee_value_changed)
        self.lay_fee_value.addWidget(self.edt_fee_value)
        self.btn_get_default_fee = QToolButton(self.scroll_area_widget)
        self.btn_get_default_fee.setText('\u2b06')
        self.btn_get_default_fee.setFixedSize(
            14,
            self.edt_fee_value.sizeHint().height())
        self.btn_get_default_fee.setToolTip('Use default fee')
        self.btn_get_default_fee.clicked.connect(
            self.on_btn_get_default_fee_clicked)
        self.lay_fee_value.addWidget(self.btn_get_default_fee)
        self.lay_fee_value.addStretch(0)

        # below the addresses grid place a label dedicated do display messages
        self.lbl_message = QLabel(Form)
        self.lbl_message.setTextInteractionFlags(
            QtCore.Qt.LinksAccessibleByMouse | QtCore.Qt.TextSelectableByMouse)
        self.lbl_message.setVisible(False)
        self.lay_main.addWidget(self.lbl_message)

        # add one 'send to' address row (in most cases it will bu sufficient)
        self.add_dest_address(1)

        # load last used file names from cache
        mru = app_cache.get_value(CACHE_ITEM_DATA_FILE_MRU_LIST,
                                  default_value=[],
                                  type=list)
        if isinstance(mru, list):
            for file_name in mru:
                if os.path.exists(file_name):
                    self.recent_data_files.append(file_name)
        self.update_mru_menu_items()

        self.retranslateUi(Form)

    def retranslateUi(self, Form):
        pass

    def sizeHint(self):
        sh = self.lay_scroll_area.sizeHint()
        marg_sl = self.lay_scroll_area.getContentsMargins()
        marg_ml = self.lay_main.getContentsMargins()
        if self.lbl_message.isVisible():
            msg_height = self.lbl_message.height()
        else:
            msg_height = 0
        sh.setHeight(sh.height() + marg_sl[1] + marg_sl[3] +
                     self.lay_actions.sizeHint().height() +
                     self.lbl_totals.sizeHint().height() +
                     self.lay_data_file.sizeHint().height() +
                     ((self.lay_main.count() - 1) * self.lay_main.spacing()) +
                     marg_ml[1] + marg_ml[3] + msg_height)
        return sh

    def display_message(self, message, color: Optional[str] = None):
        if message:
            self.lbl_message.setText(message)
            if color:
                self.lbl_message.setStyleSheet(f'QLabel{{color:{color}}}')
            changed_visibility = self.lbl_message.isVisible() != True
            self.lbl_message.setVisible(True)
        else:
            changed_visibility = self.lbl_message.isVisible() != False
            self.lbl_message.setVisible(False)

        if changed_visibility:
            QtWidgets.qApp.processEvents(QEventLoop.ExcludeUserInputEvents)
            self.resized_signal.emit()

    def move_grid_layout_row(self, from_row, to_row):
        for col_idx in range(self.lay_addresses.columnCount()):
            item = self.lay_addresses.itemAtPosition(from_row, col_idx)
            if item:
                if isinstance(item, QWidgetItem):
                    w = item.widget()
                    self.lay_addresses.removeWidget(w)
                    self.lay_addresses.addWidget(w, to_row, col_idx)
                elif isinstance(item, QLayout):
                    self.lay_addresses.removeItem(item)
                    self.lay_addresses.addItem(item, to_row, col_idx)
                elif isinstance(item, QSpacerItem):
                    self.lay_addresses.removeItem(item)
                    self.lay_addresses.addItem(item, to_row, col_idx)
                else:
                    raise Exception('Invalid item type')

    def add_dest_address(self, address_count: int = 1):
        # make a free space in the grid-layout for new addresses, just behind the last item related to the dest address
        for row_idx in reversed(
                range(len(self.recipients), self.lay_addresses.rowCount())):
            self.move_grid_layout_row(row_idx, row_idx + address_count)

        for nr in range(address_count):
            rcp_item = SendFundsDestinationItem(self.scroll_area_widget,
                                                self.app_config,
                                                self.lay_addresses,
                                                len(self.recipients),
                                                self.address_widget_width)
            rcp_item.sig_remove_address.connect(self.remove_dest_address)
            rcp_item.sig_use_all_funds.connect(self.use_all_funds_for_address)
            rcp_item.sig_amount_changed.connect(self.amount_changed)
            rcp_item.set_output_value_unit(self.values_unit)
            rcp_item.set_inputs_total_amount(self.inputs_total_amount -
                                             self.fee_amount)
            self.recipients.append(rcp_item)

        QtWidgets.qApp.processEvents(QEventLoop.ExcludeUserInputEvents)
        self.resized_signal.emit()
        self.show_hide_remove_buttons()
        self.display_totals()
        self.set_default_fee()

    def remove_item_from_layout(self, item):
        if item:
            if isinstance(item, QWidgetItem):
                w = item.widget()
                self.lay_addresses.removeWidget(w)
                w.setParent(None)
                del w
            elif isinstance(item, QLayout):
                for subitem_idx in reversed(range(item.count())):
                    subitem = item.itemAt(subitem_idx)
                    self.remove_item_from_layout(subitem)
                self.lay_addresses.removeItem(item)
                item.setParent(None)
                del item
            elif isinstance(item, QSpacerItem):
                del item
            else:
                raise Exception('Invalid item type')

    def remove_dest_address(self, address_item):
        row_idx = self.recipients.index(address_item)
        # remove all widgets related to the 'send to' address that is being removed
        for col_idx in range(self.lay_addresses.columnCount()):
            item = self.lay_addresses.itemAtPosition(row_idx, col_idx)
            self.remove_item_from_layout(item)

        # move up all rows greater than the row being removed
        for row in range(row_idx + 1, len(self.recipients)):
            self.move_grid_layout_row(row, row - 1)

        del self.recipients[row_idx]

        QtWidgets.qApp.processEvents(QEventLoop.ExcludeUserInputEvents)
        self.resized_signal.emit()
        self.show_hide_remove_buttons()
        self.set_default_fee()
        # self.calculate_change_amount()
        self.display_totals()

    def use_all_funds_for_address(self, address_item):
        row_idx = self.recipients.index(address_item)
        sum = 0.0
        left = 0.0

        # sum all the funds in all rows other than the current one
        for idx, addr in enumerate(self.recipients):
            if idx != row_idx:
                sum += addr.get_value(default_value=0.0)

        if self.values_unit == OUTPUT_VALUE_UNIT_AMOUNT:
            left = self.inputs_total_amount - sum - self.fee_amount
        elif self.values_unit == OUTPUT_VALUE_UNIT_PERCENT:
            left = 100.0 - sum

        left = round(left, 8) + 0.0
        if left < 0:
            left = 0.0
        address_item.set_value(left)
        self.update_change_amount()

    def amount_changed(self, addres_item):
        """ Activated after changing value in the 'amount' edit box of a recipient address. """
        self.init_calculate_change_value()

    def on_edt_fee_value_changed(self, text):
        if not text:
            text = '0.0'
        try:
            self.fee_amount = float(text)
            self.init_calculate_change_value()
        except Exception:
            self.display_message('Invalid \'transaction fee\' value.',
                                 'red')  # display error message

    def show_hide_change_address(self, visible):
        if visible != self.change_controls_visible:
            row_nr = self.lay_addresses.rowCount() - 1
            if row_nr >= 0:
                for col_idx in range(self.lay_addresses.columnCount()):
                    item = self.lay_addresses.itemAtPosition(row_nr, col_idx)
                    if item:
                        if isinstance(item, QWidgetItem):
                            item.widget().setVisible(visible)
                        elif isinstance(
                                item, (QSpacerItem, QHBoxLayout, QVBoxLayout)):
                            pass
                        else:
                            raise Exception('Invalid item type')
            self.change_controls_visible = visible
            QtWidgets.qApp.processEvents(QEventLoop.ExcludeUserInputEvents)
            self.resized_signal.emit()

    def show_hide_remove_buttons(self):
        visible = len(self.recipients) > 1
        for item in self.recipients:
            item.set_btn_remove_address_visible(visible)

    def set_change_addresses(self, addresses: List[Tuple[str, str]]):
        """
        :param addresses: addresses[0]: dest change address
                          addresses[1]: dest change bip32
        :return:
        """
        self.cbo_change_address.clear()
        self.change_addresses.clear()
        for addr in addresses:
            self.cbo_change_address.addItem(addr[0])
            self.change_addresses.append((addr[0], addr[1]))

    def set_input_amount(self, amount, inputs_count):
        self.inputs_count = inputs_count
        if amount != self.inputs_total_amount or inputs_count != self.inputs_count:
            # if there is only one recipient address and his current amount equals to the
            # previuus input_amount, assign new value to him

            last_total_amount = self.inputs_total_amount
            last_fee_amount = self.fee_amount
            self.inputs_total_amount = amount
            self.fee_amount = self.calculate_fee()

            if (len(self.recipients) == 1
                    or self.recipients[0].get_value(default_value=0.0) == 0.0
                    or self.recipients[0].get_value(default_value=0.0)
                    == round(last_total_amount - last_fee_amount, 8)):

                if self.values_unit == OUTPUT_VALUE_UNIT_AMOUNT:
                    amount_minus_fee = round(amount - self.fee_amount, 8)
                    if amount_minus_fee < 0:
                        amount_minus_fee = 0.0
                    self.recipients[0].set_value(amount_minus_fee)
                elif self.values_unit == OUTPUT_VALUE_UNIT_PERCENT:
                    self.recipients[0].set_value(100.0)

            old_state = self.edt_fee_value.blockSignals(True)
            self.edt_fee_value.setText(app_utils.to_string(self.fee_amount))
            self.edt_fee_value.blockSignals(old_state)

            for addr in self.recipients:
                addr.set_inputs_total_amount(amount - self.fee_amount)
                addr.clear_validation_results()

            self.edt_fee_value.update()
            self.update_change_amount()
            self.display_totals()

    def calculate_change_value(self) -> float:
        """Returns the change value in Dash."""
        sum = 0.0
        for addr in self.recipients:
            sum += addr.get_value(default_value=0.0)

        if self.values_unit == OUTPUT_VALUE_UNIT_AMOUNT:
            change_amount = round(
                self.inputs_total_amount - sum - self.fee_amount,
                8) + 0  # eliminate -0.0
        elif self.values_unit == OUTPUT_VALUE_UNIT_PERCENT:
            change_amount = round(
                (100.0 - sum) * (self.inputs_total_amount - self.fee_amount) /
                100, 8)
        else:
            raise Exception('Invalid unit')
        return change_amount

    def update_change_amount(self) -> None:
        change_amount = self.calculate_change_value()
        if self.inputs_total_amount - self.fee_amount != 0:
            change_pct = round(
                change_amount * 100 /
                (self.inputs_total_amount - self.fee_amount), 8) + 0
        else:
            change_pct = 0.0

        if self.values_unit == OUTPUT_VALUE_UNIT_AMOUNT:
            left_second_unit_str = app_utils.to_string(round(change_pct,
                                                             3)) + '%'
            self.edt_change_amount.setText(
                app_utils.to_string(round(change_amount, 8)))
        elif self.values_unit == OUTPUT_VALUE_UNIT_PERCENT:
            left_second_unit_str = app_utils.to_string(round(change_amount,
                                                             8)) + ' Dash'
            sum = 0.0
            for addr in self.recipients:
                sum += addr.get_value(default_value=0.0)
            self.edt_change_amount.setText(
                app_utils.to_string(round(100 - sum, 8)))
        else:
            raise Exception('Invalid unit')

        msg = ''
        if change_amount < 0:
            used_amount = round(self.inputs_total_amount - change_amount,
                                8) + 0
            msg = f'Not enough funds - used amount: ' \
                  f'{used_amount}, available: {self.inputs_total_amount}. Adjust ' \
                  f'the output values.'
        self.lbl_second_unit.setText(left_second_unit_str)
        self.display_message(msg, 'red')

    def validate_output_data(self) -> bool:
        ret = True
        for addr in self.recipients:
            if not addr.validate():
                ret = False
        if not ret:
            self.display_message(
                'Data of at least one recipient is invalid or empty. '
                'Please correct the data to continue.', 'red')
        else:
            self.display_message('')
        return ret

    def on_tm_calculate_change_value(self):
        self.tm_calculate_change_value.stop()
        for addr_item in self.recipients:
            addr_item.set_inputs_total_amount(self.inputs_total_amount -
                                              self.fee_amount)
        self.update_change_amount()

    def calculate_fee(self):
        if self.inputs_total_amount > 0.0:
            bytes = (self.inputs_count * 148) + (len(self.recipients) *
                                                 34) + 10
            fee = round(bytes * FEE_SAT_PER_BYTE, 8)
            if not fee:
                fee = MIN_TX_FEE
            fee = round(fee / 1e8, 8)
        else:
            fee = 0.0
        return fee

    def get_tx_fee(self):
        if self.fee_amount < 0.0:
            raise Exception('Invalid the fee value.')
        return round(self.fee_amount * 1e8)

    def init_calculate_change_value(self):
        self.tm_calculate_change_value.start(100)

    def set_default_fee(self):
        self.fee_amount = self.calculate_fee()

        old_status = self.edt_fee_value.blockSignals(True)
        try:
            self.edt_fee_value.setText(app_utils.to_string(self.fee_amount))
        finally:
            self.edt_fee_value.blockSignals(old_status)
        self.edt_fee_value.update()
        self.init_calculate_change_value()

    def on_btn_get_default_fee_clicked(self):
        self.set_default_fee()

    def set_dest_addresses(self, addresses: List):
        if len(addresses) > 0:
            count_diff = len(addresses) - len(self.recipients)
            if count_diff > 0:
                self.add_dest_address(count_diff)
            elif count_diff < 0:
                # remove unecessary rows, beginning from the largest one
                for nr in reversed(range(len(addresses),
                                         len(self.recipients))):
                    self.remove_dest_address(self.recipients[nr])
            for idx, addr_item in enumerate(self.recipients):
                if isinstance(addresses[idx], (list, tuple)):
                    # passed address-value tuple
                    if len(addresses[idx]) >= 1:
                        addr_item.set_address(addresses[idx][0])
                    if len(addresses[idx]) >= 2:
                        addr_item.set_value(addresses[idx][1])
                else:
                    addr_item.set_address(addresses[idx])
            self.display_totals()

    def set_change_value_label(self):
        if self.values_unit == OUTPUT_VALUE_UNIT_AMOUNT:
            self.lbl_change_amount.setText('value')
            self.lbl_change_amount.setToolTip(
                'Unused amount - will be sent back to the change address')
        else:
            self.lbl_change_amount.setText('pct. value')
            self.lbl_change_amount.setToolTip(
                'Unused amount (as percent of the total value of all inputs) - will '
                'be sent back to the change address')

    def on_cbo_output_unit_change(self, index):
        if index == 0:
            self.values_unit = OUTPUT_VALUE_UNIT_AMOUNT
        else:
            self.values_unit = OUTPUT_VALUE_UNIT_PERCENT

        self.set_change_value_label()
        for addr_item in self.recipients:
            addr_item.set_output_value_unit(self.values_unit)
        self.update_change_amount()

    def update_ui_value_unit(self):
        if self.values_unit == OUTPUT_VALUE_UNIT_AMOUNT:
            self.cbo_output_unit.setCurrentIndex(0)
        else:
            self.cbo_output_unit.setCurrentIndex(1)

    def simplyfy_file_home_dir(self, file_name):
        home_dir = os.path.expanduser('~')
        if self.current_file_name.find(home_dir) == 0:
            file_name = '~' + self.current_file_name[len(home_dir):]
        else:
            file_name = self.current_file_name
        return file_name

    def display_totals(self):
        bytes = (self.inputs_count * 148) + (len(self.recipients) * 34) + 10
        text = f'<span class="label"><b>Total value of selected inputs:</b>&nbsp;</span><span class="value">&nbsp;{self.inputs_total_amount} Dash&nbsp;</span>'
        if self.inputs_total_amount > 0:
            text += f'<span class="label">&nbsp;<b>Inputs:</b>&nbsp;</span><span class="value">&nbsp;{self.inputs_count}&nbsp;</span>' \
                    f'<span class="label">&nbsp;<b>Outputs:</b>&nbsp;</span><span class="value">&nbsp;{len(self.recipients)}&nbsp;</span>' \
                    f'<span class="label">&nbsp;<b>Transaction size:</b>&nbsp;</span><span class="value">&nbsp;{bytes} B&nbsp;</span>'
        self.lbl_totals.setText(text)

        if self.current_file_name:
            file_name = self.simplyfy_file_home_dir(self.current_file_name)
            text = f'<span class="label"><b>File:</b>&nbsp;</span><span class="value">{file_name}&nbsp;</span>'
            self.lbl_data_file_name.setText(text)
            self.lbl_data_file_name.setVisible(True)
            self.lbl_data_file_badge.setVisible(True)

            if self.current_file_encrypted:
                self.lbl_data_file_badge.setText('Encrypted')
                self.lbl_data_file_badge.setStyleSheet(
                    "QLabel{background-color:#2eb82e;color:white; padding: 1px 3px 1px 3px; border-radius: 3px;}"
                )
            else:
                self.lbl_data_file_badge.setText('Not encrypted')
                self.lbl_data_file_badge.setStyleSheet(
                    "QLabel{background-color:orange;color:white; padding: 1px 3px 1px 3px; border-radius: 3px;}"
                )
        else:
            self.lbl_data_file_name.setVisible(False)
            self.lbl_data_file_badge.setVisible(False)

    def clear_outputs(self):
        if WndUtils.queryDlg("Do you really want to clear all outputs?",
                             default_button=QMessageBox.Cancel,
                             icon=QMessageBox.Warning) == QMessageBox.Ok:
            self.set_dest_addresses([('', '')])
            self.use_all_funds_for_address(self.recipients[0])

    def save_to_file(self, save_encrypted):
        if self.current_file_name and os.path.exists(
                os.path.dirname(self.current_file_name)):
            dir = os.path.dirname(self.current_file_name)
        else:
            dir = self.app_config.data_dir

        if save_encrypted:
            initial_filter = "DAT files (*.dat)"
        else:
            initial_filter = "CSV files (*.csv)"

        file_filter = f"{initial_filter};;All Files (*)"

        file_name = WndUtils.save_file_query(
            self.parent_dialog,
            message='Enter the file name to save the data.',
            directory=dir,
            filter=file_filter,
            initial_filter=initial_filter)

        if file_name:
            data = bytes()
            data += b'RECIPIENT_ADDRESS\tVALUE\n'
            if self.values_unit == OUTPUT_VALUE_UNIT_PERCENT:
                suffix = '%'
            else:
                suffix = ''

            for addr in self.recipients:
                line = f'{addr.get_address()}{CSV_SEPARATOR}{str(addr.get_value(default_value=""))}{suffix}\n'
                data += line.encode('utf-8')

            if save_encrypted:
                write_file_encrypted(file_name, self.hw_session, data)
            else:
                with open(file_name, 'wb') as f_ptr:
                    f_ptr.write(data)

            self.current_file_name = file_name
            self.current_file_encrypted = save_encrypted
            self.add_menu_item_to_mru(self.current_file_name)
            self.update_mru_menu_items()
            self.display_totals()

    def on_read_from_file_clicked(self):
        try:
            if self.current_file_name and os.path.exists(
                    os.path.dirname(self.current_file_name)):
                dir = os.path.dirname(self.current_file_name)
            else:
                dir = self.app_config.data_dir

            initial_filter1 = "DAT files (*.dat)"
            initial_filter2 = "CSV files (*.csv)"

            file_filter = f"{initial_filter1};;{initial_filter2};;All Files (*.*)"

            file_name = WndUtils.open_file_query(
                self.parent_dialog,
                message='Enter the file name to read the data.',
                directory=dir,
                filter=file_filter,
                initial_filter='All Files (*.*)')

            if file_name:
                self.read_from_file(file_name)
        except Exception as e:
            self.parent_dialog.errorMsg(str(e))

    def read_from_file(self, file_name):
        try:
            file_info = {}
            data_decrypted = bytearray()
            for block in read_file_encrypted(file_name, file_info,
                                             self.hw_session):
                data_decrypted.extend(block)

            file_encrypted = file_info.get('encrypted', False)
            data = data_decrypted.decode('utf-8')

            addresses = []
            value_unit = None
            for line_idx, line in enumerate(data.split('\n')):
                if line:
                    elems = line.split('\t')
                    if len(elems) < 2:
                        elems = line.split(';')

                    if len(elems) < 2:
                        raise ValueError(
                            f'Invalid data file entry for line: {line_idx+1}.')

                    address = elems[0].strip()
                    value = elems[1].strip()

                    address_valid = dash_utils.validate_address(
                        address, dash_network=None)
                    if not address_valid:
                        if line_idx == 0 and re.match(r'^[A-Za-z_]+$',
                                                      address):
                            continue  # header line
                        else:
                            raise ValueError(
                                f'Invalid recipient address ({address}) (line {line_idx+1}).'
                            )

                    if value.endswith('%'):
                        vu = OUTPUT_VALUE_UNIT_PERCENT
                        value = value[:-1]
                    else:
                        vu = OUTPUT_VALUE_UNIT_AMOUNT
                    if value_unit is None:
                        value_unit = vu
                    elif value_unit != vu:
                        raise ValueError(
                            f'The value unit in line {line_idx+1} differs from the previous '
                            f'line.')

                    try:
                        if value:
                            value = float(value.replace(',', '.'))
                        else:
                            value = None
                        addresses.append((address, value))
                    except Exception as e:
                        raise ValueError(
                            f'Invalid data in the \'value\' field (line {line_idx+1}).'
                        )

            if len(addresses) == 0:
                raise Exception('File doesn\'t contain any recipient\'s data.')
            else:
                if self.values_unit != value_unit:
                    self.values_unit = value_unit
                    self.update_ui_value_unit()
                self.set_dest_addresses(addresses)
                self.current_file_name = file_name
                self.current_file_encrypted = file_encrypted
                self.add_menu_item_to_mru(self.current_file_name)
                self.update_mru_menu_items()
                self.update_change_amount()
                self.display_totals()
        except Exception as e:
            self.update_mru_menu_items()
            logging.exception(
                'Exception while reading file with recipients data.')
            self.parent_dialog.errorMsg(str(e))

    def add_menu_item_to_mru(self, file_name: str) -> None:
        if file_name:
            try:
                if file_name in self.recent_data_files:
                    idx = self.recent_data_files.index(file_name)
                    del self.recent_data_files[idx]
                    self.recent_data_files.insert(0, file_name)
                else:
                    self.recent_data_files.insert(0, file_name)
                app_cache.set_value(CACHE_ITEM_DATA_FILE_MRU_LIST,
                                    self.recent_data_files)
            except Exception as e:
                logging.warning(str(e))

    def update_mru_menu_items(self):
        app_utils.update_mru_menu_items(self.recent_data_files,
                                        self.mnu_recent_files,
                                        self.on_data_file_mru_action_triggered,
                                        self.current_file_name,
                                        self.on_act_clear_mru_items)

    def on_act_clear_mru_items(self):
        self.recent_data_files.clear()
        app_cache.set_value(CACHE_ITEM_DATA_FILE_MRU_LIST,
                            self.recent_data_files)
        self.update_mru_menu_items()

    def on_data_file_mru_action_triggered(self, file_name: str) -> None:
        """ Triggered by clicking one of the subitems of the 'Open Recent' menu item. Each subitem is
        related to one of recently openend data files.
        :param file_name: A data file name accociated with the menu action clicked.
        """
        self.read_from_file(file_name)

    def get_tx_destination_data(self) -> List[Tuple[str, int, str]]:
        """
        :return: Tuple structure:
            [0]: dest address
            [1]: value in satoshis/duffs
            [2]: bip32 path of the address if the item is a change address, otherwise None
        """
        if self.validate_output_data():
            change_amount = self.calculate_change_value()
            if change_amount < 0.0:
                self.update_change_amount(
                )  # here an appropriate message will be displayed
                raise Exception('Not enough funds!!!')

            dest_data = []
            for addr in self.recipients:
                dest_addr = addr.get_address()
                value = round(addr.get_value_amount() * 1e8)
                dest_data.append((dest_addr, value, None))

            if change_amount > 0.0:
                change_address_idx = self.cbo_change_address.currentIndex()
                if change_address_idx >= 0 and change_address_idx < len(
                        self.change_addresses):
                    dest_data.append(
                        (self.change_addresses[change_address_idx][0],
                         round(change_amount * 1e8),
                         self.change_addresses[change_address_idx][1]))
                else:
                    raise Exception('Invalid address for the change.')
            return dest_data
        else:
            return []

    def get_recipients_list(self) -> List[Tuple[str, ]]:
        """
        :return: List of recipient addresses
                 List[Tuple[str <address>, float <value>]
        """
        dest_data = []
        for addr in self.recipients:
            dest_addr = addr.get_address()
            if dest_addr:
                dest_data.append((dest_addr, ))
        return dest_data
コード例 #17
0
class TAAllocationOutputTab(QScrollArea):
    def __init__(self, ctx, a):
        super(TAAllocationOutputTab, self).__init__()
        self.ctx = ctx
        self.a = a

        self.wgtMain = QWidget()
        self.wgtMain.setSizePolicy(QSizePolicy.Fixed,
                                   QSizePolicy.MinimumExpanding)
        self.hboxMain = QHBoxLayout(self.wgtMain)

        self.allocation = self.ctx.app_data.results[a]

        self.drag_lists = []
        self.labels = []
        self.wgtSubs = []
        self.wgtSubLyts = []

        for t, table in enumerate(self.allocation):
            wgtSub = QGroupBox("Group {}".format(t + 1))
            wgtSub.setSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.MinimumExpanding)
            vboxSub = QVBoxLayout(wgtSub)
            self.wgtSubs.append(wgtSub)
            self.wgtSubLyts.append(vboxSub)

            drag_list = TAListDragAndDrop()
            drag_list.setMinimumHeight(200)
            drag_list.trigger.connect(self.update_tables_by_user)
            self.drag_lists.append(drag_list)
            vboxSub.addWidget(drag_list)

            label = QLabel()
            label.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
            self.labels.append(label)
            vboxSub.addWidget(label)

            self.hboxMain.addWidget(wgtSub)

        self.setWidget(self.wgtMain)

        self.set_content()

    def set_content(self):
        for t, table in enumerate(self.allocation):
            drag_list = self.drag_lists[t]
            label = self.labels[t]

            order_cluster_dict = self.ctx.app_data_manager.get_fields_cluster_dict(
            )
            order_diverse_dict = self.ctx.app_data_manager.get_fields_diverse_dict(
            )
            cats = {**order_cluster_dict, **order_diverse_dict}

            # set drag_list items
            drag_list.clear()
            r = 0
            for pid in table:
                newItem = QListWidgetItem()
                newItem.setData(Qt.UserRole, pid)
                print_label = self.ctx.app_data_manager.get_print_labels(pid)
                newItem.setText(print_label)
                tooltip_infos = [print_label]
                for field_key in cats:
                    field_key_label = self.ctx.app_data.peopledata_keys[
                        field_key]
                    field_pid_val = self.ctx.app_data_manager.load_details(
                        pid, field_key)
                    tooltip_infos.append("{}: {}".format(
                        field_key_label, field_pid_val))
                newItem.setToolTip("\n".join(tooltip_infos))
                drag_list.insertItem(r, newItem)
                r += 1

            label_strings = [
                "<p><strong>Total: {}</strong></p>".format(len(table))
            ]

            for cat_key, cat_val_terms in cats.items():
                label_strings.append("<p>{}:<br/>".format(
                    self.ctx.app_data.peopledata_keys[cat_key]))
                label_strings_cat = []
                for cat_val_term in cat_val_terms:
                    occurences = self.ctx.app_data_manager.get_occurences(
                        self.a, t, cat_key, cat_val_term)
                    label_strings_cat.append("{} {}".format(
                        occurences, cat_val_term))
                label_strings.append("<br/>".join(label_strings_cat))
                label_strings.append("</p>")

            label_string = " ".join(label_strings)
            label.setText(label_string)

        self.wgtMain.resize(self.hboxMain.sizeHint().width(),
                            self.wgtSubs[0].sizeHint().height() + 30)

    def update_tables_by_user(self):
        new_allocation = [[] for t in self.allocation]

        for t, table in enumerate(self.allocation):
            new_allocation[t] = [
                self.drag_lists[t].item(i).data(Qt.UserRole)
                for i in range(self.drag_lists[t].count())
            ]

        self.ctx.app_data.results[self.a] = new_allocation
        self.allocation = new_allocation

        self.ctx.set_unsaved()

        self.set_content()
コード例 #18
0
ファイル: douyu_client_sp.py プロジェクト: dick318/douyu_ver2
    def __init__(self):
        super(DisplayWindowSP, self).__init__()
        from douyu_client_gui import CHINESE_SIZE
        self.connect_widget = QWidget(self)
        self.room_id_list_config_button = QPushButton(u'设置监视的直播间列表', self)
        self.anchor_blacklist_config_button = QPushButton(u'设置主播黑名单', self)
        self.anchor_blacklist_check = QCheckBox(u'启用主播黑名单', self)
        self.room_id_list_config_widget = TextEditWidget(self)
        self.anchor_blacklist_config_widget = TextEditWidget(self)

        self.room_id_list_config_button.setCursor(POINT_HAND_CURSOR)
        self.anchor_blacklist_config_button.setCursor(POINT_HAND_CURSOR)
        self.room_id_list_config_button.setFixedWidth(CHINESE_SIZE.width() *
                                                      12)
        self.anchor_blacklist_config_button.setFixedWidth(
            CHINESE_SIZE.width() * 12)
        self.room_id_list_config_widget.setWindowTitle(u'设置监视的直播间列表')
        self.anchor_blacklist_config_widget.setWindowTitle(u'设置主播黑名单')

        self.topbar_widget.roomid_enter.setText('000000')
        self.topbar_widget.roomid_enter.setDisabled(True)
        self.topbar_widget.connect_danmu.setParent(self.connect_widget)
        self.topbar_widget.hide()
        self.tab_window.removeTab(0)
        self.tab_window.removeTab(1)

        connect_layout = QHBoxLayout()
        connect_layout.addWidget(self.anchor_blacklist_check)
        connect_layout.addWidget(self.anchor_blacklist_config_button)
        connect_layout.addStretch(1)
        connect_layout.addWidget(self.room_id_list_config_button)
        connect_layout.addWidget(self.topbar_widget.connect_danmu)
        connect_layout.setContentsMargins(10, 10, 10, 0)
        self.connect_widget.setLayout(connect_layout)
        self.connect_widget.resize(connect_layout.sizeHint())
        self.layout().insertWidget(0, self.connect_widget)

        self.room_id = '000000'
        self.connected_room_id_list = []
        self.room_id_list = []  # 连接的直播间号列表
        self.anchor_blacklist_enabled = False
        self.anchor_blacklist = []  # 主播黑名单
        self.queue_rid_order = {}
        self.queue_server_data = {}
        self.queue_message_data = {}
        self.queue_order_except_1 = {}
        self.queue_order_except_2 = {}
        self.dsp_temp = {}  # 广播消息显示缓存

        self.config_sp_file = os.path.join(self.room_config_path, 'config_sp')
        self.browser_list_file = os.path.join(PROGRAM_CONFIG_FOLDER,
                                              'BrowserList')
        self.browser_list = self.load_browser_list()
        self.update_details_timer.timeout.disconnect()
        self.config_widget.save_config_button.clicked.connect(
            self.load_browser_event)
        self.room_id_list_config_button.clicked.connect(
            self.room_id_list_config_button_event)
        self.anchor_blacklist_config_button.clicked.connect(
            self.anchor_blacklist_config_button_event)
        self.anchor_blacklist_check.clicked.connect(
            self.anchor_blacklist_check_event)
        self.room_id_list_config_widget.save_button.clicked.connect(
            self.room_id_list_config_save_event)
        self.anchor_blacklist_config_widget.save_button.clicked.connect(
            self.anchor_blacklist_config_save_event)
        self.room_id_list_config_widget.cancel_button.clicked.connect(
            self.room_id_list_config_widget.hide)
        self.anchor_blacklist_config_widget.cancel_button.clicked.connect(
            self.anchor_blacklist_config_widget.hide)

        self.load_config_sp()