Beispiel #1
0
class LocalButtonsConf(OptionsDialogGroupBox):
    def __init__(self, name, main):
        self.main = main
        OptionsDialogGroupBox.__init__(self, name, main)
        self.buttonBox = QGroupBox("Pins")
        self.buttonBoxLayout = QVBoxLayout()
        self.buttonBox.setLayout(self.buttonBoxLayout)

    def initUI(self):
        vbox = QVBoxLayout()
        self.polBox = QCheckBox("Invert")
        vbox.addWidget(self.polBox)
        self.buttongroup = QButtonGroup()
        self.buttongroup.setExclusive(False)
        vbox.addWidget(self.buttonBox)

        self.setLayout(vbox)

    def initButtons(self, num):
        #delete buttons
        self.num = num

        # Remove buttons
        for i in range(self.buttonBoxLayout.count()):
            b = self.buttonBoxLayout.takeAt(0)
            self.buttonBoxLayout.removeItem(b)
            b.widget().deleteLater()
        for b in self.buttongroup.buttons():
            self.buttongroup.removeButton(b)

        self.buttonBox.update()

        for i in range(self.num):
            cb = QCheckBox(str(i + 1))
            self.buttongroup.addButton(cb, i)
            self.buttonBoxLayout.addWidget(cb)

        def localcb(mask):
            for i in range(self.num):
                self.buttongroup.button(i).setChecked(mask & (1 << i))

        self.main.comms.serialGetAsync("local_btnmask?", localcb, int)

    def apply(self):
        mask = 0
        for i in range(self.num):
            if (self.buttongroup.button(i).isChecked()):
                mask |= 1 << i
        self.main.comms.serialWrite("local_btnmask=" + str(mask))
        self.main.comms.serialWrite("local_btnpol=" +
                                    ("1" if self.polBox.isChecked() else "0"))

    def readValues(self):
        self.main.comms.serialGetAsync("local_btnpins?", self.initButtons, int)

        self.main.comms.serialGetAsync("local_btnpol?", self.polBox.setChecked,
                                       int)
Beispiel #2
0
class DMSUnitWgt(QWidget):
    unitTabDataWdg = None
    decorateTypeWgt: DMSDecorateTypeWgt = None
    decorateDataWgt: DMSDecorateDataWgt = None

    currentBuilding: DB_Building = None
    unitDict: dict = {}

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

        self.initUI()
        self.initTrigger()

    def initUI(self):
        self.ui = Ui_UnitWgt()
        self.ui.setupUi(self)
        self.ui.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.setContentsMargins(0, 0, 0, 0)
        self.decorateTypeWgt = DMSDecorateTypeWgt(self)
        self.decorateDataWgt = DMSDecorateDataWgt(self)
        count = self.ui.verticalLayout.count()
        self.ui.verticalLayout.addWidget(self.decorateDataWgt)
        self.groupButton = QButtonGroup(self)

    def unitChanged(self):
        # self.decorateDataWgt.
        pass

    def initTrigger(self):
        self.ui.pBtnAddUnit.clicked.connect(self.addUnit)
        self.ui.pBtnDleleteUnit.clicked.connect(self.deleteUnit)
        self.groupButton.buttonClicked.connect(self.unitChanged)

    def setCurrentBuilding(self, building_id):
        if self.currentBuilding and self.currentBuilding.id == building_id:
            return
        self.currentBuilding = None
        building: DB_Building = dmsDatabase().getRecordById(
            DB_Building, building_id)
        if building is None:
            self.updateUiEnabled()
            return
        self.currentBuilding = building
        self.clearUnit()
        self.loadUnit()
        self.updateUiEnabled()

    def getCurrentUnit(self):
        pass

    def addUnit(self):
        unit = newUnit(self.currentBuilding)
        unit_tool_btn = self.createToolButton(unit)
        unit_tool_btn.setChecked(True)

    def deleteUnit(self):
        _id = self.groupButton.checkedId()
        _button = self.groupButton.checkedButton()

        self.groupButton.removeButton(_button)
        delete(_button)
        customDeleteRecord(DB_Building_Unit, _id)
        self.updateUiEnabled()

    def createToolButton(self, business_unit) -> QToolButton:
        if business_unit is None:
            return
        unit_tool_btn = QToolButton()
        unit_tool_btn.setText(business_unit.name)
        unit_tool_btn.setCheckable(True)
        count = self.ui.horizontalLayout.count()
        self.ui.horizontalLayout.insertWidget(count - 3, unit_tool_btn)
        self.unitDict[business_unit.id] = unit_tool_btn
        self.groupButton.addButton(unit_tool_btn, business_unit.id)

        return unit_tool_btn

    def loadUnit(self):
        if self.currentBuilding is None:
            return
        unit_list = dmsDatabase().getTableList(
            DB_Building_Unit, "building_id = " + str(self.currentBuilding.id))
        if len(unit_list) == 0:
            return
        first_item: QToolButton = None
        for item in unit_list:
            unit_tool_btn = self.createToolButton(item)
            if first_item is None:
                first_item = unit_tool_btn
        first_item.setChecked(True)

    def clearUnit(self):
        if len(self.unitDict) == 0:
            return
        tool_btn_list = self.unitDict.values()

        for var in self.groupButton.buttons():
            self.groupButton.removeButton(var)

        for item in tool_btn_list:
            self.ui.horizontalLayout.removeWidget(item)
            delete(item)
        self.unitDict.clear()

    def updateUnitDate(self, currentBuildingID, previousBuildingID=None):
        """
        槽函数
        :param currentBuildingID:
        :param previousBuildingID:
        :return:
        """
        pass
        # # Todo 待梳理嵌套关系
        # print(currentBuildingID, previousBuildingID)
        # dateTableWidget = self.unitTabWdg.currentWidget()
        # dateTableWidget = DMSDecorateDataWgt()
        # # decorateTaskList: List[DB_Decorate_Type] = dmsProject().getTableList(DB_Decorate_Type, filter_str=currentBuildingID).orderBy(
        # #     DB_Decorate_Type.order)
        # decorateTaskList: List[DB_Decorate_Type] = dmsDatabase().getTableList(DB_Decorate_Type)
        # tableHeaderList = [task.name for task in decorateTaskList]
        # dateTableWidget.setHorizontalHeaderLabels(tableHeaderList)

    def updateUiEnabled(self):
        enabled = False
        if len(self.unitDict) == 0:
            enabled = False
        else:
            enabled = True

        self.ui.pBtnDleleteUnit.setEnabled(enabled)
Beispiel #3
0
class ToggleToolBar(QWidget):

	index = 0
	buttons = []
	rows = []
	maxRow = 7
	maxCol = 4
	selectedFrame = []
	selectedButtons = []
	def __init__(self):
		super(ToggleToolBar, self).__init__()
		self.setFixedSize(300,560)
		self.container = QVBoxLayout()
		self.container.setAlignment(Qt.AlignLeft)
		self.container.setSpacing(5)
		for i in range(0,self.maxRow):
			row = QHBoxLayout()
			row.setAlignment(Qt.AlignTop)
			row.setSpacing(5)
			self.container.addLayout(row)
			self.rows.append(row)
		self.buttonGroup = QButtonGroup()
		self.buttonGroup.setExclusive(False)
		self.setLayout(self.container)
		self.buttonGroup.buttonClicked[int].connect(self.imageSelected)
	
	def imageSelected(self,imgId):
		button = self.buttons[imgId]
		if button.pixMap in self.selectedFrame and (not button.isChecked()):
			self.selectedFrame.remove(button.pixMap)
			self.selectedButtons.remove(button)

		if (not (button.pixMap in self.selectedFrame)) and button.isChecked():
			self.selectedFrame.append(button.pixMap)
			self.selectedButtons.append(button)

	def getSelected(self):
		return self.selectedFrame

	def clearAllSelected(self):
		for button in self.selectedButtons:
			button.setChecked(False)
		self.selectedButtons = []
		self.selectedFrame = []

	def addImageButton(self,image):
		imageButton = ImageToggleButton(self.index,image)
		self.buttonGroup.addButton(imageButton,self.index)
		self.rows[self.index//self.maxCol].addWidget(imageButton)
		self.buttons.append(imageButton)
		self.index += 1

	def createImageButtons(self,imagePath):
		groupImg = QImage(imagePath)
		width = groupImg.width()
		height = groupImg.height()
		frameSize = width
		for i in range(0,height//width):
			img = groupImg.copy(0,i*frameSize,frameSize,frameSize);
			self.addImageButton(img)

	def removeAllButton(self):
		for i in range(0,self.index):
			row = self.rows[i // self.maxCol]
			row.removeWidget(self.buttons[i])
			self.buttonGroup.removeButton(self.buttons[i])
			self.buttons[i].close()
		self.buttons = []
		self.index = 0
Beispiel #4
0
class MarkHandler(QWidget):
    def __init__(self, parent, maxScore, markStyle):
        super(MarkHandler, self).__init__()
        self.parent = parent
        # Set max score/mark
        self.maxScore = maxScore
        # Set current score/mark.
        self.currentScore = 0
        # One button for each possible mark, and a dictionary to store them.
        self.markButtons = {}
        # Styling for buttons
        self.redStyle = (
            "border: 2px solid #ff0000; background: "
            "qlineargradient(x1:0,y1:0,x2:1,y2:0, stop: 0 #ff0000, "
            "stop: 0.3 #ffcccc, stop: 0.7 #ffcccc, stop: 1 #ff0000);")
        # By default we set style to marking-UP.
        self.style = "Up"
        # Keep last delta used
        self.lastDelta = 0
        self.setLayout(QGridLayout())
        self._setStyle(markStyle)
        self.setDeltaButtonMenu()

    def _setStyle(self, markStyle):
        """Sets the mark entry style - either total, up or down
        Total - user just clicks the total mark.
        Up - score starts at zero and increments.
        Down - score starts at max and decrements.
        """
        # if passed a marking style, then set up accordingly.
        if markStyle == 1:
            self.setMarkingTotal()
        elif markStyle == 3:
            self.setMarkingDown()
        else:
            # Default to mark-up.
            self.setMarkingUp()
        self.ve = QButtonGroup()
        self.ve.setExclusive(True)
        for s, x in self.markButtons.items():
            self.ve.addButton(x)

    def resetAndMaybeChange(self, maxScore, markStyle):
        """Reset score, replace max/style with new values, regen buttons.

        Total - user just clicks the total mark.
        Up - score starts at zero and increments.
        Down - score starts at max and decrements.
        """
        d = {"Total": 1, "Up": 2, "Down": 3}
        if self.maxScore == maxScore and d[self.style] == markStyle:
            if markStyle == 3:
                self.setMark(self.maxScore)
            else:
                self.setMark(0)
            self.updateRelevantDeltaActions()
            return
        log.info("Adjusting for new number or new style")
        for k, x in self.markButtons.items():
            self.ve.removeButton(x)
            self.layout().removeWidget(x)
            x.deleteLater()
        self.markButtons.clear()
        self.currentScore = 0
        self.maxScore = maxScore
        self.markButtons = {}
        self._setStyle(markStyle)
        self.setDeltaButtonMenu()

    def getButtonList(self):
        """Return a list of the buttons"""
        return self.markButtons.values()

    def setMarkingUp(self):
        self.setMark(0)
        grid = self.layout()
        # assume our container will deal with margins
        grid.setContentsMargins(0, 0, 0, 0)
        grid.setSpacing(3)
        ncolumn = min(self.maxScore, 5)

        for k in range(0, self.maxScore + 1):
            b = QToolButton()
            self.markButtons[k] = b
            b.setText("+{}".format(k))
            b.setCheckable(True)
            # b.setAutoExclusive(True)
            grid.addWidget(b, k // ncolumn + 1, k % ncolumn, 1, 1)
            b.clicked.connect(self.setDeltaMark)
            b.setSizePolicy(QSizePolicy.MinimumExpanding,
                            QSizePolicy.MinimumExpanding)

        self.style = "Up"

    def setMarkingDown(self):
        self.setMark(self.maxScore)
        grid = self.layout()
        # assume our container will deal with margins
        grid.setContentsMargins(0, 0, 0, 0)
        grid.setSpacing(3)
        ncolumn = min(self.maxScore, 5)

        for k in range(0, self.maxScore + 1):
            b = QToolButton()
            self.markButtons[k] = b
            b.setText("-{}".format(k))
            b.setCheckable(True)
            # b.setAutoExclusive(True)
            grid.addWidget(b, k // ncolumn + 1, k % ncolumn, 1, 1)
            b.clicked.connect(self.setDeltaMark)
            b.setSizePolicy(QSizePolicy.MinimumExpanding,
                            QSizePolicy.MinimumExpanding)

        self.parent.totalMarkSet(self.currentScore)
        self.style = "Down"

    def setMarkingTotal(self):
        grid = self.layout()
        self.ptmb = QPushButton()

        if self.maxScore > 5:
            ncolumn = 3
        else:
            ncolumn = 2

        for k in range(0, self.maxScore + 1):
            self.markButtons[k] = QPushButton("{}".format(k))
            grid.addWidget(self.markButtons[k], k // ncolumn, k % ncolumn)
            self.markButtons[k].clicked.connect(self.setTotalMark)
            self.markButtons[k].setSizePolicy(QSizePolicy.MinimumExpanding,
                                              QSizePolicy.MinimumExpanding)

        self.parent.totalMarkSet(self.currentScore)
        self.style = "Total"

    def setDeltaMark(self):
        self.sender().setChecked(True)
        # yuck, but this will ensure other tools are not checked
        self.parent.ui.deltaButton.setChecked(True)
        self.currentDelta = self.sender().text()
        self.parent.deltaMarkSet(self.currentDelta)

    def setTotalMark(self):
        self.ptmb.setStyleSheet("")
        self.ptmb = self.sender()
        self.ptmb.setStyleSheet(self.redStyle)
        self.currentScore = int(self.sender().text())
        self.parent.totalMarkSet(self.currentScore)

    def setMark(self, newScore):
        self.currentScore = newScore
        self.parent.totalMarkSet(self.currentScore)

    def clearButtonStyle(self):
        # TODO: kill this?  but how to uncheck all in an exclusive group?
        if self.style == "Total":
            pass  # don't clear the styling when marking total.
        else:
            # Try this one wierd trick...
            self.ve.setExclusive(False)
            for k, x in self.markButtons.items():
                x.setChecked(False)
            self.ve.setExclusive(True)

    def loadDeltaValue(self, delta):
        # delta is a string
        idelta = int(delta)
        if abs(idelta) > self.maxScore or self.style == "Total":
            return
        self.markButtons[abs(idelta)].animateClick()

    def unpickleTotal(self, score):
        if (score <= self.maxScore) and (score >= 0) and (self.style
                                                          == "Total"):
            self.markButtons[score].animateClick()

    def incrementDelta(self, dlt):
        # dlt is a string, so make int(delta)
        delta = int(dlt)
        if self.style == "Up":
            if delta < 0:
                delta = 0
            else:
                delta += 1
            if delta > self.maxScore:
                delta = 0
            self.markButtons[delta].animateClick()
        elif self.style == "Down":
            if delta > 0:
                delta = -1
            else:
                delta -= 1
            if abs(delta) > self.maxScore:
                delta = -1
            self.markButtons[-delta].animateClick()

    def clickDelta(self, dlt):
        # dlt is a string, so make int(delta)
        # be careful if this has been set by a no-delta comment.
        if dlt == ".":
            delta = 0
        else:
            delta = int(dlt)
        if self.style == "Up":
            if delta < 0:
                delta = 0
            self.markButtons[delta].animateClick()
        elif self.style == "Down":
            if delta > 0:
                delta = 0
            self.markButtons[-delta].animateClick()

    def setDeltaButtonMenu(self):
        if self.style == "Total":
            # mark total - don't set anything
            return
        deltaMenu = QMenu("Set Delta")
        self.deltaActions = {}
        if self.style == "Up":
            # set to mark up
            for k in range(0, self.maxScore + 1):
                self.deltaActions[k] = deltaMenu.addAction("+{}".format(k))
                self.deltaActions[k].triggered.connect(
                    self.markButtons[k].animateClick)
        elif self.style == "Down":
            # set to mark down
            for k in range(0, self.maxScore + 1):
                self.deltaActions[k] = deltaMenu.addAction("-{}".format(k))
                self.deltaActions[k].triggered.connect(
                    self.markButtons[k].animateClick)
        self.parent.ui.deltaButton.setMenu(deltaMenu)
        self.updateRelevantDeltaActions()

    def updateRelevantDeltaActions(self):
        if self.style == "Total":
            return
        elif self.style == "Up":
            for k in range(0, self.maxScore + 1):
                if self.currentScore + k <= self.maxScore:
                    self.deltaActions[k].setEnabled(True)
                    self.markButtons[k].setEnabled(True)
                else:
                    self.deltaActions[k].setEnabled(False)
                    self.markButtons[k].setEnabled(False)
        elif self.style == "Down":
            for k in range(0, self.maxScore + 1):
                if self.currentScore >= k:
                    self.deltaActions[k].setEnabled(True)
                    self.markButtons[k].setEnabled(True)
                else:
                    self.deltaActions[k].setEnabled(False)
                    self.markButtons[k].setEnabled(False)
class MainWindow(QWidget):
    
	def __init__(self, inList):
		super().__init__()
		self.inList = inList
		self.nameFrom = 'Folder'
		self.codec = 'utvideo'
		self.alpha = False
		self.frameRate = 24
		self.defaulStyle = ''
		
		self.okIcon = QIcon(self.style().standardIcon(QStyle.SP_CustomBase))
		self.okPix = QPixmap(self.okIcon.pixmap(QSize(13, 13)))
		self.goodIcon = QIcon(self.style().standardIcon(QStyle.SP_DialogApplyButton))
		self.goodPix = QPixmap(self.goodIcon.pixmap(QSize(13, 13)))
		self.badIcon = QIcon(self.style().standardIcon(QStyle.SP_MessageBoxCritical))
		self.badPix = QPixmap(self.badIcon.pixmap(QSize(13, 13)))
		self.processingIcon = QIcon(self.style().standardIcon(QStyle.SP_ArrowRight))
		self.processingPix = QPixmap(self.processingIcon.pixmap(QSize(13, 13)))
		self.removeIcon = QIcon(self.style().standardIcon(QStyle.SP_DockWidgetCloseButton))
		self.removePix = QPixmap(self.removeIcon.pixmap(QSize(19, 19)))
		self.folderIcon = QIcon(self.style().standardIcon(QStyle.SP_FileDialogNewFolder))
		self.folderPix = QPixmap(self.folderIcon.pixmap(QSize(19, 19)))
		
		self.pbList = []
		self.chList = []
		self.lblList = []
		self.rmbList = []
		#self.newFolders = []
		self.initUI()

	def initUI(self):
		self.resize(720, 300)
		self.setWindowTitle('FFMpeg Python Compressor')
		self.verticalLayout = QVBoxLayout(self)
		self.verticalLayout.setContentsMargins(11, 11, 11, 11)
		self.verticalLayout.setSpacing(11)
		
		#COMBOBOX LABELS
		self.gridLayoutControlls = QGridLayout()
		self.codecLabel = QLabel('Codec', self)
		self.codecLabel.setMinimumHeight(13)
		self.alphaLabel = QLabel('Alpha' , self)
		self.alphaLabel.setMinimumHeight(13)
		self.frameRateLabel = QLabel('Frame Rate' , self)
		self.frameRateLabel.setMinimumHeight(13)
		self.gridLayoutControlls.addWidget(self.codecLabel, 0, 0, 1, 1)
		self.gridLayoutControlls.addWidget(self.alphaLabel, 0, 1, 1, 1)
		self.gridLayoutControlls.addWidget(self.frameRateLabel, 0, 2, 1, 1)
		
		#COMBOBOXES AND COMPRESS BUTTON
		self.codecComboBox = QComboBox(self)
		self.codecComboBox.setMinimumSize(80,23)
		self.codecComboBox.addItem("UT Video")
		self.codecComboBox.activated[str].connect(self.chooseCodec)
		
		self.alphaComboBox = QComboBox(self)
		self.alphaComboBox.setMinimumSize(80,23)
		self.alphaComboBox.addItem("No Alpha")
		self.alphaComboBox.addItem("with Alpha")
		self.alphaComboBox.activated[str].connect(self.chooseAlpha)
		
		self.frameRateComboBox = QComboBox(self)
		self.frameRateComboBox.setMinimumSize(80,23)
		self.frameRateComboBox.addItem("23.976")
		self.frameRateComboBox.addItem("24.00")
		self.frameRateComboBox.addItem("29.97")
		self.frameRateComboBox.addItem("30.00")
		self.frameRateComboBox.setCurrentIndex(1)
		self.frameRateComboBox.activated[str].connect(self.chooseFrameRate)
		
		self.compressButton = QPushButton('Compress', self)
		self.compressButton.setMinimumSize(80,23)
		self.compressButton.clicked[bool].connect(self.compressPress)
			
		self.gridLayoutControlls.addWidget(self.codecComboBox, 1, 0, 1, 1)
		self.gridLayoutControlls.addWidget(self.alphaComboBox, 1, 1, 1, 1)
		self.gridLayoutControlls.addWidget(self.frameRateComboBox, 1, 2, 1, 1)
		self.gridLayoutControlls.addWidget(self.compressButton, 1, 3, 1, 1)
			
		#RADIO BUTTON GROUP
		self.groupBox = QButtonGroup(self)
		self.radio1 = QRadioButton('Output file name from Folder name', self)
		self.radio1.setMinimumSize(80,25)
		self.radio2 = QRadioButton('Output file name from File name', self)
		self.radio2.setMinimumSize(80,25)
		self.radio1.setChecked(True)
		self.groupBox.addButton(self.radio1,1)
		self.groupBox.addButton(self.radio2,2)
		self.groupBox.buttonClicked[int].connect(self.radioBtnState)
		
		self.gridLayoutControlls.addWidget(self.radio1, 2, 0, 1, 2)
		self.gridLayoutControlls.addWidget(self.radio2, 2, 2, 1, 2)
		
		#LINE
		self.line = QFrame(self)
		self.line.setLineWidth(2)
		self.line.setMinimumHeight(3)
		self.line.setFrameShape(QFrame.HLine)
		self.line.setFrameShadow(QFrame.Sunken)
		
		self.gridLayoutControlls.addWidget(self.line, 3, 0, 1, 4)
		
		#PROGRESS BAR 
		self.gridLayoutProgress = QGridLayout()
		self.gridLayoutProgress.setVerticalSpacing(11)
		self.gridLayoutProgress.setHorizontalSpacing(6)
		self.gridLayoutProgress.setSizeConstraint(QLayout.SetNoConstraint)
		
		self.removeGroupBox = QButtonGroup(self)
		self.addProgressBarUI(self.inList)			
		self.removeGroupBox.buttonClicked[int].connect(self.removeButtonClicked)

		#ADD MORE AREA
		self.gridLayoutAddMore = QGridLayout()
		self.gridLayoutAddMore.setContentsMargins(0, 0, 0, 0)
		
		self.dragAndDropLabel_1 = QLabel("Drag and Drop folders here", self)
		self.dragAndDropLabel_1.setMinimumSize(QSize(120, 40))
		self.dragAndDropLabel_1.setAlignment(Qt.AlignCenter)
		
		self.dragAndDropLabel_2 = QLabel("", self)
		self.dragAndDropLabel_2.setFixedSize(QSize(20, 40))
		self.dragAndDropLabel_2.setAlignment(Qt.AlignCenter)
		self.dragAndDropLabel_2.setPixmap(self.folderPix)
		
		sI = QSpacerItem(40, 40,QSizePolicy.Expanding, QSizePolicy.Minimum)
		sI2 = QSpacerItem(40, 40,QSizePolicy.Expanding, QSizePolicy.Minimum)
		
		self.gridLayoutAddMore.addItem(sI, 1, 0, 1, 1)
		self.gridLayoutAddMore.addWidget(self.dragAndDropLabel_2, 1, 1, 1, 1)
		self.gridLayoutAddMore.addWidget(self.dragAndDropLabel_1, 1, 2, 1, 1)
		self.gridLayoutAddMore.addItem(sI2, 1, 3, 1, 1)
		
		#DEBUG AREA
		self.gridLayoutDebug = QGridLayout()
		self.line_2 = QFrame(self)
		self.line_2.setLineWidth(2)
		self.line_2.setFrameShape(QFrame.HLine)
		self.line_2.setFrameShadow(QFrame.Sunken)
		
		self.exploreOutputBtn = QPushButton('Explore Output',self)
		self.exploreOutputBtn.clicked[bool].connect(self.exploreOutput)

		self.hideShowLog = QPushButton('Show Log',self)
		self.hideShowLog.setCheckable(True)
		self.hideShowLog.clicked[bool].connect(self.showDebugLog)
		#self.hideShowLog.setMinimumSize(QSize(0, 20))
		
		self.logText = QPlainTextEdit('',self)
		self.logText.setReadOnly(True)
		self.logText.hide()
		
		self.spacerItem = QSpacerItem(20, 0, QSizePolicy.Minimum, QSizePolicy.Expanding)
		
		self.gridLayoutDebug.addWidget(self.line_2, 0, 0, 1, 1)
		self.gridLayoutDebug.addWidget(self.exploreOutputBtn, 1, 0, 1, 1)
		self.gridLayoutDebug.addWidget(self.hideShowLog, 2, 0, 1, 1)
		self.gridLayoutDebug.addWidget(self.logText, 3, 0, 1, 1)
		self.gridLayoutDebug.addItem(self.spacerItem, 4, 0, 1, 1)
		
		self.verticalLayout.addLayout(self.gridLayoutControlls)
		self.verticalLayout.addLayout(self.gridLayoutProgress)
		self.verticalLayout.addLayout(self.gridLayoutAddMore)
		self.verticalLayout.addLayout(self.gridLayoutDebug)
		
		# Enable dragging and dropping onto the GUI
		self.setAcceptDrops(True)
		
		#QtCore.QMetaObject.connectSlotsByName(self)
		self.show()
		self.setMinimumSize(self.size())
		
		self.threadpool = QThreadPool()
		self.threadpool.setMaxThreadCount(1)
		print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
    
	
	
	'''
	Progress bar populate function
	'''
	def addProgressBarUI(self, arr):
		pbCount = len(self.pbList)
		for i in range(len(arr)):
			tempCheckBox = QCheckBox(self)
			tempCheckBox.setChecked(True)
			tempCheckBox.setMinimumSize(14,21)
			
			tempRemoveButton = QPushButton(self)
			tempRemoveButton.setIcon(self.removeIcon)
			tempRemoveButton.setFlat(True)
			tempRemoveButton.setIconSize(QSize(19,19))
			tempRemoveButton.setFixedSize(QSize(19,21))
			
			
			tempPB = QProgressBar(self)
			tempPB.setMinimumSize(50,21)
			tempPB.setMinimum(0)
			tempPB.setMaximum(100)
			tempPB.setTextVisible(True)
			tempPB.setFormat(str(arr[i])+" %p%")
			tempPB.setAlignment(Qt.AlignCenter)
			tempPB.setValue(0)
			if i==0:
				self.defaulStyle = tempPB.styleSheet()
			
			tempStatusLabel = QLabel(self)			
			tempStatusLabel.setPixmap(self.okPix)
			tempStatusLabel.setMinimumSize(13,21)
			
			self.gridLayoutProgress.addWidget(tempCheckBox, pbCount+i, 0, 1, 1)
			self.gridLayoutProgress.addWidget(tempPB, pbCount+i, 1, 1, 1)
			self.gridLayoutProgress.addWidget(tempStatusLabel, pbCount+i, 2, 1, 1)
			self.gridLayoutProgress.addWidget(tempRemoveButton, pbCount+i, 3, 1, 1)
			self.removeGroupBox.addButton(tempRemoveButton, pbCount+i)
			
			self.pbList.append(tempPB)
			self.chList.append(tempCheckBox)
			self.lblList.append(tempStatusLabel)
			self.rmbList.append(tempRemoveButton)
	
		
	'''
	Drag+Drop Functions
	'''
	# The following three methods set up dragging and dropping for the app
	def dragEnterEvent(self, e):
		if e.mimeData().hasUrls:
			e.accept()
		else:
			e.ignore()

	def dragMoveEvent(self, e):
		if e.mimeData().hasUrls:
			e.accept()
		else:
			e.ignore()

	def dropEvent(self, e):
		"""
		Drop files directly onto the widget
		File locations are stored in fname
		:param e:
		:return:
		"""
		newFolders = []
		if e.mimeData().hasUrls:
			e.setDropAction(Qt.CopyAction)
			e.accept()
			# Workaround for OSx dragging and dropping
			for url in e.mimeData().urls():
				if op_sys == 'Darwin':
					#check for dir here as well
					fname = str(NSURL.URLWithString_(str(url.toString())).filePathURL().path())
				else:
					fname = str(url.toLocalFile())
					if os.path.isdir(fname) == True:
						newFolders.append(fname)
					#print(fname)

			#self.fname = fname
			#print(self.fname)
			#self.load_image()
			self.addNewFolders(newFolders)
			self.inList = self.inList + newFolders
		else:
			e.ignore()
	

	def addNewFolders(self, newFolders):
		self.addProgressBarUI(newFolders)
		self.setMinimumHeight(self.height()+len(newFolders)*32)
		#self.resize(self.width(),self.height()+200)
		self.update()
		self.adjustSize()
		self.setMinimumSize(self.size())
	'''
	Button Functions
	'''
	def chooseAlpha(self, text):
		switcher={
			"No Alpha":False,
			"with Alpha":True
		}
		self.alpha = switcher.get(text,"Invalid day of week")
		#print (self.alpha)

	def chooseCodec(self, text):
		switcher={
			"UT Video":"utvideo"
		}
		self.codec =  switcher.get(text,"Invalid day of week")
		#print (self.codec)
		
	def chooseFrameRate(self, text):
		self.frameRate =  float(text)
		#print (self.frameRate)
	
	
	def currentData(self, widget):
		return widget.currentText() 

	def radioBtnState(self, text):
		switcher={
			1:'Folder',
			2:'File'
		}
		self.nameFrom = switcher.get(text,"Invalid day of week")
		#print(self.nameFrom)
	
	def removeButtonClicked(self, i):
		#print('remove trigger on id '+str(i))
		
		#self.pbList.pop(i)
		'''
		self.pbList[i].hide()
		self.chList[i].setChecked(False)
		self.chList[i].hide()
		self.lblList[i].hide()
		self.rmbList[i].hide()
		'''
		print(self.gridLayoutProgress.rowCount())
		self.pbList[i].setParent(None)
		self.chList[i].setChecked(False)
		self.chList[i].setParent(None)
		self.lblList[i].setParent(None)
		self.rmbList[i].setParent(None)
		
		self.removeGroupBox.removeButton(self.rmbList[i])

		self.gridLayoutProgress.removeWidget(self.pbList[i])
		self.gridLayoutProgress.removeWidget(self.chList[i])
		self.gridLayoutProgress.removeWidget(self.lblList[i])
		self.gridLayoutProgress.removeWidget(self.rmbList[i])
		self.gridLayoutProgress.invalidate()
		self.gridLayoutProgress = QGridLayout()
		self.gridLayoutProgress.setVerticalSpacing(11)
		self.gridLayoutProgress.setHorizontalSpacing(6)
		self.gridLayoutProgress.setSizeConstraint(QLayout.SetDefaultConstraint)
		self.verticalLayout.insertLayout(1,self.gridLayoutProgress)
		
		print(self.gridLayoutProgress.rowCount())
		'''
		print(self.pbList)
		print(self.chList)
		print(self.lblList)
		print(self.rmbList)
		'''
		
		self.pbList.pop(i)
		self.chList.pop(i)
		self.lblList.pop(i)
		self.rmbList.pop(i)
		self.inList.pop(i)		
		

		#clear the gridLayout
		for j in reversed(range(len(self.pbList))):
			self.pbList[j].setParent(None)
			self.chList[j].setParent(None)
			self.lblList[j].setParent(None)
			self.rmbList[j].setParent(None)
		
		
		#reorder the gridLayout
		for j in range(len(self.pbList)):
			self.gridLayoutProgress.addWidget(self.chList[j], j, 0, 1, 1)
			self.gridLayoutProgress.addWidget(self.pbList[j], j, 1, 1, 1)
			self.gridLayoutProgress.addWidget(self.lblList[j], j, 2, 1, 1)
			self.gridLayoutProgress.addWidget(self.rmbList[j], j, 3, 1, 1)
			self.removeGroupBox.setId(self.rmbList[j],j)

		
		
		self.setMinimumHeight(self.height()-30)
		#self.setMinimumHeight(100)
		self.adjustSize()
		self.setMinimumSize(self.size())
		print(self.gridLayoutProgress.rowCount())
		#self.correctSize()
		'''
		for j in range(len(self.removeGroupBox.buttons())):
			button = self.removeGroupBox.buttons()[j]
			#print(button)
			#print('original id '+str(self.removeGroupBox.id(button)))
			#print('new id '+str(j))
			self.removeGroupBox.setId(button,j)
		'''
	
	def correctSize(self):
			self.logText.show()
			self.gridLayoutDebug.removeItem(self.spacerItem)
			self.adjustSize()
			self.setMinimumSize(self.size())
			self.repaint()
			self.gridLayoutDebug.addItem(self.spacerItem)
			self.logText.hide()
			self.setMinimumHeight(100)
			self.adjustSize()
			self.setMinimumSize(self.size())
	
	def showDebugLog(self, bol):
		if bol:
			self.logText.show()
			self.hideShowLog.setText('Hide Log')
			self.gridLayoutDebug.removeItem(self.spacerItem)
			self.adjustSize()
			#self.resize(self.width(), self.height()+80)
			self.setMinimumSize(self.size())
		else:
			self.gridLayoutDebug.addItem(self.spacerItem)
			self.logText.hide()
			self.hideShowLog.setText('Show Log')
			self.setMinimumHeight(100)
			self.adjustSize()
			self.setMinimumSize(self.size())
			#self.resize(self.width(), 100)
			#self.setGeometry(0,0,self.width(),100)
	
	'''
	Execution Functions
	'''
	def execute_this_fn(self, path, codec, alpha, frameRate, nameFrom, i, progress_callback, errorFFMPEG_callback):
		#print(path)
		pyCompression = pyFFMEGCompress(path, codec, alpha, frameRate, nameFrom)
		ffProcess = pyCompression.ffmpegCompress()
		self.lblList[i].setPixmap(self.processingPix)
		
		#with kwargs
		kwargs = {'progress_callback':progress_callback, 'errorFFMPEG_callback':errorFFMPEG_callback}
		pyCompression.printProcess(ffProcess, **kwargs)

		return (pyCompression.debugString,pyCompression.error,i)
 
	def printOutput(self, s):
		print("Printing output "+ str(s))
		
	def threadComplete(self, r):
		#print("THREAD COMPLETE! WITH ERROR " + str(r[2]) )
		if r[1] == False:
			self.lblList[r[2]].setPixmap(self.goodPix)
			self.pbList[r[2]].setStyleSheet("QProgressBar::chunk {background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #44dd14,stop: 0.4999 #39c10f,stop: 0.5 #39c10f,stop: 1 #39c10f );border-radius: 3px; border: 1px solid #29880b;}QProgressBar{color:white}")
			self.pbList[r[2]].setValue(100)

	def errorPB(self, err):
		for i in range(len(self.pbList)):
			if self.pbList[i].format() == err:
				self.pbList[i].setValue(100)
				self.pbList[i].setStyleSheet("QProgressBar::chunk {background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #FF0350,stop: 0.4999 #FF0020,stop: 0.5 #FF0019,stop: 1 #FF0000 );border-radius: 3px; border: 1px solid #a60233;}QProgressBar{color:white}")
				self.pbList[i].setFormat(self.pbList[i].format()+" - Error")
				self.chList[i].setChecked(False)
				self.lblList[i].setPixmap(self.badPix)
				
	def resetProgressBar(self, pb, text, lbl):
		pb.setValue(0)
		pb.setFormat(text + ' %p%')
		pb.setStyleSheet(self.defaulStyle)
		lbl.setPixmap(self.okPix)
	

	def compressPress(self):
		for i in range(len(self.pbList)):				
			if self.chList[i].isChecked():
				self.resetProgressBar(self.pbList[i],self.inList[i],self.lblList[i])
				
				worker = Worker(self.execute_this_fn, self.inList[i], self.codec, self.alpha, self.frameRate, self.nameFrom, i) # Any other args, kwargs are passed to the run function
				#worker.signals.result.connect(self.printOutput)
				worker.signals.result.connect(self.logText.appendPlainText)
				worker.signals.progress.connect(self.pbList[i].setValue)
				worker.signals.errorFFMPEG.connect(self.errorPB)
				worker.signals.error.connect(self.errorPB)
				worker.signals.finished.connect(self.threadComplete)
				#worker.signals.finished.connect(self.logText.appendPlainText)
				
				# Execute
				self.threadpool.start(worker)

	def exploreOutput(self):
		FILEBROWSER_PATH = os.path.join(os.getenv('WINDIR'), 'explorer.exe')
		explorePath = os.path.normpath('C:\\ExportedMOVs')
		subprocess.run([FILEBROWSER_PATH, explorePath])
class Classbar(QWidget):
    def __init__(self, state):
        super().__init__()
        self.state = state
        self.state.classbar = self

        self.classes = {}
        self.classes_group = QButtonGroup()
        self.class_label = QLabel('Current class: \n')
        self.layout = None

        self.init_gui()
        classes = list(self.state.classes)
        self.state.classes = []
        for c in classes:
            self.add_class(c)

    def init_gui(self):
        self.setMinimumHeight(400)
        self.setMaximumWidth(150)

        wrapper_layout = QVBoxLayout()
        box = QGroupBox('Classes')
        self.layout = QVBoxLayout()
        wrapper_layout.setAlignment(QtCore.Qt.AlignTop)
        self.layout.setAlignment(QtCore.Qt.AlignTop)
        box.setLayout(self.layout)
        wrapper_layout.addWidget(box)

        self.layout.addWidget(self.class_label)
        self._init_add_remove_buttons(self.layout)

        self.setLayout(wrapper_layout)

    def _init_add_remove_buttons(self, layout):
        box = QGroupBox()
        box.setMaximumHeight(50)

        layout.addWidget(box)
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        box.setLayout(layout)

        add_button = QPushButton('+')
        remove_button = QPushButton('-')
        add_button.clicked.connect(self.trigger_add_class_dialog)
        remove_button.clicked.connect(
            lambda: self.remove_class(self.state.active_class))

        layout.addWidget(add_button)
        layout.addWidget(remove_button)

        return box

    def add_class(self, name: str):
        if name in self.classes.keys():
            return
        self.classes[name] = QRadioButton(name)
        add_class = self.classes[name]
        self.classes_group.addButton(add_class)
        self.layout.addWidget(add_class)
        self.state.classes.append(name)
        add_class.clicked.connect(lambda: self.set_active_class(name))

    def remove_class(self, name: str):
        if not name:
            return
        if self.state.active_class == name:
            self.set_active_class('')
        self.state.classes.remove(name)
        remove_class = self.classes[name]
        del self.classes[name]
        self.classes_group.removeButton(remove_class)
        self.layout.removeWidget(remove_class)
        remove_class.deleteLater()

    def trigger_add_class_dialog(self):
        new_class, ok = QInputDialog.getText(
            self, 'New Class', 'Enter the name of the new class:')
        if ok:
            self.add_class(new_class)
        self.state.display.source_label.setFocus()

    def set_active_class(self, name):
        self.class_label.setText('Current Class:  \n' + name)
        self.state.active_class = name
Beispiel #7
0
class AttGenW(QGridLayout):
    _code = {
        1: "???",
        11: "0~0.5",
        12: "0.5~1.0",
        13: "1.0~2.0",
        14: "2.0~5.0",
        15: "5.0以",
        21: "0~0.5",
        22: "0.5~1.0",
        23: "1.0~2.0",
        24: "2.0~3.0",
        25: "3.0~4.0",
        26: "4.0~5.0",
        27: "5.0以上",
        31: "0~0.5m未満",
        32: "0.5~3.0",
        33: "3.0~5.0",
        34: "5.0~10.0",
        35: "10.0~20.0",
        36: "20.0以上",
        41: "0~0.3",
        42: "0.3~0.5",
        43: "0.5~1.0",
        44: "1.0~3.0",
        45: "3.0~5.0",
        46: "5.0~10.0",
        47: "10.0~20.0",
        48: "20.0以上",
        99: "XXX"
    }

    _color = {
        1: QColor(0, 255, 255),
        11: QColor(255, 153, 0),
        12: QColor(0, 255, 85),
        13: QColor(0, 255, 255),
        14: QColor(0, 0, 255),
        15: QColor(102, 0, 255),
        21: QColor(255, 153, 0),
        22: QColor(0, 255, 85),
        23: QColor(0, 255, 255),
        24: QColor(0, 0, 255),
        25: QColor(255, 0, 102),
        26: QColor(255, 0, 255),
        27: QColor(102, 0, 255),
        31: QColor(255, 153, 0),
        32: QColor(0, 255, 85),
        33: QColor(0, 255, 255),
        34: QColor(0, 0, 255),
        35: QColor(255, 0, 102),
        36: QColor(255, 0, 255),
        41: QColor(255, 153, 0),
        42: QColor(0, 255, 85),
        43: QColor(0, 255, 255),
        44: QColor(0, 0, 255),
        45: QColor(255, 0, 102),
        46: QColor(255, 0, 255),
        47: QColor(102, 0, 255),
        48: QColor(102, 102, 255),
        99: QColor(0, 0, 0)
    }

    tableUpdate = pyqtSignal(int)
    selUpdate = pyqtSignal()
    useUpdate = pyqtSignal()
    colUpdate = pyqtSignal(int)

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

        self.newrow = 0
        self.table = {}

        self.create_widgets()
        self.set_widgets()
        self.layout_widgets()
        self.create_connections()

    def create_widgets(self):
        self.title = QLabel("* Generate Attributes *")
        self.set1 = QPushButton("1段階")
        self.set5 = QPushButton("5段階")
        self.set6 = QPushButton("6段階")
        self.set7 = QPushButton("7段階")
        self.set8 = QPushButton("8段階")
        self.clr = QPushButton("clear")
        self.shwA = QPushButton("all")
        self.shwS = QPushButton("use")
        self.shwN = QPushButton("none")
        self.bg = QButtonGroup()

    def set_widgets(self):
        color_label(self.title, QColor("black"), QColor("white"))
        color_button(self.set1, QColor(255, 0, 0))
        color_button(self.set5, QColor(255, 0, 0))
        color_button(self.set6, QColor(255, 0, 0))
        color_button(self.set7, QColor(255, 0, 0))
        color_button(self.set8, QColor(255, 0, 0))
        color_button(self.shwA, QColor(255, 255, 0))
        color_button(self.shwS, QColor(255, 255, 0))
        color_button(self.shwN, QColor(255, 255, 0))
        color_button(self.clr, QColor(255, 0, 0))

    def layout_widgets(self):
        self.addWidget(self.title, 0, 0, 1, 8)
        self.addWidget(self.shwA, 1, 0)
        self.addWidget(self.shwS, 1, 1)
        self.addWidget(self.shwN, 1, 2)

        self.addWidget(self.set1, 2, 0)
        self.addWidget(self.set5, 2, 1)
        self.addWidget(self.set6, 2, 2)
        self.addWidget(self.set7, 2, 3)
        self.addWidget(self.set8, 2, 4)
        self.addWidget(self.clr, 2, 7)
        self.addWidget(QLabel("use"), 3, 0)
        self.addWidget(QLabel("show"), 3, 1)
        self.addWidget(QLabel("new"), 3, 2)
        self.addWidget(QLabel("old"), 3, 3)
        self.addWidget(QLabel("pixs"), 3, 4)
        self.addWidget(QLabel("RGB"), 3, 5)
        self.addWidget(QLabel("HSV"), 3, 6)

    def create_connections(self):
        self.set1.clicked.connect(self.gen1)
        self.set5.clicked.connect(self.gen5)
        self.set6.clicked.connect(self.gen6)
        self.set7.clicked.connect(self.gen7)
        self.set8.clicked.connect(self.gen8)
        self.clr.clicked.connect(self.clr_table)
        self.shwA.clicked.connect(self.show_all)
        self.shwS.clicked.connect(self.show_selected)
        self.shwN.clicked.connect(self.show_none)

    def clr_table(self):
        if self.table:
            for k, v in self.table.items():
                if k[1] == "act":
                    self.bg.removeButton(v)
                if k[1] not in ("att", "col", "idx"):
                    v.hide()
                    v.destroy()

            self.table = {}
            self.tableUpdate.emit(0)
            self.newrow = 0

    def gen1(self):
        if self.table != {}:
            return
        for i in range(1, 2):
            self.add_att(i)
        self.add_ex()
        self.table[(0, "sel")].setChecked(True)
        self.tableUpdate.emit(1)

    def gen5(self):
        if self.table != {}:
            return
        for i in range(11, 16):
            self.add_att(i)
        self.add_ex()
        self.table[(0, "sel")].setChecked(True)
        self.tableUpdate.emit(5)

    def gen6(self):
        if self.table != {}:
            return
        for i in range(31, 37):
            self.add_att(i)
        self.add_ex()
        self.table[(0, "sel")].setChecked(True)
        self.tableUpdate.emit(6)

    def gen7(self):
        if self.table != {}:
            return
        for i in range(21, 28):
            self.add_att(i)
        self.add_ex()
        self.table[(0, "sel")].setChecked(True)
        self.tableUpdate.emit(7)

    def gen8(self):
        if self.table != {}:
            return
        for i in range(41, 49):
            self.add_att(i)
        self.add_ex()
        self.table[(0, "sel")].setChecked(True)
        self.tableUpdate.emit(8)

    def add_ex(self):
        self.add_att(99)

    def add_att(self, i):
        off = 4
        idx = self.newrow
        self.newrow += 1

        att = self._code[i]
        self.table[(idx, "idx")] = i
        self.table[(idx, "att")] = att
        self.table[(idx, "col")] = self._color[i]
        self.table[(idx, "sel")] = QRadioButton()
        self.table[(idx, "act")] = QCheckBox()
        self.table[(idx, "pix")] = QLabel("0")
        self.table[(idx, "new")] = QPushButton(att)
        self.table[(idx, "old")] = QPushButton(att)
        self.table[(idx, "rgb")] = QLabel()
        self.table[(idx, "hsv")] = QLabel()
        self.table[(idx, "hsl")] = QLabel()

        self.bg.addButton(self.table[(idx, "sel")], i)
        color_button(self.table[(idx, "new")], self.table[(idx, "col")])

        self.addWidget(self.table[(idx, "sel")], idx + off, 0)
        self.addWidget(self.table[(idx, "act")], idx + off, 1)
        self.addWidget(self.table[(idx, "new")], idx + off, 2)
        self.addWidget(self.table[(idx, "old")], idx + off, 3)
        self.addWidget(self.table[(idx, "pix")], idx + off, 4)
        self.addWidget(self.table[(idx, "rgb")], idx + off, 5)
        self.addWidget(self.table[(idx, "hsv")], idx + off, 6)

        self.table[(idx,
                    "new")].clicked.connect(lambda: self.button_color1(idx))
        self.table[(idx,
                    "old")].clicked.connect(lambda: self.button_color2(idx))
        self.table[(idx, "act")].clicked.connect(self.selUpdate.emit)
        self.table[(idx, "sel")].clicked.connect(self.useUpdate.emit)
        print("ADDATT", i)

    def set_old_col(self, idx, col):
        color_button(self.table[(idx, "old")], col)
        self.table[(idx, "rgb")].setText(str(col.getRgb()[:3]))
        self.table[(idx, "hsv")].setText(str(col.getHsv()[:3]))

    def select_color(self, idx, col=None, auto=False):
        if not col:
            forbidden = {
                self.table[i, "col"].getRgb()[:3]
                for i in range(self.newrow)
            }
            col = get_color(auto=auto, forbidden=forbidden)
            if col is None:
                return
        self.table[(idx, "col")] = col
        color_button(self.table[idx, "new"], col)
        self.colUpdate.emit(idx)

    def button_color1(self, idx):
        self.select_color(idx)

    def button_color2(self, idx):
        self.random_color(idx)

    def random_color(self, idx, col=None):
        self.select_color(idx, auto=True)

    def show_all(self):
        for idx in range(self.newrow):
            if self.table[(idx, "idx")] < 99:
                self.table[(idx, "act")].setChecked(True)
        self.selUpdate.emit()

    def show_selected(self):
        for idx in range(self.newrow):
            self.table[(idx,
                        "act")].setChecked(self.table[(idx,
                                                       "sel")].isChecked())
        self.selUpdate.emit()

    def show_none(self):
        for idx in range(self.newrow):
            self.table[(idx, "act")].setChecked(False)
        self.selUpdate.emit()

    def selected(self):
        try:
            return self.bg.checkedId()
        except:
            return None

    def select(self, att):
        for idx in range(self.newrow):
            if self.table[(idx, "idx")] == att:
                self.table[(idx, "sel")].setChecked(True)

    def next_att(self):
        for i in range(self.newrow - 1):
            if self.table[i, "sel"].isChecked():
                self.table[i + 1, "sel"].setChecked(True)
                break
        else:
            if self.table:
                self.table[0, "sel"].setChecked(True)
Beispiel #8
0
class TabBarWidget(QWidget):
    """
    A vertical tab bar widget using tool buttons as for tabs.
    """

    currentChanged = Signal(int)

    def __init__(self, parent=None, **kwargs):
        QWidget.__init__(self, parent, **kwargs)
        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        self.setLayout(layout)

        self.setSizePolicy(QSizePolicy.Fixed,
                           QSizePolicy.Expanding)
        self.__tabs = []

        self.__currentIndex = -1
        self.__changeOnHover = False

        self.__iconSize = QSize(26, 26)

        self.__group = QButtonGroup(self, exclusive=True)
        self.__group.buttonPressed[QAbstractButton].connect(
            self.__onButtonPressed
        )
        self.setMouseTracking(True)

        self.__sloppyButton = None
        self.__sloppyRegion = QRegion()
        self.__sloppyTimer = QTimer(self, singleShot=True)
        self.__sloppyTimer.timeout.connect(self.__onSloppyTimeout)

    def setChangeOnHover(self, changeOnHover):
        """
        If set to ``True`` the tab widget will change the current index when
        the mouse hovers over a tab button.

        """
        if self.__changeOnHover != changeOnHover:
            self.__changeOnHover = changeOnHover

    def changeOnHover(self):
        """
        Does the current tab index follow the mouse cursor.
        """
        return self.__changeOnHover

    def count(self):
        """
        Return the number of tabs in the widget.
        """
        return len(self.__tabs)

    def addTab(self, text, icon=None, toolTip=None):
        """
        Add a new tab and return it's index.
        """
        return self.insertTab(self.count(), text, icon, toolTip)

    def insertTab(self, index, text, icon=None, toolTip=None):
        """
        Insert a tab at `index`
        """
        button = TabButton(self, objectName="tab-button")
        button.setSizePolicy(QSizePolicy.Expanding,
                             QSizePolicy.Expanding)
        button.setIconSize(self.__iconSize)
        button.setMouseTracking(True)

        self.__group.addButton(button)

        button.installEventFilter(self)

        tab = _Tab(text, icon, toolTip, button, None, None)
        self.layout().insertWidget(index, button)

        self.__tabs.insert(index, tab)
        self.__updateTab(index)

        if self.currentIndex() == -1:
            self.setCurrentIndex(0)
        return index

    def removeTab(self, index):
        """
        Remove a tab at `index`.
        """
        if index >= 0 and index < self.count():
            tab = self.__tabs.pop(index)
            layout_index = self.layout().indexOf(tab.button)
            if layout_index != -1:
                self.layout().takeAt(layout_index)

            self.__group.removeButton(tab.button)

            tab.button.removeEventFilter(self)

            if tab.button is self.__sloppyButton:
                self.__sloppyButton = None
                self.__sloppyRegion = QRegion()

            tab.button.deleteLater()
            tab.button.setParent(None)

            if self.currentIndex() == index:
                if self.count():
                    self.setCurrentIndex(max(index - 1, 0))
                else:
                    self.setCurrentIndex(-1)

    def setTabIcon(self, index, icon):
        """
        Set the `icon` for tab at `index`.
        """
        self.__tabs[index] = self.__tabs[index]._replace(icon=icon)
        self.__updateTab(index)

    def setTabToolTip(self, index, toolTip):
        """
        Set `toolTip` for tab at `index`.
        """
        self.__tabs[index] = self.__tabs[index]._replace(toolTip=toolTip)
        self.__updateTab(index)

    def setTabText(self, index, text):
        """
        Set tab `text` for tab at `index`
        """
        self.__tabs[index] = self.__tabs[index]._replace(text=text)
        self.__updateTab(index)

    def setTabPalette(self, index, palette):
        """
        Set the tab button palette.
        """
        self.__tabs[index] = self.__tabs[index]._replace(palette=palette)
        self.__updateTab(index)

    def setCurrentIndex(self, index):
        """
        Set the current tab index.
        """
        if self.__currentIndex != index:
            self.__currentIndex = index

            self.__sloppyRegion = QRegion()
            self.__sloppyButton = None

            if index != -1:
                self.__tabs[index].button.setChecked(True)

            self.currentChanged.emit(index)

    def currentIndex(self):
        """
        Return the current index.
        """
        return self.__currentIndex

    def button(self, index):
        """
        Return the `TabButton` instance for index.
        """
        return self.__tabs[index].button

    def setIconSize(self, size):
        if self.__iconSize != size:
            self.__iconSize = size
            for tab in self.__tabs:
                tab.button.setIconSize(self.__iconSize)

    def __updateTab(self, index):
        """
        Update the tab button.
        """
        tab = self.__tabs[index]
        b = tab.button

        if tab.text:
            b.setText(tab.text)

        if tab.icon is not None and not tab.icon.isNull():
            b.setIcon(tab.icon)

        if tab.palette:
            b.setPalette(tab.palette)

    def __onButtonPressed(self, button):
        for i, tab in enumerate(self.__tabs):
            if tab.button is button:
                self.setCurrentIndex(i)
                break

    def __calcSloppyRegion(self, current):
        """
        Given a current mouse cursor position return a region of the widget
        where hover/move events should change the current tab only on a
        timeout.

        """
        p1 = current + QPoint(0, 2)
        p2 = current + QPoint(0, -2)
        p3 = self.pos() + QPoint(self.width()+10, 0)
        p4 = self.pos() + QPoint(self.width()+10, self.height())
        return QRegion(QPolygon([p1, p2, p3, p4]))

    def __setSloppyButton(self, button):
        """
        Set the current sloppy button (a tab button inside sloppy region)
        and reset the sloppy timeout.

        """
        if not button.isChecked():
            self.__sloppyButton = button
            delay = self.style().styleHint(QStyle.SH_Menu_SubMenuPopupDelay, None)
            # The delay timeout is the same as used by Qt in the QMenu.
            self.__sloppyTimer.start(delay)
        else:
            self.__sloppyTimer.stop()

    def __onSloppyTimeout(self):
        if self.__sloppyButton is not None:
            button = self.__sloppyButton
            self.__sloppyButton = None
            if not button.isChecked():
                index = [tab.button for tab in self.__tabs].index(button)
                self.setCurrentIndex(index)

    def eventFilter(self, receiver, event):
        if event.type() == QEvent.MouseMove and \
                isinstance(receiver, TabButton):
            pos = receiver.mapTo(self, event.pos())
            if self.__sloppyRegion.contains(pos):
                self.__setSloppyButton(receiver)
            else:
                if not receiver.isChecked():
                    index = [tab.button for tab in self.__tabs].index(receiver)
                    self.setCurrentIndex(index)
                #also update sloppy region if mouse is moved on the same icon
                self.__sloppyRegion = self.__calcSloppyRegion(pos)

        return QWidget.eventFilter(self, receiver, event)

    def leaveEvent(self, event):
        self.__sloppyButton = None
        self.__sloppyRegion = QRegion()

        return QWidget.leaveEvent(self, event)
Beispiel #9
0
class SAFTVRMieParametersWidget(ParametersWidget):
    """
    Widget for changing interaction coefficients and pure fluid parameters for the SAFT-VR Mie model
    """

    def __init__(self, data, settings_name, parent=None):
        super().__init__(data, settings_name, parent)
        loadUi("gui/layouts/saftvrmie_parameters.ui", self)
        self.tab_stack_indices = {}
        self.list_name = None
        self.component_id = None

        self.pure_param_m_label.setText("m:")
        self.pure_param_sigma_label.setText("\u03C3:")
        self.pure_param_epsilon_label.setText("\u03B5 / k:")
        self.pure_param_lambda_a_label.setText("\u03BB a:")
        self.pure_param_lambda_r_label.setText("\u03BB r:")

        # Validators for input
        self.float_validator = FloatValidator()
        self.set_validators()

        self.pure_param_m_edit.editingFinished.connect(self.save_pure_fluid_params)
        self.pure_param_sigma_edit.editingFinished.connect(self.save_pure_fluid_params)
        self.pure_param_epsilon_edit.editingFinished.connect(self.save_pure_fluid_params)
        self.pure_param_lambda_a_edit.editingFinished.connect(self.save_pure_fluid_params)
        self.pure_param_lambda_r_edit.editingFinished.connect(self.save_pure_fluid_params)

        self.component_btngroup = QButtonGroup()
        self.component_btngroup.buttonClicked.connect(self.show_component_pure_params)

        self.pure_params_frame.hide()

        self.composition_list.currentItemChanged.connect(self.on_chosen_composition_list)

    def init_widget(self, data, settings_name):
        """
        Populates the list with the available compositions, calculates interaction parameters, and creates a table
        to display the matrix
        :param data: Session data
        :param settings_name: Name of the current model setup
        :return:
        """
        self.settings = data["Model setups"][settings_name]
        self.thermopack = get_thermopack(category=self.settings["Model category"])

        list_names = []
        for i in range(self.composition_list.count()):
            list_names.append(self.composition_list.item(i).text())

        for list_name in self.component_lists.keys():

            if list_name in self.settings["Parameters"].keys():
                if "Pure fluid parameters" not in self.settings["Parameters"][list_name].keys():
                    self.settings["Parameters"][list_name]["Pure fluid parameters"] = {}

            else:
                self.settings["Parameters"][list_name] = {
                    "Coefficient matrices": {},
                    "Pure fluid parameters": {}
                }

            existing_matrices = self.settings["Parameters"][list_name]["Coefficient matrices"].keys()

            if "SAFT-VR Mie Epsilon" not in existing_matrices:
                # Create one tab for each list in QTabWidget
                self.calculate_matrix_data(list_name)

            self.epsilon_table = self.get_table(list_name, "SAFT-VR Mie Epsilon")
            self.sigma_table = self.get_table(list_name, "SAFT-VR Mie Sigma")
            self.gamma_table = self.get_table(list_name, "SAFT-VR Mie Gamma")

            self.epsilon_table.itemChanged.connect(
                lambda item: self.change_coeff(item, "SAFT-VR Mie Epsilon"))
            self.sigma_table.itemChanged.connect(
                lambda item: self.change_coeff(item, "SAFT-VR Mie Sigma"))
            self.gamma_table.itemChanged.connect(
                lambda item: self.change_coeff(item, "SAFT-VR Mie Gamma"))

            tab_widget = SAFTVRMieTabWidget(self.epsilon_table, self.sigma_table, self.gamma_table)

            if list_name not in self.tab_stack_indices.keys():
                index = self.tab_stack.addWidget(tab_widget)
                self.tab_stack_indices[list_name] = index

        self.init_composition_list()
        self.tab_stack.setCurrentIndex(0)
        self.pure_params_frame.hide()
        for button in self.component_btngroup.buttons():
            self.component_btngroup.removeButton(button)
            self.component_btn_layout.removeWidget(button)
            button.hide()

    def set_validators(self):
        """
        Sets a validator for input fields to ensure a valid float input
        """
        self.pure_param_m_edit.setValidator(self.float_validator)
        self.pure_param_sigma_edit.setValidator(self.float_validator)
        self.pure_param_epsilon_edit.setValidator(self.float_validator)
        self.pure_param_lambda_a_edit.setValidator(self.float_validator)
        self.pure_param_lambda_r_edit.setValidator(self.float_validator)

    def save_pure_fluid_params(self):
        """
        Saves the current pure fluid parameters to the session data
        """
        if not self.list_name or not self.component_id:
            return

        m = float(self.pure_param_m_edit.text())
        sigma = float(self.pure_param_sigma_edit.text())
        epsilon = float(self.pure_param_epsilon_edit.text())
        lambda_a = float(self.pure_param_lambda_a_edit.text())
        lambda_r = float(self.pure_param_lambda_r_edit.text())

        fluid_params = self.settings["Parameters"][self.list_name]["Pure fluid parameters"][self.component_id]
        fluid_params["M"] = m
        fluid_params["Sigma"] = sigma
        fluid_params["Epsilon"] = epsilon
        fluid_params["Lambda a"] = lambda_a
        fluid_params["Lambda r"] = lambda_r

    def show_component_pure_params(self, button):
        """
        When a component is chosen, the corresponding pure fluid parameters are displayed
        :param button: Clicked radio button giving the chosen component
        """
        comp_name = button.text()
        list_name = self.composition_list.currentItem().text()

        self.pure_params_frame.show()

        init_thermopack(self.thermopack, self.component_lists[list_name], list_name, self.settings)

        self.component_id = get_comp_id(self.component_lists[list_name], comp_name)
        comp_index = self.thermopack.getcompindex(self.component_id)

        m, sigma, eps_div_k, lambda_a, lambda_r = self.thermopack.get_pure_fluid_param(comp_index)

        self.pure_param_m_edit.setText(str(m))
        self.pure_param_sigma_edit.setText(str(sigma))
        self.pure_param_epsilon_edit.setText(str(eps_div_k))
        self.pure_param_lambda_a_edit.setText(str(lambda_a))
        self.pure_param_lambda_r_edit.setText(str(lambda_r))

    def calculate_matrix_data(self, list_name):
        """
        Calculates binary coefficients for all composition lists and stores them in the session data.
        :param list_name: str, Name of component list
        """
        component_list = self.component_lists[list_name]["Names"]
        size = len(component_list)
        epsilon_matrix_data = np.zeros(shape=(size, size))
        sigma_matrix_data = np.zeros(shape=(size, size))
        gamma_matrix_data = np.zeros(shape=(size, size))

        init_thermopack(self.thermopack, self.component_lists[list_name], list_name, self.settings)

        for row in range(size - 1):
            for col in range(row + 1, size):
                identity1 = self.component_lists[list_name]["Identities"][row]
                identity2 = self.component_lists[list_name]["Identities"][col]
                index1 = self.thermopack.getcompindex(identity1)
                index2 = self.thermopack.getcompindex(identity2)

                epsilon_kij = self.thermopack.get_eps_kij(index1, index2)
                sigma_lij = self.thermopack.get_sigma_lij(index1, index2)
                lr_gammaij = self.thermopack.get_lr_gammaij(index1, index2)

                # Symmetric matrices
                epsilon_matrix_data[row][col] = epsilon_kij
                epsilon_matrix_data[col][row] = epsilon_kij
                sigma_matrix_data[row][col] = sigma_lij
                sigma_matrix_data[col][row] = sigma_lij
                gamma_matrix_data[row][col] = lr_gammaij
                gamma_matrix_data[col][row] = lr_gammaij

        for row in range(size):
            epsilon_matrix_data[row][row] = 0.0
            sigma_matrix_data[row][row] = 0.0
            gamma_matrix_data[row][row] = 0.0

        epsilon_matrix_data = epsilon_matrix_data.tolist()
        sigma_matrix_data = sigma_matrix_data.tolist()
        gamma_matrix_data = gamma_matrix_data.tolist()

        coeff_matrices = self.settings["Parameters"][list_name]["Coefficient matrices"]

        coeff_matrices["SAFT-VR Mie Epsilon"] = epsilon_matrix_data
        coeff_matrices["SAFT-VR Mie Sigma"] = sigma_matrix_data
        coeff_matrices["SAFT-VR Mie Gamma"] = gamma_matrix_data

    def on_chosen_composition_list(self, list_item):
        """
        Show the correct tab with interaction coefficient matrices, and display radio buttons with all components
        in the given composition.
        :param list_item: Chosen composition
        """
        self.list_name = list_item.text()
        if not self.list_name:
            return
        index = self.tab_stack_indices[self.list_name]
        self.tab_stack.setCurrentIndex(index)

        self.pure_params_frame.hide()

        component_list = self.component_lists[self.list_name]["Names"]

        for button in self.component_btngroup.buttons():
            self.component_btngroup.removeButton(button)
            self.component_btn_layout.removeWidget(button)
            button.hide()

        if "Pure fluid parameters" not in self.settings["Parameters"][self.list_name].keys():
            self.settings["Parameters"][self.list_name]["Pure fluid parameters"] = {}

        pure_fluid_params = self.settings["Parameters"][self.list_name]["Pure fluid parameters"]

        for comp_name in component_list:
            comp_id = get_comp_id(self.component_lists[self.list_name], comp_name)

            if comp_id not in pure_fluid_params.keys():
                pure_fluid_params[comp_id] = {
                    "M": None,
                    "Sigma": None,
                    "Epsilon": None,
                    "Lambda a": None,
                    "Lambda r": None
                }

            button = QRadioButton(comp_name)
            self.component_btngroup.addButton(button)
            self.component_btn_layout.addWidget(button)

    def change_coeff(self, item, table_name):
        """
        Changes a value (interaction coefficient) in the given table
        :param item: New value
        :param table_name: Name of coefficient matrix (VDW K, HV1 A, SAFT-VR Mie Sigma, ...)
        """
        row, col = item.row(), item.column()
        component_list = self.composition_list.currentItem().text()
        matrix = self.settings["Parameters"][component_list]["Coefficient matrices"][table_name]

        try:
            value = float(item.text().replace(",", "."))
        except ValueError:
            previous_value = matrix[row][col]
            item.setText(str(previous_value))
            return

        matrix[row][col] = value
        matrix[col][row] = value
        item.tableWidget().item(col, row).setText(str(value))