class statusWidget(QWidget): def __init__(self): super(statusWidget,self).__init__() self.initUI() def initUI(self): self.green = QColor(0, 128, 0) self.red = QColor(128,0,0) self.setMinimumSize(100,200) lbl1 = QLabel('Pump',self) lbl1.move(10,0) lbl2 = QLabel('Valve', self) lbl2.move(10, 85) lbl3 = QLabel('Status 3', self) lbl3.move(10, 170) self.square1 = QFrame(self) self.square1.setGeometry(10,20,60,60) self.square1.setStyleSheet("QWidget { background-color: %s }" % self.green.name()) self.square2 = QFrame(self) self.square2.setGeometry(10,105,60,60) self.square2.setStyleSheet("QWidget { background-color: %s }" % self.red.name()) self.square3 = QFrame(self) self.square3.setGeometry(10,190,60,60) self.square3.setStyleSheet("QWidget { background-color: %s }" % self.red.name())
class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.col = QColor(0, 0, 0) redb = QPushButton('Red', self) redb.setCheckable(True) redb.move(10, 10) redb.clicked[bool].connect(self.setColor) redb = QPushButton('Green', self) redb.setCheckable(True) redb.move(10, 60) redb.clicked[bool].connect(self.setColor) blueb = QPushButton('Blue', self) blueb.setCheckable(True) blueb.move(10, 110) blueb.clicked[bool].connect(self.setColor) self.square = QFrame(self) self.square.setGeometry(150, 20, 100, 100) self.square.setStyleSheet("QWidget { background-color: %s }" % self.col.name()) self.setGeometry(300, 300, 280, 170) self.setWindowTitle('Toggle button') self.show() def setColor(self, pressed): source = self.sender() if pressed: val = 255 else: val = 0 if source.text() == "Red": self.col.setRed(val) elif source.text() == "Green": self.col.setGreen(val) else: self.col.setBlue(val) self.square.setStyleSheet("QFrame { background-color: %s }" % self.col.name())
def checkStatus(self): # Update Recir Status Light if self.lifeSupport.get_circ_status: color = QColor(0,124,0) else: color = QColor(124,0,0) self.status.square2.setStyleSheet("QWidget { background-color: %s }" % color.name()) # Update Pump Status light if self.lifeSupport.get_pump_status: color = QColor(0,124,0) else: color = QColor(124,0,0) self.status.square1.setStyleSheet("QWidget { background-color: %s }" % color.name())
def colorValue(self, key, default = QColor()): if type(default) != QColor: default = QColor(default) name = self.mSettings.value(key, default.name()) if (not QColor.isValidColor(name)): return QColor() return QColor(name)
def makeMap(self, width, height, n): ''' Generates the graphical map, from the game's map. Sets events and connects signals for the territories. ''' for i in range(n): self.coords.append([]) for j in range(n): ter_square = TerritorySquare(self, self.game.map.map[i][j]) self.coords[i].append(ter_square) square = self.coords[i][j] square.mouseReleaseEvent = self.showTerritoryDialog square.incomeChanged.emit(square.ter.get_income()) square.marketUpgr.emit(square.ter.buildings.market_lvl) square.fortUpgr.emit(square.ter.buildings.fort_lvl) x = 110 + i * (width + 1) y = 60 + j * (height + 1) square.setGeometry(x, y, width, height) if square.ter.owner: color = QColor(*square.ter.owner.color) else: color = QColor(127, 127, 127) bgcolor = "QWidget { background-color: %s }" square.setStyleSheet(bgcolor % color.name()) square.calcCenter()
def start_GUI(self): frm = QFrame(self) col = QColor(0, 0, 0) frm.setStyleSheet("QWidget { background-color: %s }" % col.name()) frm.setGeometry(0, 0, 800, 800) frm.show() self.gui_choise_server_client()
class QColorButton(QPushButton): colorChanged = pyqtSignal() def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._color = QColor(255, 0, 0) self._apply_color() self.clicked.connect(self.onColorPicker) def _apply_color(self): pixmap = QPixmap(16, 16) QPainter(pixmap).fillRect(0, 0, 16, 16, self._color) self.setIcon(QIcon(pixmap)) self.setText(self._color.name()) def set_color(self, color): if color != self._color: self._color = color self.colorChanged.emit() self._apply_color() def color(self): return self._color def onColorPicker(self): dialog = QColorDialog() dialog.setCurrentColor(self._color) if dialog.exec_(): self.set_color(dialog.currentColor())
def initUI(self): col = QColor(10, 10, 100) self.btn1 = QPushButton('Color Dialog', self) self.btn1.move(20, 20) self.btn1.clicked.connect(self.showColorDialog) self.frm = QFrame(self) self.frm.setStyleSheet('QWidget {background-color: %s }' % col.name()) self.frm.setGeometry(130, 20, 100, 20) self.btn = QPushButton('input Dialog', self) self.btn.move(20, 50) self.btn.clicked.connect(self.showInputDialog) self.le = QLineEdit(self) self.le.move(130, 50) # vbox = QVBoxLayout() btn3 = QPushButton('Font Dialog', self) # btn3.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) btn3.move(20, 80) # vbox.addWidget(btn3) btn3.clicked.connect(self.showFontDialog) self.lbl = QLabel('Knowledge only matters', self) self.lbl.move(110, 80) # vbox.addWidget(self.lbl) # self.setLayout(vbox) self.setGeometry(300, 300, 290, 150) self.setWindowTitle(' Dialog') self.show()
def setCorkColor(self): color = QColor(settings.corkBackground["color"]) self.colorDialog = QColorDialog(color, self) color = self.colorDialog.getColor(color) if color.isValid(): settings.corkBackground["color"] = color.name() self.updateCorkColor() # Update Cork view self.mw.mainEditor.updateCorkBackground()
def colorSelectionSlot(self, color: QColor): column = COLOR_COL color_name = color.name() for item in self.selectedItems(): if isinstance(item, (OutlineVirtualHelixItem, OutlineOligoItem)): item.setData(column, Qt.EditRole, color_name) # print("coloring", item.__class__.__name__, item.idNum()) else: print("item uncolorable", item.__class__.__name__)
def initUI(self): col = QColor(0, 0, 0) self.btn = QPushButton('Dialog', self) self.btn.move(20, 20) self.btn.clicked.connect(self.showDialog) self.frm = QFrame(self) self.frm.setStyleSheet("QWidget {background-color:%s}" % col.name()) self.frm.setGeometry(130, 22, 100, 100) self.setGeometry(300, 300, 250, 180) self.setWindowTitle('Color dialog') self.show()
def setData(self, index, value, role=Qt.EditRole): if role == Qt.EditRole and index.column() == self.ColumnID.Color: row = index.row() brushColor = QColor(value[0]) pmapColor = QColor(value[1]) if brushColor.isValid() and pmapColor.isValid(): logger.debug("setData: brushColor = {}, pmapColor = {}" "".format(brushColor.name(), pmapColor.name())) logger.debug(" self._elements[row] has type {}" "".format(type(self._elements[row]))) self._elements[row].setBrushColor(brushColor) self._elements[row].setPmapColor(pmapColor) logger.debug(" self._elements[row].brushColor = {}" "".format(self._elements[row].brushColor().name())) logger.debug(" self._elements[row].pmapColor = {}" "".format(self._elements[row].pmapColor().name())) self.dataChanged.emit(index, index) return True else: return ListModel.setData(self, index, value, role)
def createIntersectionPoint(self): # TODO self.plotLength = self.model.projectData("length") * LENGTH_COEFFICIENT # create the horizontal plant line green = QColor(0, 144, 54) plantPen = pyqtgraph.mkPen(width=2, color=green) # Hochschule für Forstwirtschaft Rottenburg self.plantLine = InfiniteLine(self.model.projectData("count"), 0, plantPen, True) self.plantLine.sigPositionChanged.connect(self.updateCount) self.controlWidget.setCount(self.model.projectData("count")) self.controlWidget.countChanged.connect(self.plantLine.setValue) self.plantLabel = TextItem(html="<b><font color='" + green.name() + "'>Pflanzenzahl</font></b>", anchor=(-0.15, 0.9)) self.plantLabel.setParentItem(self.plantLine) self.plotWidget.addPlotItem(self.plantLine) # create the vertical fence line red = QColor(255, 0, 0) fencePen = pyqtgraph.mkPen(width=2, color=red) self.fenceLine = InfiniteLine(self.model.projectData("length"), 90, fencePen, True) self.fenceLine.sigPositionChanged.connect(self.updateLength) self.fenceLine.sigPositionChangeFinished.connect(self.updatePlotLength) self.controlWidget.setLength(self.model.projectData("length")) self.controlWidget.lengthChanged.connect(self.fenceLine.setValue) self.fenceLabel = TextItem(html="<b><font color='" + red.name() + "'>Zaunlänge</font></b>", anchor=(-2.5, 0.9), angle=-90) self.fenceLabel.setParentItem(self.fenceLine) self.plotWidget.addPlotItem(self.fenceLine) # create an arrow item as point of intersection self.arrowItem = ArrowItem(angle=-45, tipAngle=30, baseAngle=20, headLen=20, tailLen=None, pen={"color" : "#333", "width" : 2}, brush=QColor(255, 123, 0)) self.arrowItem.setPos(self.model.projectData("length"), self.model.projectData("count")) self.plotWidget.addPlotItem(self.arrowItem)
def __init__(self ): super().__init__() color = QColor(0, 0, 0) self.setGeometry(300, 300, 350, 280) self.setWindowTitle('颜色选择') self.button = QPushButton('Dialog', self) self.button.setFocusPolicy(Qt.NoFocus) self.button.move(20, 20) self.button.clicked.connect(self.showDialog) self.setFocus() self.widget = QWidget(self) self.widget.setStyleSheet('QWidget{background-color:%s} '%color.name()) self.widget.setGeometry(130, 22, 100, 100)
class ColorLine(QFrame): """Acquires a new plant protection variant for the cost calculation. The dialog contains two input fields to acquire a new plant protection variant. First there is a input field for the name of the new variant. The second input field asks about the used plant protection. The user cannot change the variant type at a later time. This class has no attributes or return values. """ colorChanged = pyqtSignal(QModelIndex, QColor) def __init__(self, index): """The constructor initializes the class NewVariantDialog.""" super().__init__(frameShadow=QFrame.Plain, frameShape=QFrame.HLine, lineWidth=3) self._farbe = QColor() self.index = index self.setFixedSize(25, 18) self.setContentsMargins(0, 0, 0, 0) self.palette = self.palette() self.palette.setColor(QPalette.Foreground, self._farbe) self.setPalette(self.palette) def mousePressEvent(self, event): self._farbe = QColorDialog().getColor() self.palette.setColor(QPalette.Foreground, self._farbe) self.setPalette(self.palette) self.colorChanged.emit(self.index, self._farbe) @pyqtProperty(str) def farbeDef(self): return self._farbe.name() @farbeDef.setter def farbeDef(self, value): self._farbe = QColor(value) self.palette.setColor(QPalette.Foreground, self._farbe) self.setPalette(self.palette)
class RSBGDocker(DockWidget): def __init__(self): super().__init__() self.setWindowTitle("Rogudator's speech bubble generator") mainLayout = QVBoxLayout() self.addOnPage = QPushButton("Add on Page") mainLayout.addWidget(self.addOnPage) previewLabel = QLabel("Preview") mainLayout.addWidget(previewLabel) self.preview = QSvgWidget(self) self.preview.setMinimumHeight(200) #self.preview.setAspectRatioMode(Qt.AspectRatioMode.KeepAspectRatio) mainLayout.addWidget(self.preview) bubbleTypes = QGroupBox() bubbleTypes.setTitle("Bubble type") bubbleTypesLayout = QHBoxLayout() self.squareBubble = QRadioButton(self) self.squareBubble.setText("Square") bubbleTypesLayout.addWidget(self.squareBubble) self.roundBubble = QRadioButton(self) self.roundBubble.setText("Round") self.roundBubble.setChecked(True) bubbleTypesLayout.addWidget(self.roundBubble) bubbleTypes.setLayout(bubbleTypesLayout) self.bubbleColorButton = QPushButton(self) self.bubbleColor = QColor("white") bubbleColorImage = QPixmap(32, 32) bubbleColorImage.fill(self.bubbleColor) bubbleColorIcon = QIcon(bubbleColorImage) self.bubbleColorButton.setIcon(bubbleColorIcon) self.bubbleColorButton.setFixedWidth(self.bubbleColorButton.height()) bubbleTypesLayout.addWidget(self.bubbleColorButton) mainLayout.addWidget(bubbleTypes) outlineSize = QGroupBox("Outline") outlineSliderAndSpinBox = QHBoxLayout() self.outlineSlider = QSlider(self) self.outlineSlider.setMinimum(0) self.outlineSlider.setMaximum(10) self.outlineSlider.setValue(3) self.outlineSlider.setOrientation(Qt.Orientation.Horizontal) outlineSliderAndSpinBox.addWidget(self.outlineSlider) self.outlineSpinBox = QSpinBox(self) self.outlineSpinBox.setMinimum(0) self.outlineSpinBox.setValue(3) outlineSliderAndSpinBox.addWidget(self.outlineSpinBox) self.outlineColorButton = QPushButton(self) self.outlineColor = QColor("black") outlineColorImage = QPixmap(32, 32) outlineColorImage.fill(self.outlineColor) outlineColorIcon = QIcon(outlineColorImage) self.outlineColorButton.setIcon(outlineColorIcon) self.outlineColorButton.setFixedWidth(self.outlineColorButton.height()) outlineSliderAndSpinBox.addWidget(self.outlineColorButton) outlineSize.setLayout(outlineSliderAndSpinBox) mainLayout.addWidget(outlineSize) speechGroup = QGroupBox("Speech") speechGroupLayout = QVBoxLayout() fontRow = QHBoxLayout() self.speechFont = QFontComboBox(self) fontRow.addWidget(self.speechFont) self.speechFontSize = QSpinBox(self) self.speechFontSize.setValue(14) self.speechFontSize.setMinimum(1) fontRow.addWidget(self.speechFontSize) self.currentFontColorButton = QPushButton(self) self.speechFontColor = QColor("black") fontColorImage = QPixmap(32, 32) fontColorImage.fill(self.speechFontColor) fontColorIcon = QIcon(fontColorImage) self.currentFontColorButton.setIcon(fontColorIcon) self.currentFontColorButton.setFixedWidth( self.currentFontColorButton.height()) fontRow.addWidget(self.currentFontColorButton) speechGroupLayout.addLayout(fontRow) self.bubbleText = QTextEdit("Rogudator's speech bubble generator!") speechGroupLayout.addWidget(self.bubbleText) self.autocenter = QCheckBox(self) self.autocenter.setText("Center automatically") self.autocenter.setChecked(True) speechGroupLayout.addWidget(self.autocenter) self.averageLineLength = QGroupBox() averageLineLengthSliderAndSpinBox = QHBoxLayout() self.averageLineLengthSlider = QSlider(self) self.averageLineLengthSlider.setMinimum(0) self.averageLineLengthSlider.setMaximum(100) self.averageLineLengthSlider.setOrientation(Qt.Orientation.Horizontal) averageLineLengthSliderAndSpinBox.addWidget( self.averageLineLengthSlider) self.averageLineLengthSpinBox = QSpinBox(self) self.averageLineLengthSpinBox.setMinimum(0) averageLineLengthSliderAndSpinBox.addWidget( self.averageLineLengthSpinBox) self.averageLineLength.setLayout(averageLineLengthSliderAndSpinBox) self.averageLineLength.setDisabled(True) speechGroupLayout.addWidget(self.averageLineLength) speechGroup.setLayout(speechGroupLayout) mainLayout.addWidget(speechGroup) tailSize = QGroupBox() tailSize.setTitle("Tail size") tailSliderAndSpinBox = QHBoxLayout() self.tailSlider = QSlider(self) self.tailSlider.setMinimum(0) self.tailSlider.setMaximum(self.speechFontSize.value() * 10) self.tailSlider.setOrientation(Qt.Orientation.Horizontal) tailSliderAndSpinBox.addWidget(self.tailSlider) self.tailSpinBox = QSpinBox(self) self.tailSpinBox.setMinimum(0) self.tailSpinBox.setMaximum(self.speechFontSize.value() * 10) tailSliderAndSpinBox.addWidget(self.tailSpinBox) tailSize.setLayout(tailSliderAndSpinBox) mainLayout.addWidget(tailSize) self.tailPositions = QGroupBox() self.tailPositions.setTitle("Tail position") tailPositionsLayout = QHBoxLayout() self.tailPosition = [] for i in range(8): self.tailPosition.append(QRadioButton(self)) self.tailPosition[i].setText(str(i + 1)) self.tailPosition[i].clicked.connect(self.updatePreview) tailPositionsLayout.addWidget(self.tailPosition[i]) self.tailPositions.setLayout(tailPositionsLayout) self.tailPositions.setDisabled(True) mainLayout.addWidget(self.tailPositions) self.updatePreview() self.addOnPage.clicked.connect(self.addOnPageShape) self.squareBubble.clicked.connect(self.updatePreview) self.roundBubble.clicked.connect(self.updatePreview) self.bubbleColorButton.clicked.connect(self.changeBubbleColor) self.outlineSlider.valueChanged.connect(self.outlineSpinBoxUpdate) self.outlineSpinBox.valueChanged.connect(self.outlineSliderUpdate) self.outlineSpinBox.valueChanged.connect(self.updatePreview) self.outlineColorButton.clicked.connect(self.changeOutlineColor) self.bubbleText.textChanged.connect(self.updatePreview) self.speechFontSize.valueChanged.connect(self.updatePreview) self.speechFontSize.valueChanged.connect(self.tailSliderUpdateMaximum) self.currentFontColorButton.clicked.connect(self.changeFontColor) self.speechFont.currentFontChanged.connect(self.updatePreview) self.autocenter.stateChanged.connect(self.enableAverageLineLength) self.autocenter.clicked.connect(self.updatePreview) self.averageLineLengthSlider.valueChanged.connect( self.averageLineLengthSpinBoxUpdate) self.averageLineLengthSpinBox.valueChanged.connect(self.updatePreview) self.averageLineLengthSpinBox.valueChanged.connect( self.averageLineLengthSliderUpdate) self.tailSlider.valueChanged.connect(self.tailSpinBoxUpdate) self.tailSpinBox.valueChanged.connect(self.tailSliderUpdate) self.tailSpinBox.valueChanged.connect(self.updatePreview) self.scrollMainLayout = QScrollArea(self) self.scrollMainLayout.setWidgetResizable(True) self.scrollMainLayout.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) widget = QWidget() widget.setLayout(mainLayout) self.scrollMainLayout.setWidget(widget) self.setWidget(self.scrollMainLayout) self.show() def tailSliderUpdateMaximum(self): self.tailSlider.setMaximum(self.speechFontSize.value() * 10) self.tailSpinBox.setMaximum(self.speechFontSize.value() * 10) def changeBubbleColor(self): self.bubbleColor = QColorDialog.getColor(self.bubbleColor) colorImage = QPixmap(32, 32) colorImage.fill(self.bubbleColor) colorIcon = QIcon(colorImage) self.bubbleColorButton.setIcon(colorIcon) self.updatePreview() def changeFontColor(self): self.speechFontColor = QColorDialog.getColor(self.speechFontColor) colorImage = QPixmap(32, 32) colorImage.fill(self.speechFontColor) colorIcon = QIcon(colorImage) self.currentFontColorButton.setIcon(colorIcon) self.updatePreview() def changeOutlineColor(self): self.outlineColor = QColorDialog.getColor(self.outlineColor) colorImage = QPixmap(32, 32) colorImage.fill(self.outlineColor) colorIcon = QIcon(colorImage) self.outlineColorButton.setIcon(colorIcon) self.updatePreview() def outlineSpinBoxUpdate(self): self.outlineSpinBox.setValue(self.outlineSlider.value()) def outlineSliderUpdate(self): if self.outlineSpinBox.value() < 51: self.outlineSlider.setValue(self.outlineSpinBox.value()) def tailSpinBoxUpdate(self): self.tailSpinBox.setValue(self.tailSlider.value()) if self.tailSlider.value() == 0: self.tailPositions.setDisabled(True) else: self.tailPositions.setDisabled(False) def tailSliderUpdate(self): if self.tailSpinBox.value() < 101: self.tailSlider.setValue(self.tailSpinBox.value()) def enableAverageLineLength(self): if self.autocenter.isChecked(): self.averageLineLength.setDisabled(True) else: self.averageLineLength.setDisabled(False) def averageLineLengthSpinBoxUpdate(self): self.averageLineLengthSpinBox.setValue( self.averageLineLengthSlider.value()) def averageLineLengthSliderUpdate(self): if self.averageLineLengthSpinBox.value() < 101: self.averageLineLengthSlider.setValue( self.averageLineLengthSpinBox.value()) def getSpeechLines(self, text, lineLength): size = 0 speach = "" lines = [] if (lineLength > 0): words = text.split(" ") for word in words: speach += word size += len(word) if size < lineLength: speach += " " else: size = 0 lines.append(speach) speach = "" if (speach != "") and (speach != " "): lines.append(speach.strip()) else: lines = text.split("\n") return lines def getPreview(self): lineLength = int((pow( (len(self.bubbleText.toPlainText())), 1 / 2)) * 1.8) if not (self.autocenter.isChecked()): lineLength = self.averageLineLengthSpinBox.value() lines = self.getSpeechLines(self.bubbleText.toPlainText(), lineLength) biggestLine = "" for line in lines: if (len(line) > len(biggestLine)): biggestLine = line #Calculate text box size font = self.speechFont.currentFont() font.setPixelSize(int(self.speechFontSize.value() * 1.3)) fontSize = self.speechFontSize.value() textHeight = int(fontSize * (len(lines)) - (fontSize - QFontMetrics(font).capHeight())) textWidth = QFontMetrics(font).width(biggestLine) tailLength = self.tailSpinBox.value() framePadding = fontSize tailPadding = tailLength bubblePadding = int(fontSize * 1.5) textTag = "<text x=\"{}\" y=\"{}\" style=\"font-size:{};font-family:{};fill:{};text-anchor:middle\" >{}</text>" text = "" textStartX = framePadding + tailPadding + bubblePadding + (int( textWidth / 2)) textStartY = framePadding + tailPadding + bubblePadding + QFontMetrics( font).capHeight() for line in lines: text += textTag.format(textStartX, textStartY, fontSize, font.family(), self.speechFontColor.name(), line) textStartY += fontSize bubbleCoordinatesX0 = framePadding + tailPadding bubbleCoordinatesY0 = framePadding + tailPadding bubbleCoordinatesXHalf = framePadding + tailPadding + bubblePadding + ( int(textWidth / 2)) bubbleCoordinatesYHalf = framePadding + tailPadding + bubblePadding + ( int(textHeight / 2)) bubbleCoordinatesX = framePadding + tailPadding + bubblePadding + textWidth + bubblePadding bubbleCoordinatesY = framePadding + tailPadding + bubblePadding + textHeight + bubblePadding bubbleCoordinates = [] bubbleCoordinates.append( BubbleCoordinates(bubbleCoordinatesXHalf, bubbleCoordinatesY0)) bubbleCoordinates.append( BubbleCoordinates(bubbleCoordinatesX, bubbleCoordinatesY0)) bubbleCoordinates.append( BubbleCoordinates(bubbleCoordinatesX, bubbleCoordinatesYHalf)) bubbleCoordinates.append( BubbleCoordinates(bubbleCoordinatesX, bubbleCoordinatesY)) bubbleCoordinates.append( BubbleCoordinates(bubbleCoordinatesXHalf, bubbleCoordinatesY)) bubbleCoordinates.append( BubbleCoordinates(bubbleCoordinatesX0, bubbleCoordinatesY)) bubbleCoordinates.append( BubbleCoordinates(bubbleCoordinatesX0, bubbleCoordinatesYHalf)) bubbleCoordinates.append( BubbleCoordinates(bubbleCoordinatesX0, bubbleCoordinatesY0)) i = 0 bubbleCoordinatesString = "M" bubbleCoordinatesStringEnd = str(bubbleCoordinates[0].x) + "," + str( bubbleCoordinates[0].y) + "Z" while (i < 8): if (self.roundBubble.isChecked()): if (self.tailSpinBox.value() > 0): #for coordinates in center (even) textWidth01 = int(pow(textWidth, 1 / 2.8)) textHeight01 = int(pow(textHeight, 1 / 2)) #for coordinates in the corner (odd) x04 = int( (bubbleCoordinates[1].x - bubbleCoordinates[0].x) * 0.4) x06 = int( (bubbleCoordinates[1].x - bubbleCoordinates[0].x) * 0.6) y04 = int( (bubbleCoordinates[2].y - bubbleCoordinates[1].y) * 0.4) y06 = int( (bubbleCoordinates[2].y - bubbleCoordinates[1].y) * 0.6) if i == 0 and self.tailPosition[i].isChecked(): bubbleCoordinatesString += str( bubbleCoordinates[0].x - textWidth01) + "," + str( bubbleCoordinates[0].y) + " L" + str( bubbleCoordinates[0].x) + "," + str( bubbleCoordinates[0].y - tailLength) + " " + str( bubbleCoordinates[0].x + textWidth01) + "," + str( bubbleCoordinates[0].y) + " " bubbleCoordinatesStringEnd = str( bubbleCoordinates[0].x - textWidth01) + "," + str( bubbleCoordinates[0].y) + "Z" elif i == 2 and self.tailPosition[i].isChecked(): bubbleCoordinatesString += str( bubbleCoordinates[2].x) + "," + str( bubbleCoordinates[2].y - textHeight01) + " L" + str( bubbleCoordinates[2].x + tailLength) + "," + str( bubbleCoordinates[2].y) + " " + str( bubbleCoordinates[2].x ) + "," + str(bubbleCoordinates[2].y + textHeight01) + " " elif i == 4 and self.tailPosition[i].isChecked(): bubbleCoordinatesString += str( bubbleCoordinates[4].x + textWidth01) + "," + str( bubbleCoordinates[4].y) + " L" + str( bubbleCoordinates[4].x) + "," + str( bubbleCoordinates[4].y + tailLength) + " " + str( bubbleCoordinates[4].x - textWidth01) + "," + str( bubbleCoordinates[4].y) + " " elif i == 6 and self.tailPosition[i].isChecked(): bubbleCoordinatesString += str( bubbleCoordinates[6].x) + "," + str( bubbleCoordinates[6].y + textHeight01) + " L" + str( bubbleCoordinates[6].x - tailLength) + "," + str( bubbleCoordinates[6].y) + " " + str( bubbleCoordinates[6].x ) + "," + str(bubbleCoordinates[6].y - textHeight01) + " " elif i == 1 and self.tailPosition[i].isChecked(): bubbleCoordinatesString += "Q" + str( bubbleCoordinates[1].x - x06 ) + "," + str(bubbleCoordinates[1].y) + " " + str( int((bubbleCoordinates[1].x + bubbleCoordinates[1].x - x06) / 2) ) + "," + str( int((bubbleCoordinates[1].y + y04 + bubbleCoordinates[1].y) / 2)) + " L" + str( bubbleCoordinates[1].x + tailLength ) + "," + str( bubbleCoordinates[1].y - tailLength ) + " " + str( int((bubbleCoordinates[1].x + bubbleCoordinates[1].x - x04) / 2) ) + "," + str( int((bubbleCoordinates[1].y + y06 + bubbleCoordinates[1].y) / 2)) + " Q" + str( bubbleCoordinates[1].x ) + "," + str(bubbleCoordinates[1].y + y06) + " " elif i == 3 and self.tailPosition[i].isChecked(): bubbleCoordinatesString += "Q" + str( bubbleCoordinates[3].x) + "," + str( bubbleCoordinates[3].y - y06) + " " + str( int( (bubbleCoordinates[3].x + bubbleCoordinates[3].x - x04) / 2 )) + "," + str( int((bubbleCoordinates[3].y - y06 + bubbleCoordinates[3].y) / 2) ) + " L" + str( bubbleCoordinates[3].x + tailLength ) + "," + str( bubbleCoordinates[3].y + tailLength ) + " " + str( int((bubbleCoordinates[3].x + bubbleCoordinates[3].x - x06) / 2) ) + "," + str( int((bubbleCoordinates[3].y - y04 + bubbleCoordinates[3].y) / 2)) + " Q" + str( bubbleCoordinates[3].x - x06 ) + "," + str( bubbleCoordinates[3].y) + " " elif i == 5 and self.tailPosition[i].isChecked(): bubbleCoordinatesString += "Q" + str( bubbleCoordinates[5].x + x06 ) + "," + str(bubbleCoordinates[5].y) + " " + str( int((bubbleCoordinates[5].x + bubbleCoordinates[5].x + x06) / 2) ) + "," + str( int((bubbleCoordinates[5].y - y04 + bubbleCoordinates[5].y) / 2)) + " L" + str( bubbleCoordinates[5].x - tailLength ) + "," + str( bubbleCoordinates[5].y + tailLength ) + " " + str( int((bubbleCoordinates[5].x + bubbleCoordinates[5].x + x04) / 2) ) + "," + str( int((bubbleCoordinates[5].y - y06 + bubbleCoordinates[5].y) / 2)) + " Q" + str( bubbleCoordinates[5].x ) + "," + str(bubbleCoordinates[5].y - y06) + " " elif i == 7 and self.tailPosition[i].isChecked(): bubbleCoordinatesString += "Q" + str( bubbleCoordinates[7].x) + "," + str( bubbleCoordinates[7].y + y06) + " " + str( int( (bubbleCoordinates[7].x + bubbleCoordinates[7].x + x04) / 2 )) + "," + str( int((bubbleCoordinates[7].y + y06 + bubbleCoordinates[7].y) / 2) ) + " L" + str( bubbleCoordinates[7].x - tailLength ) + "," + str( bubbleCoordinates[7].y - tailLength ) + " " + str( int((bubbleCoordinates[7].x + bubbleCoordinates[7].x + x06) / 2) ) + "," + str( int((bubbleCoordinates[7].y + y04 + bubbleCoordinates[7].y) / 2)) + " Q" + str( bubbleCoordinates[7].x + x06 ) + "," + str( bubbleCoordinates[7].y) + " " else: if (i % 2 == 0): bubbleCoordinatesString += str( bubbleCoordinates[i].x) + "," + str( bubbleCoordinates[i].y) + " " else: bubbleCoordinatesString += "Q" + str( bubbleCoordinates[i].x) + "," + str( bubbleCoordinates[i].y) + " " else: if (i % 2 == 0): bubbleCoordinatesString += str( bubbleCoordinates[i].x) + "," + str( bubbleCoordinates[i].y) + " " else: bubbleCoordinatesString += "Q" + str( bubbleCoordinates[i].x) + "," + str( bubbleCoordinates[i].y) + " " elif (self.squareBubble.isChecked()): bubbleCoordinatesString += str( bubbleCoordinates[i].x) + "," + str( bubbleCoordinates[i].y) + " " i += 1 bubbleCoordinatesString += bubbleCoordinatesStringEnd pathStyle = "style=\"fill:{};stroke:{};stroke-width:{};stroke-linejoin:round\"".format( self.bubbleColor.name(), self.outlineColor.name(), self.outlineSpinBox.value()) bubble = "<path " + pathStyle + " d=\"" + bubbleCoordinatesString + "\"/>" frameWidth = framePadding + tailPadding + bubblePadding + textWidth + bubblePadding + tailPadding + framePadding frameHeight = framePadding + tailPadding + bubblePadding + textHeight + bubblePadding + tailPadding + framePadding result = "<svg width=\"{}\" height=\"{}\" >{}{}</svg>".format( frameWidth, frameHeight, bubble, text) return result def updatePreview(self): result = self.getPreview() resultBytes = bytearray(result, encoding='utf-8') self.preview.renderer().load(resultBytes) def addOnPageShape(self): result = self.getPreview() d = Krita.instance().activeDocument() root = d.rootNode() l3 = d.createVectorLayer(self.bubbleText.toPlainText()[:16]) root.addChildNode(l3, None) l3.addShapesFromSvg(result) pass def canvasChanged(self, canvas): pass
class MyTableWidget(QWidget): def __init__(self, parent): super(QWidget, self).__init__(parent) # curr mouse position in plot coordinates self.curr_x = 0 self.curr_y = 0 # circle color (color picker) self.color = QColor() # circles size (slider) self.curr_size = 10 # list with circles self.circles = [] # artist for the plot self.artists = [] self.fileName = 'some_qml.xml' # gui stuff self.layout = QVBoxLayout(self) # Initialize tab screen self.tabs = QTabWidget() self.tab1 = QWidget() self.tab2 = QWidget() self.tabs.resize(300, 200) # Add tabs self.tabs.addTab(self.tab1, "Edit") self.tabs.addTab(self.tab2, "Model") # Create first tab self.tab1.layout = QVBoxLayout(self) self.tab1.setLayout(self.tab1.layout) # Creating widgets self.m = PlotCanvas(self.tab1, width=5, height=5) self.m.move(0, 0) pb_plus = Button('+', self.tab1, 500, 0, 140, 100) pb_minus = Button('-', self.tab1, 500, 100, 140, 100) pb_choose_color = Button('Choose Color', self.tab1) self.le_x_coord = QLineEdit() self.le_y_coord = QLineEdit() self.le_slider = QLineEdit() self.le_x_coord.setDisabled(True) self.le_y_coord.setDisabled(True) self.slider = QSlider(Qt.Horizontal) self.slider.setRange(1.0, 100.0) pb_save_qml = Button('Save to xml', self.tab1) pb_open_qml = Button('Open xml', self.tab1) pb_draw_system = Button('Draw Sun system', self.tab1) pb_start_animation = Button('Start animation', self.tab1) # tab Edit # Adding widgets to layout self.tab1.layout.addWidget(self.m) self.tab1.layout_coords = QHBoxLayout() self.tab1.layout.addLayout(self.tab1.layout_coords) self.tab1.layout_coords.addWidget(self.le_x_coord) self.tab1.layout_coords.addWidget(self.le_y_coord) self.tab1.layout_coords.addWidget(pb_plus) self.tab1.layout_coords.addWidget(pb_minus) self.tab1.layout_size = QHBoxLayout() self.tab1.layout.addLayout(self.tab1.layout_size) self.tab1.layout.addWidget(pb_choose_color) self.tab1.label_size = QLabel('Choose size ') self.tab1.layout_size.addWidget(self.tab1.label_size) self.tab1.layout_size.addWidget(self.slider) self.tab1.layout_size.addWidget(self.le_slider) layout_save = QHBoxLayout() layout_open = QHBoxLayout() self.tab1.le_saveFileName = QLineEdit() self.tab1.le_openFileName = QLineEdit() self.tab1.layout.addLayout(layout_save) self.tab1.layout.addLayout(layout_open) layout_save.addWidget(pb_save_qml) layout_save.addWidget(self.tab1.le_saveFileName) self.tab1.le_saveFileName.setText(self.fileName) layout_open.addWidget(pb_open_qml) layout_open.addWidget(self.tab1.le_openFileName) self.tab1.le_openFileName.setText(self.fileName) self.tab1.layout.addWidget(pb_draw_system) self.tab1.layout.addWidget(pb_start_animation) # connecting slots pb_plus.clicked.connect(self.m.zoomIn) pb_minus.clicked.connect(self.m.zoomOut) pb_choose_color.clicked.connect(self.showColorPicker) pb_save_qml.clicked.connect(self.showSaveDialog) pb_open_qml.clicked.connect(self.showOpenDialog) pb_draw_system.clicked.connect(self.drawSunEarthMoonSystem) pb_start_animation.clicked.connect(self.startAnimation) self.slider.valueChanged.connect(self.sliderValueChanged) self.le_slider.textChanged.connect(self.textSliderValueChanged) self.m.mpl_connect('motion_notify_event', self.changeCoords) self.m.mpl_connect('button_press_event', self.drawCircleMouseClick) self.slider.setValue(10) # Add tabs to widget self.layout.addWidget(self.tabs) self.setLayout(self.layout) # tab Model self.tab2.layout = QVBoxLayout(self) self.tab2.setLayout(self.tab2.layout) rb_scipy = QRadioButton('scipy') rb_verlet = QRadioButton('verlet') rb_verletThreading = QRadioButton('verlet-threading') rb_verletMultiprocessing = QRadioButton('verlet-multiprocessing') rb_verletCython = QRadioButton('verlet-cython') rb_verletOpenCL = QRadioButton('verlet-opencl') rb_verlet.setChecked(True) vbox = QVBoxLayout() vbox.addWidget(rb_scipy) vbox.addWidget(rb_verlet) vbox.addWidget(rb_verletThreading) vbox.addWidget(rb_verletCython) vbox.addWidget(rb_verletMultiprocessing) vbox.addWidget(rb_verletOpenCL) groupBox = QGroupBox() groupBox.setTitle('Select mode') groupBox.setLayout(vbox) self.tab2.layout.addWidget(groupBox) # self.drawSunEarthMoonSystem() def drawCircleMouseClick(self, event): if (event.inaxes): circle = customCircle(self.curr_x, self.curr_y, self.curr_size, self.color.name()) self.m.axes.add_artist(circle) self.circles.append(circle) self.m.draw() def drawCircle(self, customCircle): a = self.m.axes.add_artist(customCircle) self.artists.append(a) self.m.draw() def drawCirclesList(self): for circ in self.circles: self.m.axes.add_artist(circ) self.m.draw() def scaleCircles(self, scale): for circ in self.circles: circ.scaleCircle(scale) def scaleCirclesRadius(self, scale): for circ in self.circles: circ.radius *= scale def setCentersAfterIteration(self): for circ in self.circles: circ.setCenterFromRadiusVector() def drawSunEarthMoonSystem(self): # all velocities are [0,v] self.circles.clear() self.m.axes.clear() r_earth_sun = 1.496 * (10 ** 11) r_moon_earth = 3.844 * (10 ** 8) r_moon_sun = r_earth_sun + r_moon_earth sun = getSunCircle(0, 0) earth = getEarthCircle(r_earth_sun, 0) moon = getMoonCircle(r_moon_sun, 0) self.circles.append(sun) self.circles.append(earth) self.circles.append(moon) self.scaleCircles(1e-9) self.scaleCirclesRadius(0.5) print(self.circles[1].x) self.drawCirclesList() def startAnimation(self): t = 0 iters = 20 dt = 3600 * 24 *1e-4 # I don't know about dt, mb it should be normalized somehow for i in range(iters): print(self.circles[1].r) print(self.circles[1].v) verletIteration(self.circles, dt, t) self.setCentersAfterIteration() self.m.axes.clear() self.m.draw() self.drawCirclesList() t += 1 def changeCoords(self, event): if (event.inaxes): self.le_x_coord.setText(str(event.xdata)) self.le_y_coord.setText(str(event.ydata)) self.curr_x = event.xdata self.curr_y = event.ydata else: self.le_x_coord.clear() self.le_y_coord.clear() def showColorPicker(self): self.color = QColorDialog.getColor() def sliderValueChanged(self, val): self.le_slider.setText(str(val)) self.curr_size = val def textSliderValueChanged(self): if isConvertibleToFloat(self.le_slider.text()): val = float(self.le_slider.text()) self.slider.setValue(val) self.curr_size = val def showSaveDialog(self): self.save2Xml() return options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog self.fileName, _ = QFileDialog.getSaveFileName(self, "QFileDialog.getSaveFileName()", "", "All Files (*);;Text Files (*.txt)", options=options) def showOpenDialog(self): self.openXml() return options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog self.fileName, _ = QFileDialog.getOpenFileName(self, "QFileDialog.getOpenFileName()", "", "All Files (*);;Python Files (*.py)", options=options) def save2Xml(self): root = ET.Element("data") params = ET.SubElement(root, "parameters") plot_size = ET.SubElement(params, "plot_size") plot_size.text = str(self.m.axes.get_xlim()) color = ET.SubElement(params, "color") color.text = self.color.name() slider = ET.SubElement(params, "slider_data") slider_min = ET.SubElement(slider, "min_value") slider_min.text = str(self.slider.minimum()) slider_max = ET.SubElement(slider, "max_value") slider_max.text = str(self.slider.maximum()) slider_value = ET.SubElement(slider, "value") slider_value.text = str(self.slider.value()) circles = ET.SubElement(root, "circles") for cir in self.circles: circle = ET.SubElement(circles, "circle") ET.SubElement(circle, "x").text = str(cir.x) ET.SubElement(circle, "y").text = str(cir.y) ET.SubElement(circle, "size").text = str(cir.radius) ET.SubElement(circle, "color").text = str(cir.color) tree = ET.ElementTree(root) tree.write(self.fileName) def openXml(self): tree = ET.parse(self.fileName) parameters = tree.find("parameters") plot_size = parameters.find("plot_size") spl = plot_size.text.split('(')[1].split(')')[0].split(',') lim = (float(spl[0]), float(spl[1])) color = parameters.find('color').text slider = parameters.find('slider_data') min_v = slider.find('min_value').text max_v = slider.find('max_value').text v = slider.find('value').text self.m.axes.clear() self.m.axes.set_xlim(lim) self.m.axes.set_ylim(lim) self.color.setNamedColor(color) self.slider.setMinimum(int(min_v)) self.slider.setMaximum(int(max_v)) self.slider.setValue(int(v)) self.circles.clear() circles_root = tree.find("circles") circles = circles_root.getiterator("circle") for c in circles: x = c.find("x").text y = c.find("y").text radius = c.find("size").text color = c.find("color").text newCircle = customCircle(float(x), float(y), float(radius), color) self.circles.append(newCircle) self.m.axes.add_artist(newCircle) self.m.draw()
class Example(QWidget): ''' ''' def __init__(self): super().__init__() self.initUI() def initUI(self): ''' ''' checkBox = QCheckBox('Show title', self) checkBox.move(20, 20) checkBox.toggle() checkBox.stateChanged.connect(self.changeTitle) self.color = QColor(0, 0, 0) redBtn = QPushButton('Red', self) redBtn.setCheckable(True) redBtn.move(20, 60) redslider = QSlider(Qt.Horizontal, self) redslider.setFocusPolicy(Qt.NoFocus) redslider.setGeometry(100, 60, 100, 20) redBtn.clicked[bool].connect(self.setColor) redslider.valueChanged[int].connect(self.changeRedValue) greenBtn = QPushButton('Green', self) greenBtn.setCheckable(True) greenBtn.move(20, 100) greenslider = QSlider(Qt.Horizontal, self) greenslider.setFocusPolicy(Qt.NoFocus) greenslider.setGeometry(100, 100, 100, 20) greenBtn.clicked[bool].connect(self.setColor) greenslider.valueChanged[int].connect(self.changeGreenValue) blueBtn = QPushButton('Blue', self) blueBtn.setCheckable(True) blueBtn.move(20, 140) blueslider = QSlider(Qt.Horizontal, self) blueslider.setFocusPolicy(Qt.NoFocus) blueslider.setGeometry(100, 140, 100, 20) blueBtn.clicked[bool].connect(self.setColor) blueslider.valueChanged[int].connect(self.changeBlueValue) calinder = QCalendarWidget(self) calinder.setGridVisible(True) calinder.move(160, 200) calinder.clicked[QDate].connect(self.showDate) self.label = QLabel(self) date = calinder.selectedDate() self.label.setText(date.toString()) self.label.move(20, 200) self.frame = QFrame(self) self.frame.setGeometry(350, 60, 100, 100) self.frame.setStyleSheet('QWidget {background-color: %s}' % self.color.name()) self.pbar = QProgressBar(self) self.pbar.setGeometry(20, 450, 500, 20) self.pBtn = QPushButton('Start', self) self.pBtn.move(20, 400) self.pBtn.clicked.connect(self.doAction) self.timer = QBasicTimer() self.step = 0 self.setGeometry(300, 300, 600, 500) self.setWindowTitle('控件示例') self.show() def setColor(self, pressed): ''' ''' source = self.sender() if pressed: val = 255 else: val = 0 if source.text() == 'Red': self.color.setRed(val) elif source.text() == 'Green': self.color.setGreen(val) else: self.color.setBlue(val) self.frame.setStyleSheet('QWidget {background-color: %s}' % self.color.name()) def changeRedValue(self, value): ''' ''' colorvalue = (value + 1) * 255 // 100 self.color.setRed(colorvalue) self.frame.setStyleSheet('QWidget {background-color: %s}' % self.color.name()) def changeGreenValue(self, value): ''' ''' colorvalue = (value + 1) * 255 // 100 self.color.setGreen(colorvalue) self.frame.setStyleSheet('QWidget {background-color: %s}' % self.color.name()) def changeBlueValue(self, value): ''' ''' colorvalue = (value + 1) * 255 // 100 self.color.setBlue(colorvalue) self.frame.setStyleSheet('QWidget {background-color: %s}' % self.color.name()) def changeTitle(self, state): ''' ''' if state == Qt.Checked: self.setWindowTitle('控件选择') else: self.setWindowTitle('控件未选择') def showDate(self, date): ''' ''' self.label.setText(date.toString()) def doAction(self): ''' ''' if self.timer.isActive(): self.timer.stop() self.pBtn.setText('Start') else: self.timer.start(100, self) self.step = 0 self.pBtn.setText('Stop') def timerEvent(self, event): ''' ''' if self.step >= 100: self.timer.stop() self.pBtn.setText('Start') return self.step += 1 self.pbar.setValue(self.step) def keyPressEvent(self, event): '''重写事件处理器函数 ''' if event.key() == Qt.Key_Escape: self.close()
class MyMainWindow(QMainWindow, Ui_Form): path = '' key = '9fwbrTfbKfFVtpy9NGN5zeRG' def __init__(self, parent=None): super(MyMainWindow, self).__init__(parent) self.setupUi(self) self.col = QColor(255, 255, 255) self.frame.setStyleSheet("QWidget { background-color: %s }" % self.col.name()) self.path = './pic' # 设置信号与槽 self.CreateSignalSlot() def CreateSignalSlot(self): self.comboBox.currentIndexChanged.connect(self.ChColor) self.lineEdit.textEdited.connect(self.chKey) # self.pushButton.clicked.connect(self.openfile) self.pushButton_2.clicked.connect(self.RemoveAllFilesBg) def chKey(self): self.key = self.lineEdit.text() print("当前秘钥为:{1}".format(self.key)) # def openfile(self): # try: # openfile_name = QFileDialog.getOpenFileNames(self, '选择文件', '', 'files()') # # print(openfile_name) # self.path = openfile_name[0] # self.lineEdit.setText(self.path[0]) # except: # self.path = '.' def ChColor(self): if self.comboBox.currentIndex() == 0: self.col = QColor(255, 255, 255) if self.comboBox.currentIndex() == 1: self.col = QColor(211, 4, 4) if self.comboBox.currentIndex() == 2: self.col = QColor(0, 0, 0) if self.comboBox.currentIndex() == 3: self.col = QColor(28, 4, 211) if self.comboBox.currentIndex() == 4: self.col = QColor(242, 150, 31) if self.comboBox.currentIndex() == 5: self.col = QColor(193, 31, 242) if self.comboBox.currentIndex() == 6: self.col = QColor(0, 127, 125) self.frame.setStyleSheet("QWidget { background-color: %s }" % self.col.name()) def RemoveBg(self, fileName, key): saveFile = fileName.split('.')[0] + '_rm.' + fileName.split('.')[-1] response = requests.post( 'https://api.remove.bg/v1.0/removebg', files={'image_file': open(fileName, 'rb')}, data={'size': 'auto'}, headers={'X-Api-Key': key}, ) if response.status_code == requests.codes.ok: with open(saveFile, 'wb') as out: out.write(response.content) print("sucess") self.label_2.setText("处理成功") im = Image.open(saveFile, mode='r') print(saveFile) return saveFile else: print("Error:", response.status_code, response.text) def ChgBg(self, fileName, bg): saveFile = fileName.split('.')[0] + '_mod.' + fileName.split('.')[-1] im = cv.imread(fileName) for i in range(im.shape[0]): for j in range(im.shape[1]): if (im[i, j] == numpy.array([0, 0, 0])).all(): im[i, j] = bg # cv.imshow("Noize", im) cv.imwrite(saveFile, im) def RemoveAllFilesBg(self): # 判断是否是文件夹 if os.path.isdir(self.path): print(self.path) os.chdir(self.path) files = os.listdir(os.getcwd()) for i in files: if os.path.splitext(i)[-1] == '.png' or os.path.splitext( i)[-1] == '.jpg': print("start") self.ChgBg(self.RemoveBg(i), self.col.getRgb()[:3], self.key)
def Night(self): color = QColor(51, 51, 51) if color.isValid(): self.setStyleSheet("QWidget { background-color: %s }" % color.name()) self.display.append('已切换为夜间模式')
class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): # 设置颜色为黑色 self.col = QColor(0, 0, 0) # 创建一个QPushButton,然后调用它的setCheckable()的方法就把这个按钮变成了切换按钮。 redb = QPushButton('Red', self) redb.setCheckable(True) redb.move(10, 10) # 把点击信号和我们定义好的函数关联起来,这里是把点击事件转换成布尔值。 redb.clicked[bool].connect(self.setColor) greenb = QPushButton('Blue', self) greenb.setCheckable(True) greenb.move(10, 60) greenb.clicked[bool].connect(self.setColor) blueb = QPushButton('Blue', self) blueb.setCheckable(True) blueb.move(10, 110) blueb.clicked[bool].connect(self.setColor) self.square = QFrame(self) self.square.setGeometry(150, 20, 100, 100) self.square.setStyleSheet("QWidget { background-color: %s }" % self.col.name()) self.setGeometry(300, 300, 280, 170) self.setWindowTitle('Toggle button') self.show() def setColor(self, pressed): # 获取被点击的按钮。 source = self.sender() if pressed: val = 255 else: val = 0 # 如果是标签为“red”的按钮被点击,就把颜色更改为预设好的对应颜色。 if source.text() == "Red": self.col.setRed(val) elif source.text() == "Green": self.col.setGreen(val) else: self.col.setBlue(val) # 使用样式表(就是CSS的SS)改变背景色 self.square.setStyleSheet("QFrame { background-color: %s }" % self.col.name())
class Example(QWidget): def __init__(self): super(Example, self).__init__() self.initUI() def initUI(self): # checkBox cb = QCheckBox('show title', self) cb.move(10, 10) cb.toggle() cb.stateChanged.connect(self.changeTitle) # 颜色混合 self.col = QColor(0, 0, 0) redb = QPushButton('Red', self) redb.setCheckable(True) redb.move(10, 30) redb.clicked[bool].connect(self.setColor) grnb = QPushButton('Green', self) grnb.setCheckable(True) grnb.move(10, 60) grnb.clicked[bool].connect(self.setColor) blueb = QPushButton('Blue', self) blueb.setCheckable(True) blueb.move(10, 90) blueb.clicked[bool].connect(self.setColor) self.square = QFrame(self) self.square.setGeometry(150, 20, 50, 50) self.square.setStyleSheet("QWidget { background-color: %s}" % self.col.name()) # slider 滚动条 sld = QSlider(Qt.Horizontal, self) sld.setFocusPolicy(Qt.NoFocus) sld.setGeometry(10, 120, 100, 10) sld.valueChanged[int].connect(self.changeValue) self.label = QLabel(self) self.label.setPixmap(QPixmap('1.png')) self.label.setGeometry(150, 90, 80, 80) # 进度条ProgressBar self.pbar = QProgressBar(self) self.pbar.setGeometry(10, 170, 200, 20) self.btn = QPushButton('Start', self) self.btn.move(10, 200) self.btn.clicked.connect(self.doAction) self.timer = QBasicTimer() self.step = 0 # Calendar 日历 cal = QCalendarWidget(self) cal.setGridVisible(True) cal.move(10, 230) cal.clicked[QDate].connect(self.showDate) self.lbl = QLabel(self) date = cal.selectedDate() self.lbl.setText(date.toString()) self.lbl.move(80, 440) self.setGeometry(300, 200, 300, 500) self.setWindowTitle('Toggle') self.show() def changeTitle(self, state): if state == Qt.Checked: self.setWindowTitle('Toogle') else: self.setWindowTitle(' ') def setColor(self, pressed): source = self.sender() if pressed: val = 255 else: val = 0 if source.text() == "Red": self.col.setRed(val) elif source.text() == "Green": self.col.setGreen(val) else: self.col.setBlue(val) self.square.setStyleSheet("QFrame {background-color: %s}" % self.col.name()) def changeValue(self, value): if value == 0: self.label.setPixmap(QPixmap('1.png')) elif 0 < value <= 30: self.label.setPixmap(QPixmap('2.png')) elif 30 < value < 80: self.label.setPixmap(QPixmap('3.png')) else: self.label.setPixmap(QPixmap('4.png')) def timerEvent(self, *args, **kwargs): if self.step >= 100: self.timer.stop() self.btn.setText('Finished') return self.step += 1 self.pbar.setValue(self.step) def doAction(self): if self.timer.isActive(): self.timer.stop() self.btn.setText('Start') else: self.timer.start(100, self) self.btn.setText('Stop') def showDate(self, date): self.lbl.setText(date.toString())
class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(800, 600) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget) self.graphicsView.setGeometry(QtCore.QRect(30, 20, 741, 511)) self.graphicsView.setObjectName("graphicsView") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setEnabled(True) self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 25)) self.menubar.setObjectName("menubar") self.menuFile = QtWidgets.QMenu(self.menubar) self.menuFile.setObjectName("menuFile") self.menuColor = QtWidgets.QMenu(self.menubar) self.menuColor.setObjectName("menuColor") self.menuAlgorithms = QtWidgets.QMenu(self.menubar) self.menuAlgorithms.setObjectName("menuAlgorithms") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.actionAdd_node = QtWidgets.QAction(MainWindow) self.actionAdd_node.setObjectName("actionAdd_node") self.actionAdd_edge = QtWidgets.QAction(MainWindow) self.actionAdd_edge.setObjectName("actionAdd_edge") self.actionDelete_node = QtWidgets.QAction(MainWindow) self.actionDelete_node.setObjectName("actionDelete_node") self.actionDelete_edge = QtWidgets.QAction(MainWindow) self.actionDelete_edge.setObjectName("actionDelete_edge") self.actionMax_matching = QtWidgets.QAction(MainWindow) self.actionMax_matching.setObjectName("actionMax_matching") self.actionEdge_3_color = QtWidgets.QAction(MainWindow) self.actionEdge_3_color.setObjectName("actionEdge_3_color") self.actionVertex_cover = QtWidgets.QAction(MainWindow) self.actionVertex_cover.setObjectName("actionVertex_cover") self.actionIndependent_Set = QtWidgets.QAction(MainWindow) self.actionIndependent_Set.setObjectName("actionIndependent_Set") self.actionHamiltonian_Path = QtWidgets.QAction(MainWindow) self.actionHamiltonian_Path.setObjectName("actionHamiltonian_Path") self.actionMax_Clique = QtWidgets.QAction(MainWindow) self.actionMax_Clique.setObjectName("actionMax_Clique") self.actionMove_node = QtWidgets.QAction(MainWindow) self.actionMove_node.setObjectName("actionMove_node") self.actionSave_File = QtWidgets.QAction(MainWindow) self.actionSave_File.setObjectName("actionSave_File") self.actionSave_File.setShortcut("Ctrl+S") self.actionOpen_File = QtWidgets.QAction(MainWindow) self.actionOpen_File.setObjectName("actionOpen_File") self.actionOpen_File.setShortcut("Ctrl+O") self.actionClear_Scene = QtWidgets.QAction(MainWindow) self.actionClear_Scene.setObjectName("actionClear_Scene") self.actionNode_Color = QtWidgets.QAction(MainWindow) self.actionNode_Color.setObjectName("actionNode_Color") self.actionEdge_Color = QtWidgets.QAction(MainWindow) self.actionEdge_Color.setObjectName("actionEdge_Color") self.menuFile.addAction(self.actionAdd_node) self.menuFile.addAction(self.actionAdd_edge) self.menuFile.addAction(self.actionDelete_node) self.menuFile.addAction(self.actionDelete_edge) self.menuFile.addAction(self.actionMove_node) self.menuAlgorithms.addAction(self.actionMax_matching) self.menuAlgorithms.addAction(self.actionEdge_3_color) self.menuAlgorithms.addAction(self.actionVertex_cover) self.menuAlgorithms.addAction(self.actionIndependent_Set) self.menuAlgorithms.addAction(self.actionHamiltonian_Path) self.menuAlgorithms.addAction(self.actionMax_Clique) self.menuFile.addAction(self.actionSave_File) self.menuFile.addAction(self.actionOpen_File) self.menuFile.addAction(self.actionClear_Scene) self.menuColor.addAction(self.actionEdge_Color) self.menuColor.addAction(self.actionNode_Color) self.menubar.addAction(self.menuFile.menuAction()) self.menubar.addAction(self.menuColor.menuAction()) self.menubar.addAction(self.menuAlgorithms.menuAction()) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.menuFile.setTitle(_translate("MainWindow", "File")) self.menuColor.setTitle(_translate("MainWindow", "Color")) self.menuAlgorithms.setTitle(_translate("MainWindow", "Algorithms")) self.actionAdd_node.setText(_translate("MainWindow", "Add node")) self.actionAdd_edge.setText(_translate("MainWindow", "Add edge")) self.actionDelete_node.setText(_translate("MainWindow", "Delete node")) self.actionDelete_edge.setText(_translate("MainWindow", "Delete edge")) self.actionMove_node.setText(_translate("MainWindow", "Move node")) self.actionMax_matching.setText(_translate("MainWindow", "Max matching")) self.actionEdge_3_color.setText(_translate("MainWindow","Minimum Vertex color")) self.actionVertex_cover.setText(_translate("MainWindow","Vertex Cover")) self.actionIndependent_Set.setText(_translate("MainWindow", "Independent Set")) self.actionHamiltonian_Path.setText(_translate("MainWindow", "Hamiltonian Path")) self.actionMax_Clique.setText(_translate("MainWindow", "Max Clique")) self.actionSave_File.setText(_translate("MainWindow", "Save File")) self.actionOpen_File.setText(_translate("MainWindow", "Open File")) self.actionClear_Scene.setText(_translate("MainWindow", "Clear Scene")) self.actionDelete_edge.setStatusTip(_translate("MainWindow", "Click on the 2 corresponding nodes")) self.actionEdge_Color.setText(_translate("MainWindow", "Edge Color")) self.actionNode_Color.setText(_translate("MainWindow", "Node Color")) self.x1 = 0 self.y1 = 0 self.x2 = 0 self.y2 = 0 self.function = 0 self.node = [] self.edge = [] self.index = 0 self.eindex = 0 self.s1 = -1 self.s2 = -1 self.graphicsView.scene = QGraphicsScene() self.graphicsView.setScene(self.graphicsView.scene) self.graphicsView.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) pen = QPen(QtCore.Qt.white) brush = QBrush(QtCore.Qt.white) self.graphicsView.scene.addEllipse(5,5,10,10,pen,brush) self.epen = QPen(QtCore.Qt.black,5) self.ebrush = QBrush(QtCore.Qt.black) self.npen = QPen(QtCore.Qt.black,5) self.nbrush = QBrush(QtCore.Qt.black) self.psel = QPen(QtCore.Qt.red,5) self.bsel = QBrush(QtCore.Qt.red) self.ecolour = QColor(0,0,0) self.ncolour = QColor(0,0,0) self.mm = QColor(255,255,255) self.vc = QColor(255,255,255) self.ind = QColor(255,255,255) self.hp = QColor(255,255,255) self.menuFile.triggered[QtWidgets.QAction].connect(self.processtrigger) self.menuColor.triggered[QtWidgets.QAction].connect(self.processtrigger) self.menuAlgorithms.triggered[QtWidgets.QAction].connect(self.processtrigger) def find_maximum_matching(self,G,M): P = self.finding_aug_path(G,M) if P == []:#Base Case return M else: #Augment P to M ##Add the alternating edges of P to M for i in range(0,len(P)-2,2): M.add_edge(P[i],P[i+1]) M.remove_edge(P[i+1],P[i+2]) M.add_edge(P[-2],P[-1]) return self.find_maximum_matching(G,M) def dist_to_root(self,point,root,Graph): path = nx.shortest_path(Graph, source = point, target = root) return (len(path)-1) def finding_aug_path(self,G,M,Blossom_stack=[]): Forest = [] #Storing the Forests Path = [] # The final path unmarked_edges = list(set(G.edges()) - set(M.edges())) unmarked_nodes = list(G.nodes()) Forest_nodes = [] ## we need a map from v to the tree tree_to_root = {} # key=idx of tree in forest, val=root root_to_tree = {} # key=root, val=idx of tree in forest ##List of exposed vertices - ROOTS OF TREES exp_vertex = list(set(G.nodes()) - set(M.nodes())) counter = 0 #List of trees with the exposed vertices as the roots for v in exp_vertex: temp = nx.Graph() temp.add_node(v) Forest.append(temp) Forest_nodes.append(v) #link each root to its tree tree_to_root[counter] = v root_to_tree[v] = counter counter = counter + 1 for v in Forest_nodes: root_of_v = None tree_num_of_v = None for tree_number in range(len(Forest)): tree_in = Forest[tree_number] if tree_in.has_node(v) == True: root_of_v = tree_to_root[tree_number] tree_num_of_v = tree_number break #Break out of the for loop edges_v = list(G.edges(v)) for edge_number in range(len(edges_v)): e = edges_v[edge_number] e2 = (e[1],e[0]) #the edge in the other order if ((e in unmarked_edges or e2 in unmarked_edges) and e!=[]): w = e[1] # the other vertex of the unmarked edge w_in_Forest = 0; ##Indicator for w in F or not ##Go through all the trees in the forest to check if w in F tree_of_w = None tree_num_of_w = None for tree_number in range(len(Forest)): tree = Forest[tree_number] if tree.has_node(w) == True: w_in_Forest = 1 root_of_w = tree_to_root[tree_number] tree_num_of_w = tree_number tree_of_w = Forest[tree_num_of_w] break #Break the outer for loop if w_in_Forest == 0: ## w is matched, so add e and w's matched edge to F Forest[tree_num_of_v].add_edge(e[0],e[1]) # edge {v,w} # Note: we don't add w to forest nodes b/c it's odd dist from root #assert(M.has_node(w)) edge_w = list(M.edges(w))[0] # get edge {w,x} Forest[tree_num_of_v].add_edge(edge_w[0],edge_w[1]) # add edge{w,x} Forest_nodes.append(edge_w[1]) ## add {x} to the list of forest nodes else: ## w is in Forest # if odd, do nothing. if self.dist_to_root(w,root_of_w,Forest[tree_num_of_w])%2 == 0: if (tree_num_of_v != tree_num_of_w): ##Shortest path from root(v)--->v-->w---->root(w) path_in_v = nx.shortest_path(Forest[tree_num_of_v], source = root_of_v, target = v) path_in_w = nx.shortest_path(Forest[tree_num_of_w], source = w, target = root_of_w) return path_in_v + path_in_w else: ##Contract the blossom # create blossom blossom = nx.shortest_path(tree_of_w, source=v, target=w) blossom.append(v) #assert(len(blossom)%2 == 0) # contract blossom into single node w contracted_G = copy.deepcopy(G) contracted_M = copy.deepcopy(M) for node in blossom[0:len(blossom)-1]: if node != w: contracted_G = nx.contracted_nodes(contracted_G, w, node, self_loops=False) if node in contracted_M.nodes(): edge_rm = list(M.edges(node))[0] #this will be exactly one edge contracted_M.remove_node(node) contracted_M.remove_node(edge_rm[1]) #assert(len(list(contracted_M.nodes()))%2 == 0) # add blossom to our stack Blossom_stack.append(w) # recurse aug_path = self.finding_aug_path(contracted_G, contracted_M, Blossom_stack) # check if blossom exists in aug_path v_B = Blossom_stack.pop() if (v_B in aug_path): ##Define the L_stem and R_stem L_stem = aug_path[0:aug_path.index(v_B)] R_stem = aug_path[aug_path.index(v_B)+1:] lifted_blossom = [] #stores the path within the blossom to take # Find base of blossom i = 0 base = None base_idx = -1 blossom_ext = blossom + [blossom[1]] while base == None and i < len(blossom) - 1: if not(M.has_edge(blossom[i],blossom[i+1])): if not(M.has_edge(blossom[i+1],blossom_ext[i+2])): base = blossom[i+1] base_idx = i+1 else: i += 2 else: i += 1 # if needed, create list of blossom nodes starting at base if blossom[0] != base: based_blossom = [] base_idx = blossom.index(base) for i in range(base_idx,len(blossom)-1): based_blossom.append(blossom[i]) for i in range(0,base_idx): based_blossom.append(blossom[i]) based_blossom.append(base) else: based_blossom = blossom # CHECK IF BLOSSOM IS ENDPT if L_stem == [] or R_stem == []: if L_stem != []: if G.has_edge(base, L_stem[-1]): # CASE 1: # Chuck the blossom return L_stem + [base] else: # CASE 2: # find where Lstem is connected i = 1 while (lifted_blossom == []): #assert(i < len(based_blossom)-1) if G.has_edge(based_blossom[i],L_stem[-1]): # make sure we're adding the even part to lifted path if i%2 == 0: # same dir path lifted_blossom = list(reversed(based_blossom))[-i-1:] #################### else: # opposite dir path lifted_blossom = based_blossom[i:]########################## i += 1 return L_stem + lifted_blossom else: if G.has_edge(base, R_stem[0]): # CASE 1: # Chuck the blossom. return [base] + R_stem else: # CASE 2: # find where R_stem is connected i = 1 while (lifted_blossom == []): #assert(i < len(based_blossom)-1) if G.has_edge(based_blossom[i],R_stem[0]): # make sure we're adding the even part to lifted path if i%2 == 0: # same dir path lifted_blossom = based_blossom[:i+1] #print lifted_blossom else: # opposite dir path lifted_blossom = list(reversed(based_blossom))[:-i] i += 1 return lifted_blossom + R_stem else: # blossom is in the middle # LIFT the blossom # check if L_stem attaches to base if M.has_edge(base, L_stem[-1]): # find where right stem attaches if G.has_edge(base, R_stem[0]): # blossom is useless return L_stem + [base] + R_stem else: # blossom needs to be lifted i = 1 while (lifted_blossom == []): # assert(i < len(based_blossom)-1) if G.has_edge(based_blossom[i],R_stem[0]): # make sure we're adding the even part to lifted path if i%2 == 0: # same dir path lifted_blossom = based_blossom[:i+1] # print lifted_blossom else: # opposite dir path lifted_blossom = list(reversed(based_blossom))[:-i] # print lifted_blossom i += 1 return L_stem + lifted_blossom + R_stem else: # R stem to base is in matching # assert(M.has_edge(base, R_stem[0])) # check where left stem attaches if G.has_edge(base, L_stem[-1]): # blossom is useless return L_stem + [base] + R_stem else: # blossom needs to be lifted i = 1 while (lifted_blossom == []): # assert(i < len(based_blossom)-1) if G.has_edge(based_blossom[i],L_stem[-1]): # make sure we're adding the even part to lifted path if i%2 == 0: # same dir path lifted_blossom = list(reversed(based_blossom))[-i-1:] else: # opposite dir path lifted_blossom = based_blossom[i:] i += 1 return L_stem + list((lifted_blossom)) + R_stem else: # blossom is not in aug_path return aug_path ##IF Nothing is Found return Path ##Empty Path def pixelselect(self,event): self.a = event.localPos() self.x1 = int(self.a.x()) self.y1 = int(self.a.y()) if self.function == 1: self.graphicsView.scene.addEllipse(self.x1, self.y1, 10, 10, self.npen,self.nbrush) self.node.append(st(self.x1,self.y1,1,self.ncolour.name(),self.ncolour.name())) if self.function == 3: self.f2=0 for i in range(len(self.node)): self.ni1 = abs(self.x1-self.node[i].x) self.ni2 = abs(self.y1-self.node[i].y) if self.ni1<10: if self.ni2<10: self.i1 = i self.f2= 1 self.node[i].fl = 0 for i in range(len(self.edge)): if self.edge[i].x == self.i1: self.edge[i].fl = 0 if self.edge[i].y == self.i1: self.edge[i].fl = 0 if self.f2==1: self.graphicsView.scene.clear() for i in range(len(self.node)): if self.node[i].fl == 1: self.colour = QColor(self.node[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addEllipse(self.node[i].x,self.node[i].y,10,10,self.pen,self.brush) for i in range(len(self.edge)): if self.edge[i].fl == 1: self.colour = QColor(self.edge[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addLine(self.node[self.edge[i].x].x+5,self.node[self.edge[i].x].y+5,self.node[self.edge[i].y].x+5,self.node[self.edge[i].y].y+5,self.pen) if self.function == 4: for i in range(len(self.node)): self.ni1 = abs(self.x1-self.node[i].x) self.ni2 = abs(self.y1-self.node[i].y) if self.ni1<10: if self.ni2<10: if self.s1 == -1: self.s1 = i self.graphicsView.scene.addEllipse(self.node[i].x,self.node[i].y,10,10,self.psel,self.bsel) else: self.s2 = i if self.s1 != -1: if self.s2 != -1: for i in range(len(self.edge)): if self.edge[i].x == self.s1 or self.edge[i].y == self.s1: if self.edge[i].x == self.s2 or self.edge[i].y == self.s2: self.edge[i].fl = 0 self.graphicsView.scene.clear() for i in range(len(self.node)): if self.node[i].fl == 1: self.colour = QColor(self.node[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addEllipse(self.node[i].x,self.node[i].y,10,10,self.pen,self.brush) for i in range(len(self.edge)): if self.edge[i].fl == 1: self.colour = QColor(self.edge[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addLine(self.node[self.edge[i].x].x+5,self.node[self.edge[i].x].y+5,self.node[self.edge[i].y].x+5,self.node[self.edge[i].y].y+5,self.pen) self.s1 = -1 self.s2 = -1 if self.function == 6: for i in range(len(self.node)): self.a1 = abs(self.x1-self.node[i].x) self.a2 = abs(self.y1-self.node[i].y) if self.a1<10: if self.a2<10: self.a3 = i def blos(self): ton = QColorDialog.getColor() self.mm = ton.name() if self.function == 5: G = nx.Graph() for ii in range(len(self.node)): if self.node[ii].color == self.mm or self.vc or self.ind or self.mc: self.node[ii].color = self.node[ii].pcolor if self.node[ii].fl == 1: G.add_node((self.node[ii].x,self.node[ii].y)) for ii in range(len(self.edge)): if self.edge[ii].color == self.mm or self.hp: self.edge[ii].color = self.edge[ii].pcolor if self.edge[ii].fl == 1: G.add_edge((self.node[self.edge[ii].x].x,self.node[self.edge[ii].x].y),(self.node[self.edge[ii].y].x,self.node[self.edge[ii].y].y)) M = nx.Graph() MM = self.find_maximum_matching(G,M) for ii in MM.node(): for i in range(len(self.node)): if ii==(self.node[i].x,self.node[i].y): self.node[i].pcolor = self.node[i].color self.node[i].color = self.mm for ii in MM.edges(): for i in range(len(self.edge)): if ii==((self.node[self.edge[i].x].x,self.node[self.edge[i].x].y),(self.node[self.edge[i].y].x,self.node[self.edge[i].y].y)) or ii==((self.node[self.edge[i].y].x,self.node[self.edge[i].y].y),(self.node[self.edge[i].x].x,self.node[self.edge[i].x].y)): self.edge[i].pcolor = self.edge[i].color self.edge[i].color = self.mm self.graphicsView.scene.clear() for i in range(len(self.node)): if self.node[i].fl == 1: self.colour = QColor(self.node[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addEllipse(self.node[i].x,self.node[i].y,10,10,self.pen,self.brush) for i in range(len(self.edge)): if self.edge[i].fl == 1: self.colour = QColor(self.edge[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addLine(self.node[self.edge[i].x].x+5,self.node[self.edge[i].x].y+5,self.node[self.edge[i].y].x+5,self.node[self.edge[i].y].y+5,self.pen) def move(self,event): self.b = event.localPos() self.x2 = int(self.b.x()) self.y2 = int(self.b.y()) self.min1 = 0 self.mini1=0 self.min2 = 0 self.mini2=0 self.mini3=0 self.mini4=0 self.f1=0 self.f2=0 if self.function == 2: for i in range(len(self.node)): self.mini1 = abs(self.x1-self.node[i].x) self.mini2 = abs(self.y1-self.node[i].y) if self.mini1<10: if self.mini2<10: self.min1 = i self.f1=1 self.mini3 = abs(self.x2-self.node[i].x) self.mini4 = abs(self.y2-self.node[i].y) if self.mini3<10: if self.mini4<10: self.min2 = i self.f2=1 if self.f1==1: if self.f2==1: self.graphicsView.scene.addLine(self.node[self.min1].x+5,self.node[self.min1].y+5,self.node[self.min2].x+5,self.node[self.min2].y+5,self.epen) self.edge.append(st(self.min1,self.min2,1,self.ecolour.name(),self.ecolour.name())) if self.function == 6: self.node[self.a3].x = self.x2 self.node[self.a3].y = self.y2 self.graphicsView.scene.clear() for i in range(len(self.node)): if self.node[i].fl == 1: self.colour = QColor(self.node[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addEllipse(self.node[i].x,self.node[i].y,10,10,self.pen,self.brush) for i in range(len(self.edge)): if self.edge[i].fl == 1: self.colour = QColor(self.edge[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addLine(self.node[self.edge[i].x].x+5,self.node[self.edge[i].x].y+5,self.node[self.edge[i].y].x+5,self.node[self.edge[i].y].y+5,self.pen) def save(self): name = QFileDialog.getSaveFileName(self.centralwidget, 'Save File') file = open(name[0],'w') nl = '\n' sep = ',' file.write(str(len(self.node))) file.write(nl) for i in range(len(self.node)): file.write(str(self.node[i].x)) file.write(nl) file.write(str(self.node[i].y)) file.write(nl) file.write(str(self.node[i].fl)) file.write(nl) file.write(str(self.node[i].pcolor)) file.write(nl) file.write(str(self.node[i].color)) file.write(nl) file.write(str(len(self.edge))) file.write(nl) for i in range(len(self.edge)): file.write(str(self.edge[i].x)) file.write(nl) file.write(str(self.edge[i].y)) file.write(nl) file.write(str(self.edge[i].fl)) file.write(nl) file.write(str(self.edge[i].pcolor)) file.write(nl) file.write(str(self.edge[i].color)) file.write(nl) file.close() def open(self): op = QFileDialog.getOpenFileName(self.centralwidget, 'Open File') fil = open(op[0], 'r') self.graphicsView.scene.clear() self.node.clear() self.edge.clear() nn = int(fil.readline()) for i in range(nn): x = int(fil.readline()) y = int(fil.readline()) fl = int(fil.readline()) pcol = fil.read(7) a = fil.readline() col = fil.read(7) a = fil.readline() self.node.append(st(x,y,fl,pcol,col)) ne = int(fil.readline()) for i in range(ne): x = int(fil.readline()) y = int(fil.readline()) fl = int(fil.readline()) pcol = fil.read(7) a = fil.readline() col = fil.read(7) a = fil.readline() self.edge.append(st(x,y,fl,pcol,col)) for i in range(len(self.node)): if self.node[i].fl == 1: self.colour = QColor(self.node[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addEllipse(self.node[i].x,self.node[i].y,10,10,self.pen,self.brush) for i in range(len(self.edge)): if self.edge[i].fl == 1: self.colour = QColor(self.edge[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addLine(self.node[self.edge[i].x].x+5,self.node[self.edge[i].x].y+5,self.node[self.edge[i].y].x+5,self.node[self.edge[i].y].y+5,self.pen) #min vertex color problem start def isSafe(self, v, colour, c): for i in range(self.l): if self.mat[v][i] == 1 and colour[i] == c: return False return True def graphColourUtil(self, m, colour, v): if v == self.l: return True for c in range(1, m+1): if self.isSafe(v, colour, c) == True: colour[v] = c if self.graphColourUtil(m, colour, v+1) == True: return True colour[v] = 0 def graphColouring(self, m): colour = [0] * self.l if self.graphColourUtil(m, colour, 0) == None: return False for i in range(self.l): if colour[i] == 1: ton = QColor(0,0,0) if colour[i] == 2: ton = QColor(56,27,245) if colour[i] == 3: ton = QColor(51,255,51) if colour[i] == 4: ton = QColor(255,51,153) if colour[i] == 5: ton = QColor(255,255,51) if colour[i] == 6: ton = QColor(27,245,230) self.node[i].color = ton.name() return True def np1(self): self.l = 0 A = nx.Graph() for ii in range(len(self.node)): if self.node[ii].color == self.mm or self.vc or self.iss or self.mc: self.node[ii].color = self.node[ii].pcolor if self.node[ii].fl == 1: A.add_node((self.node[ii].x,self.node[ii].y)) self.l = self.l+1 self.mat = [[0 for i in range(self.l)] for j in range(self.l)] for ii in range(len(self.edge)): if self.edge[ii].color == self.mm or self.hp: self.edge[ii].color = self.edge[ii].pcolor if self.edge[ii].fl == 1: A.add_edge((self.node[self.edge[ii].x].x,self.node[self.edge[ii].x].y),(self.node[self.edge[ii].y].x,self.node[self.edge[ii].y].y)) self.mat[self.edge[ii].x][self.edge[ii].y] = 1 self.mat[self.edge[ii].y][self.edge[ii].x] = 1 self.graphColouring(self.l) self.graphicsView.scene.clear() for i in range(len(self.node)): if self.node[i].fl == 1: self.colour = QColor(self.node[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addEllipse(self.node[i].x,self.node[i].y,10,10,self.pen,self.brush) for i in range(len(self.edge)): if self.edge[i].fl == 1: self.colour = QColor(self.edge[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addLine(self.node[self.edge[i].x].x+5,self.node[self.edge[i].x].y+5,self.node[self.edge[i].y].x+5,self.node[self.edge[i].y].y+5,self.pen) #min vertex color end def approx(self,G): degree_list = [val for (node,val) in G.degree()] VC = list() #vertex cover set max_node = degree_list.index(max(degree_list)) while degree_list[max_node] > 0: degree_list[max_node] = 0 VC.append(max_node) for node in G.neighbors(max_node): degree_list[node] = degree_list[node] - 1 max_node = degree_list.index(max(degree_list)) return VC def np2(self): ton = QColorDialog.getColor() self.vc = ton.name() A = nx.Graph() for ii in range(len(self.node)): if self.node[ii].color == self.mm or self.vc or self.iss or self.mc: self.node[ii].color = self.node[ii].pcolor if self.node[ii].fl == 1: A.add_node(ii) for ii in range(len(self.edge)): if self.edge[ii].color == self.mm or self.hp: self.edge[ii].color = self.edge[ii].pcolor if self.edge[ii].fl == 1: A.add_edge(self.edge[ii].x,self.edge[ii].y) VC = self.approx(A) for i in range(len(VC)): self.node[VC[i]].pcolor = self.node[VC[i]].color self.node[VC[i]].color = self.vc self.graphicsView.scene.clear() for i in range(len(self.node)): if self.node[i].fl == 1: self.colour = QColor(self.node[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addEllipse(self.node[i].x,self.node[i].y,10,10,self.pen,self.brush) for i in range(len(self.edge)): if self.edge[i].fl == 1: self.colour = QColor(self.edge[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addLine(self.node[self.edge[i].x].x+5,self.node[self.edge[i].x].y+5,self.node[self.edge[i].y].x+5,self.node[self.edge[i].y].y+5,self.pen) def np3(self): q = [] ton = QColorDialog.getColor() self.iss = ton.name() A = nx.Graph() for ii in range(len(self.node)): if self.node[ii].color == self.mm or self.vc or self.iss or self.mc: self.node[ii].color = self.node[ii].pcolor if self.node[ii].fl == 1: A.add_node(ii) q.append(1) for ii in range(len(self.edge)): if self.edge[ii].color == self.mm or self.hp: self.edge[ii].color = self.edge[ii].pcolor if self.edge[ii].fl == 1: A.add_edge(self.edge[ii].x,self.edge[ii].y) VC = self.approx(A) for i in range(len(VC)): q[VC[i]] = 0 for i in range(len(q)): if q[i] == 1: self.node[i].pcolor = self.node[i].color self.node[i].color = self.iss self.graphicsView.scene.clear() for i in range(len(self.node)): if self.node[i].fl == 1: self.colour = QColor(self.node[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addEllipse(self.node[i].x,self.node[i].y,10,10,self.pen,self.brush) for i in range(len(self.edge)): if self.edge[i].fl == 1: self.colour = QColor(self.edge[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addLine(self.node[self.edge[i].x].x+5,self.node[self.edge[i].x].y+5,self.node[self.edge[i].y].x+5,self.node[self.edge[i].y].y+5,self.pen) def Safe(self, v, pos, path): if self.graph[path[pos-1]][v] == 0: return False for vertex in path: if vertex == v: return False return True def hamCycleUtil(self, path, pos): if pos == self.V: if self.graph[path[pos-1]][path[0]] == 1: return True else: return False for v in range(1,self.V): if self.Safe(v, pos, path) == True: path[pos] = v if self.hamCycleUtil(path, pos+1) == True: return True path[pos] = -1 return False def hamCycle(self): path = [-1] * self.V path[0] = 0 if self.hamCycleUtil(path,1) == False: QMessageBox.about(self.centralwidget, "Error", "No hamiltonian path found") return False self.printSolution(path) return True def printSolution(self, path): for i in range(len(path)-1): for j in range(len(self.edge)): if self.edge[j].x == path[i] or self.edge[j].y == path[i]: if self.edge[j].y == path[i+1] or self.edge[j].x == path[i+1]: self.edge[j].color = self.hp def np4(self): ton = QColorDialog.getColor() self.hp = ton.name() self.V = 0 A = nx.Graph() for ii in range(len(self.node)): if self.node[ii].color == self.mm or self.vc or self.iss or self.mc: self.node[ii].color = self.node[ii].pcolor if self.node[ii].fl == 1: A.add_node((self.node[ii].x,self.node[ii].y)) self.V = self.V+1 self.graph = [[0 for i in range(self.V)] for j in range(self.V)] for ii in range(len(self.edge)): if self.edge[ii].color == self.mm or self.hp: self.edge[ii].color = self.edge[ii].pcolor if self.edge[ii].fl == 1: A.add_edge((self.node[self.edge[ii].x].x,self.node[self.edge[ii].x].y),(self.node[self.edge[ii].y].x,self.node[self.edge[ii].y].y)) self.graph[self.edge[ii].x][self.edge[ii].y] = 1 self.graph[self.edge[ii].y][self.edge[ii].x] = 1 self.hamCycle() self.graphicsView.scene.clear() for i in range(len(self.node)): if self.node[i].fl == 1: self.colour = QColor(self.node[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addEllipse(self.node[i].x,self.node[i].y,10,10,self.pen,self.brush) for i in range(len(self.edge)): if self.edge[i].fl == 1: self.colour = QColor(self.edge[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addLine(self.node[self.edge[i].x].x+5,self.node[self.edge[i].x].y+5,self.node[self.edge[i].y].x+5,self.node[self.edge[i].y].y+5,self.pen) def np5(self): self.l = 0 ton = QColorDialog.getColor() self.mc = ton.name() q = [] A = nx.Graph() for ii in range(len(self.node)): if self.node[ii].color == self.mm or self.vc or self.iss or self.mc: self.node[ii].color = self.node[ii].pcolor if self.node[ii].fl == 1: A.add_node(ii) self.l = self.l+1 q.append(1) for ii in range(len(self.edge)): if self.edge[ii].color == self.mm or self.hp: self.edge[ii].color = self.edge[ii].pcolor if self.edge[ii].fl == 1: A.add_edge(self.edge[ii].x,self.edge[ii].y) B = nx.Graph() B = nx.complement(A) VC = self.approx(B) for i in range(len(VC)): q[VC[i]] = 0 for i in range(len(q)): if q[i] == 1: self.node[i].pcolor = self.node[i].color self.node[i].color = self.mc for i in range(len(self.edge)): if self.node[self.edge[i].x].color == self.node[self.edge[i].y].color == self.mc: self.edge[i].pcolor = self.edge[i].color self.edge[i].color = self.mc self.graphicsView.scene.clear() for i in range(len(self.node)): if self.node[i].fl == 1: self.colour = QColor(self.node[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addEllipse(self.node[i].x,self.node[i].y,10,10,self.pen,self.brush) for i in range(len(self.edge)): if self.edge[i].fl == 1: self.colour = QColor(self.edge[i].color) self.pen = QPen(self.colour,5) self.brush = QBrush(self.colour) self.graphicsView.scene.addLine(self.node[self.edge[i].x].x+5,self.node[self.edge[i].x].y+5,self.node[self.edge[i].y].x+5,self.node[self.edge[i].y].y+5,self.pen) def processtrigger(self, q): if q.text() == 'Add node': self.function = 1 if q.text() == 'Add edge': self.function = 2 if q.text() == 'Delete node': self.function = 3 if q.text() == 'Delete edge': self.function = 4 if q.text() == 'Max matching': self.function = 5 self.blos() if q.text() == 'Minimum Vertex color': self.np1() if q.text() == 'Vertex Cover': self.np2() if q.text() == 'Independent Set': self.np3() if q.text() == 'Hamiltonian Path': self.np4() if q.text() == 'Max Clique': self.np5() if q.text() == 'Move node': self.function = 6 if q.text() == 'Save File': self.save() if q.text() == 'Open File': self.open() if q.text() == 'Clear Scene': self.graphicsView.scene.clear() self.node.clear() self.edge.clear() if q.text() == 'Edge Color': self.ecolour = QColorDialog.getColor() self.epen = QPen(self.ecolour,5) self.ebrush = QBrush(self.ecolour) if q.text() == 'Node Color': self.ncolour = QColorDialog.getColor() self.npen = QPen(self.ncolour,5) self.nbrush = QBrush(self.ncolour) self.graphicsView.mousePressEvent = self.pixelselect self.graphicsView.mouseReleaseEvent = self.move
class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): '''-------------单选框------------------''' cb = QCheckBox('Show title', self) cb.move(120, 120) cb.toggle() cb.stateChanged.connect(self.changeTitle) '''-------------开关按钮------------------''' self.col = QColor(0, 0, 0) redb = QPushButton('Red', self) redb.setCheckable(True) redb.move(10, 10) redb.clicked.connect(self.setColor) greenb = QPushButton('Green', self) greenb.setCheckable(True) greenb.move(10, 60) greenb.clicked.connect(self.setColor) blueb = QPushButton('Blue', self) blueb.setCheckable(True) blueb.move(10, 110) blueb.clicked.connect(self.setColor) whiteb = QPushButton('white', self) whiteb.setCheckable(True) whiteb.move(10, 180) whiteb.clicked.connect(self.setColor) self.square = QFrame(self) self.square.setGeometry(150, 20, 100, 100) self.square.setStyleSheet('QWidget { background-color:%s}' % self.col.name()) self.setGeometry(300, 300, 400, 420) #x,y,w,h self.setWindowTitle('Icon') self.setWindowIcon(QIcon('web.png')) self.show() def changeTitle(self, state): '''单选框''' if state == Qt.Checked: self.setWindowTitle('QCheckBox') else: self.setWindowTitle('') def setColor(self, pressed): source = self.sender() if pressed: val = 255 else: val = 0 if source.text() == 'Red': self.col.setRed(val) elif source.text() == 'Green': self.col.setGreen(val) elif source.text() == 'white': self.col.setAlpha(val) else: self.col.setBlue(val) self.square.setStyleSheet('QWidget { background-color:%s}' % self.col.name())
class StartTest(QDialog): def __init__(self, parent): super().__init__() loadUi('qt_ui/test.ui', self) self.parent = parent self.all_words = self.parent.words self.words = None self.wrong_words = [] self.num_done = 0 # количество сделанных self.num_true = 0 # количество сделанных правильно self.col_false = QColor(255, 0, 0) self.col_true = QColor(0, 255, 0) self.col = QColor(0, 0, 0) self.lan_remark = None # примечание на нужном языке self.lan_translate = None # слово на нужном языке self.lan_word = None # слово , которое нужно перевести, на нужном языке self.show() self.choose_words() self.initUi() def choose_words(self): self.words = self.all_words # временно def initUi(self): if self.num_done % 2 == 0: self.lan_translate = "english_word" self.lan_word = "russian_word" self.lan_remark = "rus_remark" else: self.lan_word = "english_word" self.lan_language = "russian_word" self.lan_remark = "remark" self.word.setText(self.words[self.num_done]['russian_word']) # append self.remark.setText(self.words[self.num_done]['rus_remark']) self.buttonANSWER.setText('ANSWER') self.buttonANSWER.autoDefault() self.buttonANSWER.clicked.connect(self.button_answer) self.buttonSTOP.clicked.connect(self.button_stop) self.progress.setRange(1, len(self.words)) self.update_progress() def button_answer(self): print('button ANSWER clicked') if self.num_done % 2 == 0: self.lan_translate = "english_word" self.lan_word = "russian_word" self.lan_remark = "rus_remark" else: self.lan_word = "english_word" self.lan_translate = "russian_word" self.lan_remark = "remark" self.translated_word.setStyleSheet("QTextEdit { color: %s }" % self.col.name()) print(self.lan_translate) print(self.lan_word) if line_treatment(self.translated_word.toPlainText()) == self.words[self.num_done][self.lan_translate]: # если слово введено правильно print('YES') self.translated_word.setStyleSheet( "QTextEdit { color: %s }" % self.col_true.name()) # меняю цвет текста на зеленый self.num_true += 1 self.words[self.num_done]["rating"] -= 10 else: print('NO') self.wrong_words.append(self.words[self.num_done]) self.error.setText(self.words[self.num_done][self.lan_translate]) # выводим правильный ответ self.translated_word.setStyleSheet( "QTextEdit { color: %s }" % self.col_false.name()) # меняю цвет текста на красный self.buttonANSWER.setText('Next') # меняю название кнопки self.buttonANSWER.clicked.connect(self.answ_next) self.buttonANSWER.clicked.disconnect(self.button_answer) def answ_next(self): print('button NEXT clicked') self.num_done += 1 if self.num_done % 2 == 0: self.lan_translate = "english_word" self.lan_word = "russian_word" self.lan_remark = "rus_remark" else: self.lan_word = "english_word" self.lan_translate = "russian_word" self.lan_remark = "remark" self.translated_word.setStyleSheet("QTextEdit { color: %s }" % self.col.name()) # возвращаю черный цвет текста self.buttonANSWER.setText('ANSWER') # меняю название кнопки self.buttonANSWER.clicked.connect(self.button_answer) self.buttonANSWER.clicked.disconnect(self.answ_next) if self.num_done < len(self.words): self.translated_word.clear() self.word.clear() self.error.clear() self.word.setText(self.words[self.num_done][self.lan_word]) # append self.remark.setText(self.words[self.num_done][self.lan_remark]) self.update_progress() if self.num_done >= len(self.words): self.complete() def button_stop(self): self.question_ex = Exit_question(self) def update_progress(self): self.progress.setValue(self.num_done + 1) self.partProcess.setText('%s / %s' % (str(self.num_done + 1), str(len(self.words)))) def complete(self): self.results = Results(self) self.close()
def __init__(self): super().__init__() self.dialog = uic.loadUi("demoColorChooseDialog.ui", self) # načtení formuláře col = QColor(0,0,0) # init barva je černá self.widget.setStyleSheet("QWidget {background-color: %s }" % col.name()) self.show()
def get_hex_color(color: QColor): return int(color.name().replace("#", ""), 16)
class Window(QWidget): def __init__(self): super().__init__() self.size_h = 600 self.size_w = 1000 self.setGeometry(200, 200, self.size_w, self.size_h) self.setFixedSize(self.size_w, self.size_h) self.setWindowTitle("Растровый редактор") self.points = [] self.preview = {} for _ in range(self.size_w): self.points.append([0 for _ in range(self.size_h)]) self.qp = QPainter() self.width = 0 self.left_x = 0 self.top_y = 0 self.height = 0 self.last_x = 0 self.last_y = 0 h_layout = QHBoxLayout() h_layout.addStretch(1) v_layout = QVBoxLayout() v_layout.addStretch(1) self.option = Instruments.pen self.thickness = 1 self.color = QColor(0, 0, 0) self.color_changer = QPushButton(self) self.color_changer.setFixedSize(30, 30) self.color_changer.setStyleSheet("background: black") self.color_changer.clicked[bool].connect(self.change_color) self.thick_changer = QSlider(Qt.Horizontal, self) self.thick_changer.setRange(1, 9) self.thick_changer.setFixedSize(50, 10) self.thick_changer.valueChanged[int].connect(self.change_thickness) self.thick_lab = QLabel("W: 1", self) pen = Button("Перо", Instruments.pen, self) pen.clicked[bool].connect(self.change_option) line = Button("Линия", Instruments.line, self) line.clicked[bool].connect(self.change_option) rect = Button("Прямоугольник", Instruments.rect, self) rect.clicked[bool].connect(self.change_option) fill = Button("Заливка", Instruments.fill, self) fill.clicked[bool].connect(self.change_option) clean = QPushButton("Очистить", self) clean.clicked[bool].connect(self.clean) save = QPushButton("Сохранить", self) save.clicked[bool].connect(self.save) load = QPushButton("Загрузить", self) load.clicked[bool].connect(self.load) h_layout.addWidget(save) h_layout.addWidget(load) h_layout.addWidget(self.thick_lab) h_layout.addWidget(self.thick_changer) h_layout.addWidget(pen) h_layout.addWidget(line) h_layout.addWidget(rect) h_layout.addWidget(fill) h_layout.addWidget(clean) h_layout.addWidget(self.color_changer) v_layout.addLayout(h_layout) self.setLayout(v_layout) self.figure_x1 = 0 self.figure_y1 = 0 def clean(self): for i in range(self.size_w): for j in range(self.size_h): self.points[i][j] = 0 self.left_x = 0 self.top_y = 0 self.width = self.size_w self.height = self.size_h self.repaint() def change_color(self): self.color = QColorDialog.getColor() self.color_changer.setStyleSheet("background: %s" % self.color.name()) self.top_y = 0 self.left_x = 0 self.width = self.size_w self.height = self.size_h self.repaint(self.left_x, self.top_y, self.width, self.height) def change_option(self): sender = self.sender() self.option = sender.option def change_thickness(self): self.thickness = self.thick_changer.value() self.thick_lab.setText("W: "+str(self.thickness)) def save(self): image = Image.new('RGB', (self.size_w, self.size_h), (0, 0, 0, 0)) drawer = ImageDraw.Draw(image) for i in range(self.size_w): for j in range(self.size_h): if self.points[i][j]: drawer.point((i, j), (self.points[i][j].red(),\ self.points[i][j].green(),\ self.points[i][j].blue())) else: drawer.point((i, j), tuple([255, 255, 255])) name = QFileDialog.getSaveFileName(self, filter="Images (*.png)")[0] if name: image.save(name, 'PNG') self.left_x = 0 self.top_y = 0 self.width = self.size_w self.height = self.size_h self.repaint() def load(self): picture_name = QFileDialog.getOpenFileName(self)[0] if picture_name.split('.')[-1] != 'png' or not picture_name: return image = Image.open(picture_name) data = image.load() size_y = min(image.size[1], self.size_h) size_x = min(image.size[0], self.size_w) for x in range(size_x): for y in range(size_y): x_y = data[x, y] self.points[x][y] = QColor(x_y[0], x_y[1], x_y[2]) self.left_x = 0 self.top_y = 0 self.width = self.size_w self.height = self.size_h self.repaint() def mousePressEvent(self, event): x = event.x() y = event.y() if self.option == Instruments.pen: logic.add_thickness_point(self.points, x, y, self.color, self.thickness) elif self.option == Instruments.line: self.figure_x1 = x self.figure_y1 = y elif self.option == Instruments.rect: self.figure_x1 = x self.figure_y1 = y else: logic.brush(x, y, self.points, self.color, self.size_w, self.size_h) self.left_x = 0 self.top_y = 0 self.width = self.size_w self.height = self.size_h self.repaint() return self.last_x = x self.last_y = y self.left_x = x-self.thickness self.width = 2*self.thickness self.top_y = y-self.thickness self.height = 2*self.thickness self.repaint(self.left_x, self.top_y, self.width, self.height) def mouseMoveEvent(self, event): x = event.x() y = event.y() if -1 < x < self.size_w-self.thickness and -1 < y < self.size_h-self.thickness: self.left_x = int(min(x, self.last_x)) - self.thickness self.top_y = int(min(y, self.last_y)) - self.thickness self.width = int(abs(self.left_x-max(x, self.last_x)))+self.thickness self.height = int(abs(self.top_y-max(y, self.last_y)))+self.thickness else: return if self.option == Instruments.pen: logic.draw_line(x, y, self.last_x, self.last_y, self.points, self.color, self.thickness) self.last_x = x self.last_y = y elif self.option == Instruments.line: self.preview.clear() logic.draw_line(x, y, self.figure_x1, self.figure_y1, self.preview, self.color, self.thickness) elif self.option == Instruments.rect: self.preview.clear() logic.draw_rect(x, y, self.figure_x1, self.figure_y1, self.preview, self.color, self.thickness) self.repaint(self.left_x, self.top_y, self.width, self.height) def mouseReleaseEvent(self, event): if self.option == Instruments.line or self.option == Instruments.rect: self.figure_x1 = 0 self.figure_y1 = 0 for point, color in self.preview.items(): self.points[point[0]][point[1]] = color self.preview.clear() self.top_y = 0 self.left_x = 0 self.width = self.size_w self.height = self.size_h self.repaint(0, 0, self.size_w, self.size_h) def paintEvent(self, QPaintEvent): self.qp.begin(self) for i in range(self.left_x, self.left_x+self.width): for j in range(self.top_y, self.top_y+self.height): if self.points[i][j]: self.qp.setPen(self.points[i][j]) self.qp.drawPoint(i, j) for point, color in self.preview.items(): self.qp.setPen(color) self.qp.drawPoint(point[0], point[1]) self.qp.end()
def changeBackgroundColor(self, color:QColor): self.setStyleSheet("#Custom_Main_Widget {background: %s;}"%(color.name())) #self.startBackground.setBackgroundColor(color) self.animator.setBackgroundColor(color) self.hueEditor.setBackgroundColor(color) self.backgroundColor = color
def paint_v2(self, p, option, index): # QStyledItemDelegate.paint(self, p, option, index) if not index.isValid(): return item = index.internalPointer() self.updateRects(option, index) colors = outlineItemColors(item) style = qApp.style() def _rotate(angle, rect=self.mainRect): p.translate(rect.center()) p.rotate(angle) p.translate(-rect.center()) def drawRect(r): p.save() p.setBrush(Qt.gray) p.drawRect(r) p.restore() # Draw background cg = QPalette.ColorGroup(QPalette.Normal if option.state & QStyle.State_Enabled else QPalette.Disabled) if cg == QPalette.Normal and not option.state & QStyle.State_Active: cg = QPalette.Inactive # Selection if option.state & QStyle.State_Selected: p.save() p.setBrush(option.palette.brush(cg, QPalette.Highlight)) p.setPen(Qt.NoPen) #p.drawRoundedRect(option.rect, 12, 12) p.drawRect(option.rect) p.restore() # Background p.save() if settings.viewSettings["Cork"]["Background"] != "Nothing": c = colors[settings.viewSettings["Cork"]["Background"]] if c == QColor(Qt.transparent): c = QColor(Qt.white) col = mixColors(c, QColor(Qt.white), .2) backgroundColor = col p.setBrush(col) else: p.setBrush(Qt.white) backgroundColor = QColor(Qt.white) # Cache background color self.bgColors[index] = backgroundColor.name() p.setPen(Qt.NoPen) p.drawRect(self.cardRect) if item.isFolder(): itemPoly = QPolygonF([ self.topRect.topLeft(), self.topRect.topLeft() + QPoint(self.topRect.width() * .35, 0), self.cardRect.topLeft() + QPoint(self.topRect.width() * .45, 0), self.cardRect.topRight(), self.cardRect.bottomRight(), self.cardRect.bottomLeft() ]) p.drawPolygon(itemPoly) p.restore() # Label color if settings.viewSettings["Cork"]["Corner"] != "Nothing": p.save() color = colors[settings.viewSettings["Cork"]["Corner"]] p.setPen(Qt.NoPen) p.setBrush(color) p.drawRect(self.labelRect) w = self.labelRect.width() poly = QPolygonF([ self.labelRect.bottomLeft() + QPointF(0, 1), self.labelRect.bottomLeft() + QPointF(0, w / 2), self.labelRect.bottomLeft() + QPointF(w / 2, 1), self.labelRect.bottomRight() + QPointF(1, w / 2), self.labelRect.bottomRight() + QPointF(1, 1), ]) p.drawPolygon(poly) p.restore() if settings.viewSettings["Cork"]["Corner"] == "Nothing" or \ color == Qt.transparent: # No corner, so title can be full width self.titleRect.setRight(self.mainRect.right()) # Draw the icon iconRect = self.iconRect mode = QIcon.Normal if not option.state & style.State_Enabled: mode = QIcon.Disabled elif option.state & style.State_Selected: mode = QIcon.Selected # index.data(Qt.DecorationRole).paint(p, iconRect, option.decorationAlignment, mode) icon = index.data(Qt.DecorationRole).pixmap(iconRect.size()) if settings.viewSettings["Cork"]["Icon"] != "Nothing": color = colors[settings.viewSettings["Cork"]["Icon"]] colorifyPixmap(icon, color) QIcon(icon).paint(p, iconRect, option.decorationAlignment, mode) # Draw title p.save() text = index.data() if text: p.setPen(Qt.black) textColor = QColor(Qt.black) if settings.viewSettings["Cork"]["Text"] != "Nothing": col = colors[settings.viewSettings["Cork"]["Text"]] if col == Qt.transparent: col = Qt.black # If title setting is compile, we have to hack the color # Or we won't see anything in some themes if settings.viewSettings["Cork"]["Text"] == "Compile": if item.compile() in [0, "0"]: col = mixColors(QColor(Qt.black), backgroundColor) else: col = Qt.black textColor = col p.setPen(col) f = QFont(option.font) f.setPointSize(f.pointSize() + 4) f.setBold(True) p.setFont(f) fm = QFontMetrics(f) elidedText = fm.elidedText(text, Qt.ElideRight, self.titleRect.width()) p.drawText(self.titleRect, Qt.AlignLeft | Qt.AlignVCenter, elidedText) p.restore() # One line summary background lineSummary = item.data(Outline.summarySentence) fullSummary = item.data(Outline.summaryFull) # Border if settings.viewSettings["Cork"]["Border"] != "Nothing": p.save() p.setBrush(Qt.NoBrush) pen = p.pen() pen.setWidth(2) col = colors[settings.viewSettings["Cork"]["Border"]] pen.setColor(col) p.setPen(pen) if item.isFolder(): p.drawPolygon(itemPoly) else: p.drawRect(self.cardRect) p.restore() # Draw status status = item.data(Outline.status) if status: it = mainWindow().mdlStatus.item(int(status), 0) if it != None: p.save() p.setClipRegion(QRegion(self.cardRect)) f = p.font() f.setPointSize(f.pointSize() + 12) f.setBold(True) p.setFont(f) p.setPen(QColor(Qt.red).lighter(170)) _rotate(-35, rect=self.cardRect) p.drawText(self.cardRect, Qt.AlignCenter, it.text()) p.restore() # Draw Summary # One line if lineSummary: p.save() f = QFont(option.font) f.setBold(True) p.setFont(f) p.setPen(textColor) fm = QFontMetrics(f) elidedText = fm.elidedText(lineSummary, Qt.ElideRight, self.mainLineRect.width()) p.drawText(self.mainLineRect, Qt.AlignLeft | Qt.AlignVCenter, elidedText) p.restore() # Full summary if fullSummary: p.save() p.setFont(option.font) p.setPen(textColor) p.drawText(self.mainTextRect, Qt.TextWordWrap, fullSummary) p.restore()
class QtImageAnnotator(QGraphicsView): # Mouse button signals emit image scene (x, y) coordinates. # !!! For image (row, column) matrix indexing, row = y and column = x. leftMouseButtonPressed = pyqtSignal(float, float) middleMouseButtonPressed = pyqtSignal(float, float) rightMouseButtonPressed = pyqtSignal(float, float) leftMouseButtonReleased = pyqtSignal(float, float) middleMouseButtonReleased = pyqtSignal(float, float) rightMouseButtonReleased = pyqtSignal(float, float) leftMouseButtonDoubleClicked = pyqtSignal(float, float) middleMouseButtonDoubleClicked = pyqtSignal(float, float) rightMouseButtonDoubleClicked = pyqtSignal(float, float) mouseWheelRotated = pyqtSignal(float) def __init__(self): QGraphicsView.__init__(self) # Image is displayed as a QPixmap in a QGraphicsScene attached to this QGraphicsView. self.scene = QGraphicsScene() self.setScene(self.scene) # Shape of the loaded image (height, width) self.shape = (None, None) # Store a local handle to the scene's current image pixmap. self._pixmapHandle = None # This holds the image self._helperHandle = None # This holds the "helper" overlay which is not directly manipulated by the user self._auxHelper = None # Aux helper for various purpuses self._overlayHandle = None # This is the overlay over which we are painting self._cursorHandle = None # This is the cursor that appears to assist with brush size self._deleteCrossHandles = None # For showing that we've activated delete mode # Helper display state self.showHelper = True self._lastCursorCoords = None # Latest coordinates of the cursor, need in some cursor overlay update operations self._overlay_stack = collections.deque(maxlen=MAX_CTRLZ_STATES) # Offscreen mask, used to speed things up (but has an impact on painting speed) self._offscreen_mask = None self._offscreen_mask_stack = collections.deque(maxlen=MAX_CTRLZ_STATES) # Needed for proper drawing self.lastPoint = QPoint() self.lastCursorLocation = QPoint() # Direct mask painting self.direct_mask_paint = False # Pixmap that contains the mask and the corresponding painter self.mask_pixmap = None # Parameters of the brush and paint self.brush_diameter = 50 self.MIN_BRUSH_DIAMETER = 1 self.MAX_BRUSH_DIAMETER = 500 self.brush_fill_color = QColor(255, 0, 0, 99) # Zoom in modifier: this should be between 4 and 20 self.zoom_in_modifier = 4 # Painting and erasing modes #self.MODE_PAINT = QPainter.RasterOp_SourceOrDestination self.MODE_PAINT = QPainter.CompositionMode_Source self.MODE_ERASE = QPainter.CompositionMode_Clear self.current_painting_mode = self.MODE_PAINT self.global_erase_override = False # Mask related. This will allow to automatically create overlays given grayscale masks # and also save grayscale masks from RGB drawings. Both dicts must be provided for the # related functions to work properly (cannot assume unique key-value combinations) self.d_rgb2gray = None self.d_gray2rgb = None # Make mouse events accessible self.setMouseTracking(True) # Image aspect ratio mode. # Qt.IgnoreAspectRatio: Scale image to fit viewport. # Qt.KeepAspectRatio: Scale image to fit inside viewport, preserving aspect ratio. # Qt.KeepAspectRatioByExpanding: Scale image to fill the viewport, preserving aspect ratio. self.aspectRatioMode = Qt.KeepAspectRatio # Scroll bar behaviour. # Qt.ScrollBarAlwaysOff: Never shows a scroll bar. # Qt.ScrollBarAlwaysOn: Always shows a scroll bar. # Qt.ScrollBarAsNeeded: Shows a scroll bar only when zoomed. self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) # Stack of QRectF zoom boxes in scene coordinates. self.zoomStack = [] # Flags for enabling/disabling mouse interaction. self.canZoom = True self.canPan = True def hasImage(self): """ Returns whether or not the scene contains an image pixmap. """ return self._pixmapHandle is not None # def paintEvent(self, event): # painter = QPainter(self) # # if self._pixmapHandle is not None: # painter.drawPixmap(self.rect(), self._pixmapHandle) # if self._overlayHandle is not None: # print("This isn't implemented yet") # if self._cursorHandle is not None: # painter.drawEllipse(self.rect(), self._cursorHandle) def clearImage(self): """ Removes the current image pixmap from the scene if it exists. """ if self.hasImage(): self.scene.removeItem(self._pixmapHandle) self._pixmapHandle = None def pixmap(self): """ Returns the scene's current image pixmap as a QPixmap, or else None if no image exists. :rtype: QPixmap | None """ if self.hasImage(): return self._pixmapHandle.pixmap() return None def image(self): """ Returns the scene's current image pixmap as a QImage, or else None if no image exists. :rtype: QImage | None """ if self.hasImage(): return self._pixmapHandle.pixmap().toImage() return None # Configure the annotator with data. # NB! Breaking change. Both IMAGE and MASK arguments from version 1.0b are # **assumed** to be numpy arrays! # # Named arguments: # helper = additional layer which helps with the annotation process, its display can be toggled # process_gray2rgb = whether the mask is supplied as a grayscale image which should be converted # to RGB on initialization (this process is rather fast). Conversion dictionaries must be set. # direct_mask_paint = to speed up multicolor mask export, it may be beneficial to draw directly # on a hidden mask. Then, exporting it is super fast compared to converting the RGB mask to # a grayscale one. def clearAndSetImageAndMask(self, image, mask, helper=None, aux_helper=None, process_gray2rgb=False, direct_mask_paint=False): # Clear the scene self.scene.clear() # Set direct mask painting mode self.direct_mask_paint = direct_mask_paint # Clear handles self._pixmapHandle = None self._helperHandle = None self._auxHelper = None self._overlayHandle = None # Clear UNDO stack self._overlay_stack = collections.deque(maxlen=MAX_CTRLZ_STATES) # For compatibility, convert IMAGE to QImage, if needed if type(image) is np.array: image = array2qimage(image) # First we just set the image if type(image) is QPixmap: pixmap = image elif type(image) is QImage: pixmap = QPixmap.fromImage(image) else: raise RuntimeError( "QtImageAnnotator.clearAndSetImageAndMask: Argument must be a QImage or QPixmap." ) self.shape = pixmap.height(), pixmap.width() self._pixmapHandle = self.scene.addPixmap(pixmap) self.setSceneRect(QRectF(pixmap.rect())) # Off-screen mask for direct drawing if direct_mask_paint: # We need to convert the offscreen mask to QImage at this point gray_mask = QImage(mask.data, mask.shape[1], mask.shape[0], mask.strides[0], QImage.Format_Grayscale8) self._offscreen_mask = gray_mask.copy() self._offscreen_mask_stack = collections.deque( maxlen=MAX_CTRLZ_STATES) # Now we add the helper, if present if type(helper) is np.array: helper = array2qimage(helper) if helper is not None: if type(helper) is QPixmap: pixmap = helper elif type(helper) is QImage: pixmap = QPixmap.fromImage(helper) else: raise RuntimeError( "QtImageAnnotator.clearAndSetImageAndMask: Argument must be a QImage or QPixmap." ) # Add the helper layer self._helperHandle = self.scene.addPixmap(pixmap) if type(aux_helper) is np.array: aux_helper = array2qimage(aux_helper) if aux_helper is not None: if type(aux_helper) is QPixmap: pixmap = aux_helper elif type(aux_helper) is QImage: pixmap = QPixmap.fromImage(aux_helper) else: raise RuntimeError( "QtImageAnnotator.clearAndSetImageAndMask: Argument must be a QImage or QPixmap." ) # Add the aux helper layer self._auxHelper = self.scene.addPixmap(pixmap) # If we are supplied a grayscale mask that we need to convert to RGB, we will do it here if process_gray2rgb: if self.d_gray2rgb: # We assume mask is np array, grayscale and the conversion rules are set (otherwise cannot continue) h, w = mask.shape new_mask = np.zeros((h, w, 4), np.uint8) for gr, rgb in self.d_gray2rgb.items(): col = QColor("#63" + rgb.split("#")[1]).getRgb( ) # TODO: not elegant, need external function new_mask[mask == gr] = col use_mask = array2qimage(new_mask) else: raise RuntimeError( "Cannot convert the provided grayscale mask to RGB without color specifications." ) else: use_mask = array2qimage(mask) pixmap = QPixmap.fromImage(use_mask) self.mask_pixmap = pixmap self._overlayHandle = self.scene.addPixmap(self.mask_pixmap) # Add brush cursor to top layer self._cursorHandle = self.scene.addEllipse(0, 0, self.brush_diameter, self.brush_diameter) # Add also X to the cursor for "delete" operation, and hide it by default only showing it when the # either the global drawing mode is set to ERASE or when CTRL is held while drawing self._deleteCrossHandles = (self.scene.addLine(0, 0, self.brush_diameter, self.brush_diameter), self.scene.addLine(0, self.brush_diameter, self.brush_diameter, 0)) if self.current_painting_mode is not self.MODE_ERASE: self._deleteCrossHandles[0].hide() self._deleteCrossHandles[1].hide() self.updateViewer() # Clear everything def clearAll(self): self.shape = (None, None) if self._pixmapHandle is not None: self.scene.removeItem(self._pixmapHandle) if self._helperHandle is not None: self.scene.removeItem(self._helperHandle) if self._auxHelper is not None: self.scene.removeItem(self._auxHelper) if self._overlayHandle is not None: self.scene.removeItem(self._overlayHandle) self._pixmapHandle = None self._helperHandle = None self._auxHelper = None self._overlayHandle = None if self.direct_mask_paint: self._offscreen_mask = None self._offscreen_mask_stack = collections.deque( maxlen=MAX_CTRLZ_STATES) self._overlay_stack = collections.deque(maxlen=MAX_CTRLZ_STATES) self.updateViewer() # Set image only def setImage(self, image): """ Set the scene's current image pixmap to the input QImage or QPixmap. Raises a RuntimeError if the input image has type other than QImage or QPixmap. :type image: QImage | QPixmap | numpy.array """ if type(image) is np.array: image = array2qimage(image) if type(image) is QPixmap: pixmap = image elif type(image) is QImage: pixmap = QPixmap.fromImage(image) else: raise RuntimeError( "ImageViewer.setImage: Argument must be a QImage or QPixmap.") if self.hasImage(): self._pixmapHandle.setPixmap(pixmap) else: self._pixmapHandle = self.scene.addPixmap(pixmap) self.setSceneRect(QRectF( pixmap.rect())) # Set scene size to image size. # Add the mask layer self.mask_pixmap = QPixmap(pixmap.rect().width(), pixmap.rect().height()) self.mask_pixmap.fill(QColor(0, 0, 0, 0)) self._overlayHandle = self.scene.addPixmap(self.mask_pixmap) # Add brush cursor to top layer self._cursorHandle = self.scene.addEllipse(0, 0, self.brush_diameter, self.brush_diameter) # Add also X to the cursor for "delete" operation, and hide it by default only showing it when the # either the global drawing mode is set to ERASE or when CTRL is held while drawing self._deleteCrossHandles = (self.scene.addLine(0, 0, self.brush_diameter, self.brush_diameter), self.scene.addLine(0, self.brush_diameter, self.brush_diameter, 0)) if self.current_painting_mode is not self.MODE_ERASE: self._deleteCrossHandles[0].hide() self._deleteCrossHandles[1].hide() self.updateViewer() def loadImageFromFile(self, fileName=""): """ Load an image from file. Without any arguments, loadImageFromFile() will popup a file dialog to choose the image file. With a fileName argument, loadImageFromFile(fileName) will attempt to load the specified image file directly. """ if len(fileName) == 0: if QT_VERSION_STR[0] == '4': fileName = QFileDialog.getOpenFileName(self, "Open image file.") elif QT_VERSION_STR[0] == '5': fileName, dummy = QFileDialog.getOpenFileName( self, "Open image file.") if len(fileName) and os.path.isfile(fileName): image = QImage(fileName) self.setImage(image) def updateViewer(self): """ Show current zoom (if showing entire image, apply current aspect ratio mode). """ if not self.hasImage(): return if len(self.zoomStack) and self.sceneRect().contains( self.zoomStack[-1]): self.fitInView(self.zoomStack[-1], self.aspectRatioMode) # Show zoomed rect else: self.zoomStack = [ ] # Clear the zoom stack (in case we got here because of an invalid zoom). self.fitInView( self.sceneRect(), self.aspectRatioMode ) # Show entire image (use current aspect ratio mode). def resizeEvent(self, event): """ Maintain current zoom on resize. """ self.updateViewer() def update_brush_diameter(self, change): val = self.brush_diameter val += change if val > self.MAX_BRUSH_DIAMETER: val = self.MAX_BRUSH_DIAMETER if val < self.MIN_BRUSH_DIAMETER: val = self.MIN_BRUSH_DIAMETER self.brush_diameter = val if self._lastCursorCoords is not None: x, y = self._lastCursorCoords else: x, y = 0, 0 if self._cursorHandle is not None: self._cursorHandle.setPos(x - self.brush_diameter / 2, y - self.brush_diameter / 2) self._cursorHandle.setRect(0, 0, self.brush_diameter, self.brush_diameter) if self._deleteCrossHandles is not None: self._deleteCrossHandles[0].setLine( x - self.brush_diameter / (2 * np.sqrt(2)), y - self.brush_diameter / (2 * np.sqrt(2)), x + self.brush_diameter / (2 * np.sqrt(2)), y + self.brush_diameter / (2 * np.sqrt(2))) self._deleteCrossHandles[1].setLine( x - self.brush_diameter / (2 * np.sqrt(2)), y + self.brush_diameter / (2 * np.sqrt(2)), x + self.brush_diameter / (2 * np.sqrt(2)), y - self.brush_diameter / (2 * np.sqrt(2))) def update_cursor_location(self, event): scenePos = self.mapToScene(event.pos()) x, y = scenePos.x(), scenePos.y() # Store the coordinates for other operations to use self._lastCursorCoords = (x, y) if self._cursorHandle is not None: self._cursorHandle.setPos(x - self.brush_diameter / 2, y - self.brush_diameter / 2) if self._deleteCrossHandles is not None: self._deleteCrossHandles[0].setLine( x - self.brush_diameter / (2 * np.sqrt(2)), y - self.brush_diameter / (2 * np.sqrt(2)), x + self.brush_diameter / (2 * np.sqrt(2)), y + self.brush_diameter / (2 * np.sqrt(2))) self._deleteCrossHandles[1].setLine( x - self.brush_diameter / (2 * np.sqrt(2)), y + self.brush_diameter / (2 * np.sqrt(2)), x + self.brush_diameter / (2 * np.sqrt(2)), y - self.brush_diameter / (2 * np.sqrt(2))) def redraw_cursor(self): if self._cursorHandle is not None: self._cursorHandle.update() if self._deleteCrossHandles is not None: self._deleteCrossHandles[0].update() self._deleteCrossHandles[1].update() # Draws a single ellipse def fillMarker(self, event): scenePos = self.mapToScene(event.pos()) painter = QPainter(self.mask_pixmap) painter.setCompositionMode(self.current_painting_mode) painter.setPen(self.brush_fill_color) painter.setBrush(self.brush_fill_color) # Get the coordinates of where to draw a0 = scenePos.x() - self.brush_diameter / 2 b0 = scenePos.y() - self.brush_diameter / 2 r0 = self.brush_diameter # Finally, draw painter.drawEllipse(a0, b0, r0, r0) # TODO: With really large images, update is rather slow. Must somehow fix this. # It seems that the way to approach hardcore optimization is to switch to OpenGL # for all rendering purposes. This update will likely come much later in the tool's # lifecycle. self._overlayHandle.setPixmap(self.mask_pixmap) # In case of direct mask paint mode, we need to paint on the mask as well if self.direct_mask_paint: if not self.d_rgb2gray: raise RuntimeError( "Cannot use direct mask painting since there is no color conversion rules set." ) painter = QPainter(self._offscreen_mask) painter.setCompositionMode(self.current_painting_mode) tc = self.d_rgb2gray[self.brush_fill_color.name()] painter.setPen(QColor(tc, tc, tc)) painter.setBrush(QColor(tc, tc, tc)) painter.drawEllipse(a0, b0, r0, r0) self.lastPoint = scenePos # Draws a line def drawMarkerLine(self, event): scenePos = self.mapToScene(event.pos()) painter = QPainter(self.mask_pixmap) painter.setCompositionMode(self.current_painting_mode) painter.setPen( QPen(self.brush_fill_color, self.brush_diameter, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) painter.drawLine(self.lastPoint, scenePos) self._overlayHandle.setPixmap(self.mask_pixmap) # In case of direct mask paint mode, we need to paint on the mask as well if self.direct_mask_paint: if not self.d_rgb2gray: raise RuntimeError( "Cannot use direct mask painting since there is no color conversion rules set." ) painter = QPainter(self._offscreen_mask) painter.setCompositionMode(self.current_painting_mode) tc = self.d_rgb2gray[self.brush_fill_color.name()] painter.setPen( QPen(QColor(tc, tc, tc), self.brush_diameter, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) painter.drawLine(self.lastPoint, scenePos) self.lastPoint = scenePos # Fills an area using the last stored cursor location # If optional argument remove_closed_contour is set to True, then # the closed contour over which the cursor is hovering will be erased def fillArea(self, remove_closed_contour=False, remove_only_current_color=True): # Store previous state so we can go back to it self._overlay_stack.append(self.mask_pixmap.copy()) if self.direct_mask_paint: self._offscreen_mask_stack.append(self._offscreen_mask.copy()) # We first convert the mask to a QImage and then to ndarray orig_mask = self.mask_pixmap.toImage().convertToFormat( QImage.Format_ARGB32) msk = alpha_view(orig_mask).copy() # Apply simple tresholding and invert the image msk[np.where((msk > 0))] = 255 msk = 255 - msk msk1 = np.copy(msk) if remove_closed_contour: msk1 = 255 - msk1 if remove_closed_contour: if remove_only_current_color: the_mask = np.ones(msk1.shape[:2], np.uint8) * 255 # Initial mask fullmask = self.export_ndarray_noalpha( ) # Get the colored version reds, greens, blues = fullmask[:, :, 0], fullmask[:, :, 1], fullmask[:, :, 2] cur_col = list(self.brush_fill_color.getRgb() )[:-1] # Only current color is considered # So that fill happens only for this specific color the_mask[ np.isclose(reds, cur_col[0], atol=PIXMAP_CONV_BUG_ATOL) & np.isclose(greens, cur_col[1], atol=PIXMAP_CONV_BUG_ATOL) & np.isclose(blues, cur_col[2], atol=PIXMAP_CONV_BUG_ATOL)] = 0 else: the_mask = np.zeros(msk1.shape[:2], np.uint8) else: the_mask = cv2.bitwise_not(np.copy(msk)) the_mask = cv2.copyMakeBorder(the_mask, 1, 1, 1, 1, cv2.BORDER_CONSTANT, 0) # Fill the contour seed_point = (int(self.lastCursorLocation.x()), int(self.lastCursorLocation.y())) cv2.floodFill(msk1, the_mask, seed_point, 0, 0, 1) # We paint in only the newly arrived pixels (or remove the pixels in the contour) if remove_closed_contour: paintin = msk1 else: paintin = msk - msk1 # This is fill case # Take original pixmap image: it has two components, RGB and ALPHA new_img = np.dstack((rgb_view(orig_mask), alpha_view(orig_mask))) # Fill the newly created area with current brush color if not remove_closed_contour: new_img[np.where( (paintin == 255))] = list(self.brush_fill_color.getRgb()) else: new_img[np.where((paintin == 0))] = (0, 0, 0, 0) # Erase new_qimg = array2qimage(new_img) # In case of direct drawing, need to update the offscreen mask as well if self.direct_mask_paint: omask = byte_view(self._offscreen_mask).copy() omask = omask.reshape(omask.shape[:-1]) if not remove_closed_contour: tc = self.d_rgb2gray[self.brush_fill_color.name()] omask[np.where((paintin == 255))] = tc else: omask[np.where((paintin == 0))] = 0 self._offscreen_mask = QImage(omask.data, omask.shape[1], omask.shape[0], omask.strides[0], QImage.Format_Grayscale8) # Finally update the screen stuff self.mask_pixmap = QPixmap.fromImage(new_qimg) self._overlayHandle.setPixmap(self.mask_pixmap) # Repaint connected contour (disregarding color information) to the current paint color def repaintArea(self): self._overlay_stack.append(self.mask_pixmap.copy()) if self.direct_mask_paint: self._offscreen_mask_stack.append(self._offscreen_mask.copy()) orig_mask = self.mask_pixmap.toImage().convertToFormat( QImage.Format_ARGB32) msk = alpha_view(orig_mask).copy() msk[np.where((msk > 0))] = 255 msk = 255 - msk msk1 = 255 - np.copy(msk) the_mask = cv2.copyMakeBorder(np.zeros(msk1.shape[:2], np.uint8), 1, 1, 1, 1, cv2.BORDER_CONSTANT, 0) seed_point = (int(self.lastCursorLocation.x()), int(self.lastCursorLocation.y())) cv2.floodFill(msk1, the_mask, seed_point, 0, 0, 1) paintin = np.bitwise_xor(msk, msk1) new_img = np.dstack((rgb_view(orig_mask), alpha_view(orig_mask))) new_img[np.where( (paintin == 0))] = list(self.brush_fill_color.getRgb()) new_qimg = array2qimage(new_img) if self.direct_mask_paint: omask = byte_view(self._offscreen_mask).copy() omask = omask.reshape(omask.shape[:-1]) tc = self.d_rgb2gray[self.brush_fill_color.name()] omask[np.where((paintin == 0))] = tc self._offscreen_mask = QImage(omask.data, omask.shape[1], omask.shape[0], omask.strides[0], QImage.Format_Grayscale8) self.mask_pixmap = QPixmap.fromImage(new_qimg) self._overlayHandle.setPixmap(self.mask_pixmap) ''' *********************** IMPORTERS AND EXPORTERS *********************** ''' # Export the grayscale mask # This should always be used with direct mode, which supports up to 255 colors for the mask def export_rgb2gray_mask(self): if self._overlayHandle is not None: if self.d_rgb2gray: if self.direct_mask_paint: # Easy mode mask = byte_view(self._offscreen_mask).copy() mask = mask.reshape(mask.shape[:-1]) else: # The hard way # Split the image to rgb components rgb_m = self.export_ndarray_noalpha() reds, greens, blues = rgb_m[:, :, 0], rgb_m[:, :, 1], rgb_m[:, :, 2] h, w, _ = rgb_m.shape mask = np.zeros((h, w), np.uint8) # Go through all the colors and paint the grayscale mask according to the conversion spec for rgb, gr in self.d_rgb2gray.items(): cc = list(QColor(rgb).getRgb()) mask[np.isclose(reds, cc[0], atol=PIXMAP_CONV_BUG_ATOL) & np.isclose( greens, cc[1], atol=PIXMAP_CONV_BUG_ATOL) & np.isclose( blues, cc[2], atol=PIXMAP_CONV_BUG_ATOL)] = gr else: raise RuntimeError( "Cannot convert the RGB mask to grayscale without color specifications." ) else: raise RuntimeError("There is no RGB mask to export to grayscale.") return mask # Export current mask WITHOUT alpha channel (mask types are determined by colors, not by alpha anyway) def export_ndarray_noalpha(self): mask = self.mask_pixmap.toImage().convertToFormat(QImage.Format_ARGB32) return rgb_view(mask).copy() def export_ndarray(self): mask = self.mask_pixmap.toImage().convertToFormat(QImage.Format_ARGB32) return np.dstack((rgb_view(mask).copy(), alpha_view(mask).copy())) ''' ************** EVENT HANDLERS ************** ''' def wheelEvent(self, event): if self.hasImage(): self.redraw_cursor() # Depending on whether control is pressed, set brush diameter accordingly if QApplication.keyboardModifiers() & Qt.ControlModifier: change = 1 if event.angleDelta().y() > 0 else -1 self.update_brush_diameter(change) self.redraw_cursor() self.mouseWheelRotated.emit(change) else: QGraphicsView.wheelEvent(self, event) def mouseMoveEvent(self, event): if self.hasImage(): # Make sure that the element has focus when the mouse moves, # otherwise keyboard shortcuts will not work if not self.hasFocus(): self.setFocus() self.update_cursor_location(event) # Support for panning if event.buttons() == Qt.MiddleButton: offset = self.__prevMousePos - event.pos() self.__prevMousePos = event.pos() self.verticalScrollBar().setValue( self.verticalScrollBar().value() + offset.y()) self.horizontalScrollBar().setValue( self.horizontalScrollBar().value() + offset.x()) # Filling in the markers if event.buttons() == Qt.LeftButton: self.drawMarkerLine(event) # Store cursor location separately; needed for certain operations (like fill) self.lastCursorLocation = self.mapToScene(event.pos()) QGraphicsView.mouseMoveEvent(self, event) # Keypress event handler def keyPressEvent(self, event): if self.hasImage(): # Zoom in if event.key() == Qt.Key_Plus: viewBBox = self.zoomStack[-1] if len( self.zoomStack) else self.sceneRect() wh12 = int( max(viewBBox.width(), viewBBox.height()) / self.zoom_in_modifier) x, y = self._lastCursorCoords selectionBBox = QRectF(x - wh12, y - wh12, 2 * wh12, 2 * wh12).intersected(viewBBox) if selectionBBox.isValid() and (selectionBBox != viewBBox): self.zoomStack.append(selectionBBox) self.updateViewer() # Zoom out if event.key() == Qt.Key_Minus: if self.canZoom: viewBBox = self.zoomStack[-1] if len( self.zoomStack) else False if viewBBox: self.zoomStack = self.zoomStack[:-1] self.updateViewer() # Fill mask region if event.key() == Qt.Key_F: try: self.viewport().setCursor(Qt.BusyCursor) self.fillArea() except Exception as e: print("Cannot fill region. Additional information:") print(e) self.viewport().setCursor(Qt.ArrowCursor) # Erase closed contour under cursor with current paint color if event.key() == Qt.Key_X: if QApplication.keyboardModifiers() & Qt.ControlModifier: try: self.viewport().setCursor(Qt.BusyCursor) self.fillArea(remove_closed_contour=True) except Exception as e: print( "Cannot remove the contour. Additional information:" ) print(e) self.viewport().setCursor(Qt.ArrowCursor) # Erase closed contour under cursor and any connected contour regardless of color if event.key() == Qt.Key_Q: if QApplication.keyboardModifiers() & Qt.ControlModifier: try: self.viewport().setCursor(Qt.BusyCursor) self.fillArea(remove_closed_contour=True, remove_only_current_color=False) except Exception as e: print( "Cannot remove the contour. Additional information:" ) print(e) self.viewport().setCursor(Qt.ArrowCursor) # Erase mode enable/disable if event.key() == Qt.Key_D: self.global_erase_override = not self.global_erase_override if self.global_erase_override: self.current_painting_mode = self.MODE_ERASE self._deleteCrossHandles[0].show() self._deleteCrossHandles[1].show() else: self.current_painting_mode = self.MODE_PAINT self._deleteCrossHandles[0].hide() self._deleteCrossHandles[1].hide() # Temporarily hide the overlay if event.key() == Qt.Key_H: self._overlayHandle.hide() # Toggle helper on and off if event.key() == Qt.Key_T: if self._auxHelper is not None: if self.showHelper: self._auxHelper.hide() self.showHelper = False else: self._auxHelper.show() self.showHelper = True # Undo operations if event.key() == Qt.Key_Z: if QApplication.keyboardModifiers() & Qt.ControlModifier: if (len(self._overlay_stack) > 0): self.mask_pixmap = self._overlay_stack.pop() self._overlayHandle.setPixmap(self.mask_pixmap) if self.direct_mask_paint: if len(self._offscreen_mask_stack) > 0: self._offscreen_mask = self._offscreen_mask_stack.pop( ) # When CONTROL is pressed, show the delete cross if event.key( ) == Qt.Key_Control and not self.global_erase_override: self._deleteCrossHandles[0].show() self._deleteCrossHandles[1].show() QGraphicsView.keyPressEvent(self, event) def keyReleaseEvent(self, event): if self.hasImage(): if event.key( ) == Qt.Key_Control and not self.global_erase_override: self._deleteCrossHandles[0].hide() self._deleteCrossHandles[1].hide() # Show the overlay again if event.key() == Qt.Key_H: self._overlayHandle.show() QGraphicsView.keyPressEvent(self, event) def mousePressEvent(self, event): if self.hasImage(): """ Start drawing, panning with mouse, or zooming in """ scenePos = self.mapToScene(event.pos()) if event.button() == Qt.LeftButton: self._overlay_stack.append(self.mask_pixmap.copy()) if self.direct_mask_paint: self._offscreen_mask_stack.append( self._offscreen_mask.copy()) # If ALT is held, replace color repaint_was_active = False if QApplication.keyboardModifiers() & Qt.AltModifier: try: repaint_was_active = True self.viewport().setCursor(Qt.BusyCursor) self.repaintArea() except Exception as e: print("Cannot repaint region. Additional information:") print(e) self.viewport().setCursor(Qt.ArrowCursor) # If SHIFT is held, draw a line if QApplication.keyboardModifiers() & Qt.ShiftModifier: self.drawMarkerLine(event) # If CONTROL is held, erase, but only if global erase override is not enabled if not self.global_erase_override: if QApplication.keyboardModifiers() & Qt.ControlModifier: self.current_painting_mode = self.MODE_ERASE else: self.current_painting_mode = self.MODE_PAINT # If the user just clicks, add a marker (unless repainting was done) if not repaint_was_active: self.fillMarker(event) self.leftMouseButtonPressed.emit(scenePos.x(), scenePos.y()) elif event.button() == Qt.MiddleButton: if self.canPan: self.__prevMousePos = event.pos() self.viewport().setCursor(Qt.ClosedHandCursor) self._cursorHandle.hide() self.middleMouseButtonPressed.emit(scenePos.x(), scenePos.y()) elif event.button() == Qt.RightButton: if self.canZoom: self.setDragMode(QGraphicsView.RubberBandDrag) self._cursorHandle.hide() self.rightMouseButtonPressed.emit(scenePos.x(), scenePos.y()) QGraphicsView.mousePressEvent(self, event) def mouseReleaseEvent(self, event): """ Stop mouse pan or zoom mode (apply zoom if valid). """ if self.hasImage(): QGraphicsView.mouseReleaseEvent(self, event) scenePos = self.mapToScene(event.pos()) if event.button() == Qt.MiddleButton: self.viewport().setCursor(Qt.ArrowCursor) self._cursorHandle.show() self.middleMouseButtonReleased.emit(scenePos.x(), scenePos.y()) elif event.button() == Qt.RightButton: if self.canZoom: viewBBox = self.zoomStack[-1] if len( self.zoomStack) else self.sceneRect() selectionBBox = self.scene.selectionArea().boundingRect( ).intersected(viewBBox) self.scene.setSelectionArea( QPainterPath()) # Clear current selection area. if selectionBBox.isValid() and (selectionBBox != viewBBox): self.zoomStack.append(selectionBBox) self.updateViewer() self.setDragMode(QGraphicsView.NoDrag) self._cursorHandle.show() self.rightMouseButtonReleased.emit(scenePos.x(), scenePos.y()) QGraphicsView.mouseReleaseEvent(self, event) def mouseDoubleClickEvent(self, event): """ Show entire image. """ if self.hasImage(): scenePos = self.mapToScene(event.pos()) if event.button() == Qt.MiddleButton: self.middleMouseButtonDoubleClicked.emit( scenePos.x(), scenePos.y()) elif event.button() == Qt.RightButton: if self.canZoom: self.zoomStack = [] # Clear zoom stack. self.updateViewer() self.rightMouseButtonDoubleClicked.emit( scenePos.x(), scenePos.y()) QGraphicsView.mouseDoubleClickEvent(self, event)
class Setting: settingDefault = { 'X': 1320, 'Y': 850, 'W': 600, 'H': 300, 'TP': 0.5, 'CL': QColor(Qt.darkCyan).rgb(), 'FM': 'hh:mm' } settingMinMax = { 'X': [0, 9999], 'Y': [0, 9999], 'W': [0, 9999], 'H': [0, 9999], 'TP': [0.0, 1.0], 'CL': [QColor(0, 0, 0).rgb(), QColor(255, 255, 255).rgb()], 'FM': ['hh:mm:ss', 'hh:mm'] } def SettingSave(self): try: with open('setting.json', 'w', encoding='utf8') as file: setting = dict() setting['X'] = self.X setting['Y'] = self.Y setting['W'] = self.W setting['H'] = self.H setting['TP'] = self.TP setting['CL'] = self.CL setting['FM'] = self.FM json.dump(setting, file) except Exception as identifier: print(('setting.json save error!', identifier)) pass def SettingLoadOne(self, setting, name, continued): if continued: if name not in setting or type(setting[name]) != type( self.settingDefault[name] ) or setting[name] < self.settingMinMax[name][0] or setting[ name] > self.settingMinMax[name][1]: print('%s load bad!' % name) return self.settingDefault[name] else: return setting[name] else: if name not in setting or type(setting[name]) != type( self.settingDefault[name] ) or setting[name] not in self.settingMinMax[name]: print('%s load bad!' % name) return self.settingDefault[name] else: return setting[name] def SettingLoad(self): try: with open('setting.json', 'r', encoding='utf8') as file: setting = json.loads(file.read()) self.X = self.SettingLoadOne(setting, 'X', True) self.Y = self.SettingLoadOne(setting, 'Y', True) self.W = self.SettingLoadOne(setting, 'W', True) self.H = self.SettingLoadOne(setting, 'H', True) self.TP = self.SettingLoadOne(setting, 'TP', True) self.CL = self.SettingLoadOne(setting, 'CL', True) self.FM = self.SettingLoadOne(setting, 'FM', False) except Exception as identifier: print(('setting.json load error!', identifier)) self.X = self.settingDefault['X'] self.Y = self.settingDefault['Y'] self.W = self.settingDefault['W'] self.H = self.settingDefault['H'] self.TP = self.settingDefault['TP'] self.CL = self.settingDefault['CL'] self.FM = self.settingDefault['FM'] def SettingDialog(self, ApplyChange): from PyQt5.QtWidgets import (QDialog, QSpinBox, QComboBox, QDialogButtonBox, QFormLayout, QColorDialog, QPushButton, QSizePolicy) dialog = self.dialog = QDialog() dialog.setWindowTitle('设置') if hasattr(sys, "_MEIPASS"): dialog.setWindowIcon(QIcon(sys._MEIPASS + r'/Icon.ico')) else: dialog.setWindowIcon(QIcon(r'./Icon.ico')) boxX = QSpinBox(dialog) boxX.setRange(-100000, 100000) boxX.setValue(self.X) boxY = QSpinBox(dialog) boxY.setRange(-100000, 100000) boxY.setValue(self.Y) boxW = QSpinBox(dialog) boxW.setRange(0, 100000) boxW.setValue(self.W) boxH = QSpinBox(dialog) boxH.setRange(0, 100000) boxH.setValue(self.H) boxTP = QSpinBox(dialog) boxTP.setRange(0, 100) boxTP.setValue(self.TP * 100) self.buttonColorVal = QColor(self.CL) self.buttonColor = QPushButton(parent=dialog) self.buttonColor.setStyleSheet('QWidget {background-color:%s}' % self.buttonColorVal.name()) def ChangeCol(): qcd = QColorDialog(dialog) qcd.setWindowTitle('颜色选择') qcd.setCurrentColor(self.buttonColorVal) if qcd.exec() == QDialog.Accepted: self.buttonColorVal = qcd.selectedColor() self.buttonColor.setStyleSheet( 'QWidget {background-color:%s}' % self.buttonColorVal.name()) self.buttonColor.clicked.connect(ChangeCol) boxFM = QComboBox(dialog) boxFM.addItems(self.settingMinMax['FM']) boxFM.setCurrentIndex(boxFM.findText(self.FM)) def Apply(): self.X = boxX.value() self.Y = boxY.value() self.W = boxW.value() self.H = boxH.value() self.TP = boxTP.value() / 100.0 self.CL = self.buttonColorVal.rgb() self.FM = boxFM.currentText() ApplyChange() self.SettingSave() buttonBox = QDialogButtonBox( QDialogButtonBox.Apply | QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, dialog) buttonBox.button(QDialogButtonBox.Apply).setText("应用") buttonBox.button(QDialogButtonBox.Ok).setText("确定") buttonBox.button(QDialogButtonBox.Cancel).setText("取消") buttonBox.accepted.connect(dialog.accept) buttonBox.rejected.connect(dialog.reject) buttonBox.button(QDialogButtonBox.Apply).clicked.connect(Apply) form = QFormLayout(dialog) form.addRow(QLabel("设置:")) form.addRow("坐标X:", boxX) form.addRow("坐标Y:", boxY) form.addRow("大小W:", boxW) form.addRow("大小H:", boxH) form.addRow("透明度:", boxTP) form.addRow("颜色:", self.buttonColor) form.addRow("格式:", boxFM) form.addRow(buttonBox) dialog.setFixedSize(dialog.sizeHint()) if dialog.exec() == QDialog.Accepted: Apply()
class uartToFile(QWidget): def __init__(self): super().__init__() self.initUI() self.com = serial.Serial() def initUI(self): self.col = QColor(0, 0, 0) serialOpenCloseButton = QPushButton('openClose', self) serialOpenCloseButton.clicked.connect(self.openCloseSerial) serialOpenCloseButton.setCheckable(True) serialOpenCloseButton.move(20, 10) saveToFileButton = QPushButton('saveOrNot', self) saveToFileButton.clicked[bool].connect(self.open_close) saveToFileButton.setCheckable(True) saveToFileButton.move(20, 60) self.square = QFrame(self) self.square.setGeometry(150, 20, 100, 100) self.square.setStyleSheet("QWidget { background-color: %s }" % self.col.name()) self.setGeometry(300, 300, 600, 400) self.setWindowTitle('uart To File') self.show() def open_close(self, pressed): source = self.sender() print(source.text(), pressed) if source.text() == 'saveOrNot': if pressed == True: print('save file') else: print('close file') def openCloseSerial(self): print('openCloseSerial') t = threading.Thread(target=self.openCloseSerialProcess) t.setDaemon(True) t.start() return def openCloseSerialProcess(self): try: if self.com.is_open: self.com.close() self.receiveProgressStop = True print('uart close') print('receiveCount =', self.receiveCount) else: try: self.com.baudrate = 115200 self.com.port = 'COM7' print(self.com) self.com.open() print('uart open') receiveProcess = threading.Thread(target=self.receiveData) receiveProcess.setDaemon(True) receiveProcess.start() except Exception as e: self.com.close() print('uart open fail') print(e) self.receiveProgressStop = True except Exception as e: print(e) return def receiveData(self): self.receiveProgressStop = False self.receiveCount = 0 self.timeLastReceive = 0 while(not self.receiveProgressStop): try: if self.com.is_open: print("is_open") content = self.com.read(1) print("try read") if len(content): self.receiveCount += len(content) print("content = ", content) except Exception as e: print(e) print("receiveData error") if self.com.is_open: print("self.com.close") self.com.close() return
def setColor(self, a): mycolor = QColor(0, 0, 0) mycolor.setBlue(a) self.setStyleSheet("QWidget{background-color:%s}" % mycolor.name()) pass
def createMeals(self): self.mealContainer = QFrame(self) self.mealContainer.setFixedSize(500, 700) vbox = QVBoxLayout() self.mealGroup = QGroupBox("اختار وجبتك", self) self.mealGroup.setFont(QFont("urdu Typesetting", 36, 900)) mealGrid = QGridLayout() self.lblMeal = QLabel("الوجبة", self) self.lblPrice = QLabel("السعر(ج.م)", self) self.lblQuantity = QLabel("الكمية", self) mealHeaders = [self.lblMeal, self.lblPrice, self.lblQuantity] for h, head in enumerate(mealHeaders): head.setFont(QFont("urdu Typesetting", 18, 900)) head.setFixedSize(80, 40) head.setAlignment(Qt.AlignCenter) head.setStyleSheet( "background-color: grey; color: black; border: 1px solid black; border-radius:10px" ) mealGrid.addWidget(head, 0, h, 1, 1) self.chkShrimp = QCheckBox("الجمبري مع أرز", self) self.chkShrimp.toggled.connect(lambda: self.selectedItem( self.chkShrimp, self.shrimpPrice, self.QShrimp)) self.chkFish = QCheckBox("السمك مع أرز", self) self.chkFish.toggled.connect(lambda: self.selectedItem( self.chkFish, self.fishPrice, self.QFish)) self.chkBeef = QCheckBox("طاجن اللحم مع أرز", self) self.chkBeef.toggled.connect(lambda: self.selectedItem( self.chkBeef, self.beefPrice, self.QBeef)) self.chkChicken = QCheckBox("الفراخ مع أرز", self) self.chkChicken.toggled.connect(lambda: self.selectedItem( self.chkChicken, self.chickenPrice, self.QChicken)) self.chkBeefShawarma = QCheckBox("شاروما لحم مع الأرز", self) self.chkBeefShawarma.toggled.connect(lambda: self.selectedItem( self.chkBeefShawarma, self.beefShawarmaPrice, self.QBeefShawarma)) self.chkChickenShawarma = QCheckBox("شاورما فراخ مع الأرز", self) self.chkChickenShawarma.toggled.connect(lambda: self.selectedItem( self.chkChickenShawarma, self.chickenShawarmaPrice, self. QChickenShawarma)) self.chkMeatRiceNuts = QCheckBox("لحم مع أرز بالمكسرات", self) self.chkMeatRiceNuts.toggled.connect(lambda: self.selectedItem( self.chkMeatRiceNuts, self.meatRicePrice, self.QMeatRiceNuts)) self.chkMeatKofta = QCheckBox("كفتة لحم مع الأرز", self) self.chkMeatKofta.toggled.connect(lambda: self.selectedItem( self.chkMeatKofta, self.meatKoftaPrice, self.QMeatKofta)) self.chkVegetables = QCheckBox("خضراوات مع الأرز", self) self.chkVegetables.toggled.connect(lambda: self.selectedItem( self.chkVegetables, self.vegetablesPrice, self.QVegetables)) chkMeals = [ self.chkShrimp, self.chkFish, self.chkBeef, self.chkChicken, self.chkBeefShawarma, self.chkChickenShawarma, self.chkMeatRiceNuts, self.chkMeatKofta, self.chkVegetables ] chkFont = QFont("Traditinal Arabic", 20, 900) # chkFont.setBold(True) # chkColor = QColor(30, 30, 200) chkStyle = "padding: 3px" for m, meal in enumerate(chkMeals): meal.setFont(chkFont) meal.setStyleSheet(chkStyle) mealGrid.addWidget(meal, m + 1, 0, 1, 1) self.shrimpPrice = QLabel("45.00", self) self.fishPrice = QLabel("45.00", self) self.beefPrice = QLabel("45.00", self) self.chickenPrice = QLabel("40.50", self) self.beefShawarmaPrice = QLabel("40.50", self) self.chickenShawarmaPrice = QLabel("40.50", self) self.meatRicePrice = QLabel("45.50", self) self.meatKoftaPrice = QLabel("45.50", self) self.vegetablesPrice = QLabel("35.50", self) lblPrices = [ self.shrimpPrice, self.fishPrice, self.beefPrice, self.chickenPrice, self.beefShawarmaPrice, self.chickenShawarmaPrice, self.meatRicePrice, self.meatKoftaPrice, self.vegetablesPrice ] for p, price in enumerate(lblPrices): price.setFont(chkFont) price.setAlignment(Qt.AlignCenter) mealGrid.addWidget(price, p + 1, 1, 1, 1) self.QShrimp = QLineEdit("0", self) self.QFish = QLineEdit("0", self) self.QBeef = QLineEdit("0", self) self.QChicken = QLineEdit("0", self) self.QBeefShawarma = QLineEdit("0", self) self.QChickenShawarma = QLineEdit("0", self) self.QMeatRiceNuts = QLineEdit("0", self) self.QMeatKofta = QLineEdit("0", self) self.QVegetables = QLineEdit("0", self) quantities = [ self.QShrimp, self.QFish, self.QBeef, self.QChicken, self.QBeefShawarma, self.QChickenShawarma, self.QMeatRiceNuts, self.QMeatKofta, self.QVegetables ] for q, quantity in enumerate(quantities): quantity.setFixedSize(80, 40) quantity.setAlignment(Qt.AlignCenter) quantity.setFont(QFont("urdu Typesetting", 20)) mealGrid.addWidget(quantity, q + 1, 2, 1, 1) self.mealGroup.setLayout(mealGrid) vbox.addWidget(self.mealGroup) self.ctrlGroup = QGroupBox("إصدار فاتورة", self) self.ctrlGroup.setFont(QFont("urdu Typesetting", 14)) ctrlFont = QFont("urdu Typesetting", 18, 900) ctrlSize = QSize(110, 60) ctrlbgColor = QColor(20, 70, 150) ctrlfgColor = QColor(200, 200, 200) ctrlStyle = "background-color: {}; color: {}; border: 3px solid {}; border-radius: 10px".format( ctrlbgColor.name(), ctrlfgColor.name(), ctrlfgColor.name()) ctrlGrid = QGridLayout() self.getTotals = QPushButton("حساب الإجمالي", self) self.getTotals.clicked.connect(self.getTotalAction) self.getInvoice = QPushButton("طباعة الفاتورة", self) self.getInvoice.clicked.connect(self.getInvoiceAction) self.clearData = QPushButton("فاتورة جديدة", self) self.clearData.clicked.connect(self.newTransaction) self.exitProgram = QPushButton("خروج", self) self.exitProgram.clicked.connect(self.exit_pro) controls = [ self.getTotals, self.getInvoice, self.clearData, self.exitProgram ] for c, ctrl in enumerate(controls): ctrl.setFont(ctrlFont) ctrl.setFixedSize(ctrlSize) ctrl.setStyleSheet(ctrlStyle) ctrlGrid.addWidget(ctrl, 0, c, 1, 1) self.ctrlGroup.setLayout(ctrlGrid) vbox.addWidget(self.ctrlGroup) self.mealContainer.setLayout(vbox)
class RGBSlider(QWidget): def __init__(self, _image=None): super().__init__() self._image = _image self.hex_values_label = QLabel() # Create RGB sliders and spin boxes self.blue_spinbox = QSpinBox() self.blue_slider = QSlider(Qt.Horizontal) self.green_spinbox = QSpinBox() self.green_slider = QSlider(Qt.Horizontal) self.red_spinbox = QSpinBox() self.red_slider = QSlider(Qt.Horizontal) self.cd_label = QLabel() self.color_display = QImage(100, 50, QImage.Format_RGBX64) # Store the current pixel value self.current_val = QColor() self.init_ui() def init_ui(self): """ Initialize the window and display its contents to the screen. """ self.setMinimumSize(225, 600) self.setWindowTitle('9.3 - RGB Slider') self.setup_window() self.show() def setup_window(self): """ Create instances of widgets and arrange them in layouts. """ # Image that will display the current color set by # slider/spin_box values self.color_display.fill(Qt.black) self.cd_label.setPixmap(QPixmap.fromImage(self.color_display)) self.cd_label.setScaledContents(True) # Create RGB sliders and spin boxes red_label = QLabel("Red") red_label.setFont(QFont('Helvetica')) self.red_slider.setObjectName("Red") self.red_slider.setMaximum(255) self.red_spinbox.setMaximum(255) green_label = QLabel("Green") green_label.setFont(QFont('Helvetica')) self.green_slider.setObjectName("Green") self.green_slider.setMaximum(255) self.green_spinbox.setMaximum(255) blue_label = QLabel("Blue") blue_label.setFont(QFont('Helvetica')) self.blue_slider.setObjectName("Blue") self.blue_slider.setMaximum(255) self.blue_spinbox.setMaximum(255) # Use the hex labels to display color values in hex format hex_label = QLabel("Hex Color ") hex_h_box = QHBoxLayout() hex_h_box.addWidget(hex_label, Qt.AlignRight) hex_h_box.addWidget(self.hex_values_label, Qt.AlignRight) hex_container = QWidget() hex_container.setLayout(hex_h_box) # Create grid layout for sliders and spin boxes grid = QGridLayout() grid.addWidget(red_label, 0, 0, Qt.AlignLeft) grid.addWidget(self.red_slider, 0, 1) grid.addWidget(self.red_spinbox, 0, 2) grid.addWidget(green_label, 1, 0, Qt.AlignLeft) grid.addWidget(self.green_slider, 1, 1) grid.addWidget(self.green_spinbox, 1, 2) grid.addWidget(blue_label, 2, 0, Qt.AlignLeft) grid.addWidget(self.blue_slider, 2, 1) grid.addWidget(self.blue_spinbox, 2, 2) grid.addWidget(hex_container, 3, 0, 1, 0) # Use [] to pass arguments to the valueChanged signal # The sliders and spin boxes for each color should display the same values and be updated at the same time. self.red_slider.valueChanged['int'].connect(self.update_red_spinbox) self.red_spinbox.valueChanged['int'].connect(self.update_red_slider) self.green_slider.valueChanged['int'].connect( self.update_green_spinbox) self.green_spinbox.valueChanged['int'].connect( self.update_green_slider) self.blue_slider.valueChanged['int'].connect(self.update_blue_spinbox) self.blue_spinbox.valueChanged['int'].connect(self.update_blue_slider) # Create container for rgb widgets rgb_widgets = QWidget() rgb_widgets.setLayout(grid) v_box = QVBoxLayout() v_box.addWidget(self.cd_label) v_box.addWidget(rgb_widgets) self.setLayout(v_box) # The following methods update the red, green, and blue # sliders and spin boxes. def update_red_spinbox(self, value): self.red_spinbox.setValue(value) self.red_value(value) def update_red_slider(self, value): self.red_slider.setValue(value) self.red_value(value) def update_green_spinbox(self, value): self.green_spinbox.setValue(value) self.green_value(value) def update_green_slider(self, value): self.green_slider.setValue(value) self.green_value(value) def update_blue_spinbox(self, value): self.blue_spinbox.setValue(value) self.blue_value(value) def update_blue_slider(self, value): self.blue_slider.setValue(value) self.blue_value(value) # Create new colors based upon the changes to the RGB values def red_value(self, value): new_color = qRgb(value, self.current_val.green(), self.current_val.blue()) self.update_color_info(new_color) def green_value(self, value): new_color = qRgb(self.current_val.red(), value, self.current_val.blue()) self.update_color_info(new_color) def blue_value(self, value): new_color = qRgb(self.current_val.red(), self.current_val.green(), value) self.update_color_info(new_color) def update_color_info(self, color): """ Update color displayed in image and set the hex values accordingly. """ self.current_val = QColor(color) self.color_display.fill(color) self.cd_label.setPixmap(QPixmap.fromImage(self.color_display)) self.hex_values_label.setText(self.current_val.name()) def get_pixels_value(self, event): """ The method reimplements the mousePressEvent method. To use, set a widget's mousePressEvent equal to getPixelValues, like so: image_label.mousePressEvent = rgb_slider.getPixelValues If an _image != None, then the user can select pixels in the images, and update the sliders to get view the color, and get the rgb and hex values. """ x = event.x() y = event.y() # valid() returns true if the point selected is a valid coordinate pair within the image if QImage(self._image).valid(x, y): self.current_val = QColor(QImage(self._image).pixel(x, y)) red_val = self.current_val.red() green_val = self.current_val.green() blue_val = self.current_val.blue() self.update_red_spinbox(red_val) self.update_red_slider(red_val) self.update_green_spinbox(green_val) self.update_green_slider(green_val) self.update_blue_spinbox(blue_val) self.update_blue_slider(blue_val) elif self.color_display.valid(x, y): self.current_val = QColor(self.color_display.pixel(x, y)) else: pass
class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): # checkbox cb = QCheckBox('Show title', self) cb.move(20, 160) cb.toggle() cb.stateChanged.connect(self.changeTitle) # toggle button self.col = QColor(0, 0, 0) redb = QPushButton('Red', self) redb.setCheckable(True) redb.move(10, 10) redb.clicked[bool].connect(self.setColor) redb = QPushButton('Green', self) redb.setCheckable(True) redb.move(10, 60) redb.clicked[bool].connect(self.setColor) blueb = QPushButton('Blue', self) blueb.setCheckable(True) blueb.move(10, 110) blueb.clicked[bool].connect(self.setColor) self.square = QFrame(self) self.square.setGeometry(150, 20, 100, 100) self.square.setStyleSheet("QWidget { background-color: %s }" % self.col.name()) # slider sld = QSlider(Qt.Horizontal, self) sld.setFocusPolicy(Qt.NoFocus) sld.setGeometry(30, 210, 100, 30) sld.valueChanged[int].connect(self.changeValue) # pixmap self.label = QLabel(self) self.label.setPixmap(QPixmap('web.png')) self.label.setGeometry(160, 210, 80, 30) # process bar self.pbar = QProgressBar(self) self.pbar.setGeometry(30, 260, 200, 25) self.btn = QPushButton('Start', self) self.btn.move(40, 310) self.btn.clicked.connect(self.doAction) self.timer = QBasicTimer() self.step = 0 # calendar cal = QCalendarWidget(self) cal.setGridVisible(True) cal.move(300, 10) cal.clicked[QDate].connect(self.showDate) self.lbl = QLabel(self) date = cal.selectedDate() self.lbl.setText(date.toString()) self.lbl.move(300, 260) # line edit self.lbl2 = QLabel(self) qle = QLineEdit(self) qle.move(300, 310) self.lbl2.move(480, 310) qle.textChanged[str].connect(self.onChanged) self.setGeometry(300, 300, 640, 480) self.setWindowTitle('QCheckBox') self.show() def changeTitle(self, state): if state == Qt.Checked: self.setWindowTitle('QCheckBox') else: self.setWindowTitle('') def setColor(self, pressed): source = self.sender() if pressed: val = 255 else: val = 0 if source.text() == "Red": self.col.setRed(val) elif source.text() == "Green": self.col.setGreen(val) else: self.col.setBlue(val) self.square.setStyleSheet("QFrame { background-color: %s }" % self.col.name()) def changeValue(self, value): if value == 0: self.label.setPixmap(QPixmap('web.png')) elif value > 0 and value <= 30: self.label.setPixmap(QPixmap('web.png')) elif value > 30 and value < 80: self.label.setPixmap(QPixmap('web.png')) else: self.label.setPixmap(QPixmap('web.png')) def timerEvent(self, e): if self.step >= 100: self.timer.stop() self.btn.setText('Finished') return self.step = self.step + 1 self.pbar.setValue(self.step) def doAction(self): if self.timer.isActive(): self.timer.stop() self.btn.setText('Start') else: self.timer.start(100, self) self.btn.setText('Stop') def showDate(self, date): self.lbl.setText(date.toString()) def onChanged(self, text): self.lbl2.setText(text) self.lbl2.adjustSize()
def updateMessage(self, color: QColor): self.setText(color.name())
def setColor(self, color: QColor): self._color = color self.setStyleSheet("background-color: " + color.name())
class GroundSoftware(QWidget): def __init__(self, kiss_serial=None): super().__init__() self.initUI() def initUI(self, kiss_serial=None): self.labels = [] self.leds = [] self.checkboxes = [] #CHIMERA INFO self.chi_status = CHI_STATUS() self.chi_sci_tm = CHI_SCI_TM() self.SOFTWARE_VERSION = QLabel("CHIMERA Software: V." + str(self.chi_status.SOFTWARE_VERSION)) self.reset_type = QLabel("Reset type: " + str(self.chi_status.reset_type)) self.device_mode = QLabel("Device Mode: " + str(self.chi_status.device_mode)) self.no_cycles = QLabel("Number of Cycles: " + str(self.chi_status.no_cycles)) self.local_time = QLabel("CHIMERA time: " + str(self.chi_sci_tm.local_time)) self.ki = kiss_serial self.red = QColor(255, 0, 0) self.green = QColor(0, 255, 0) button_box = QVBoxLayout() status_b = QPushButton('Get Status', self) status_b.clicked[bool].connect(self.getStatus) prevpacket_b = QPushButton('Get Previous', self) prevpacket_b.clicked[bool].connect(self.get_prev) sci_tm_b = QPushButton('Get Telemetry', self) sci_tm_b.clicked[bool].connect(self.get_sci_tcm) mode_box = QHBoxLayout() mode_label = QLabel("Select Mode") mode_button = QPushButton("Set Mode") mode_button.clicked[bool].connect(self.set_mode) self.mode_selector = QComboBox() self.mode_selector.addItem("Read Mode") self.mode_selector.addItem("R/W/E Mode") mode_box.addWidget(mode_label) mode_box.addWidget(self.mode_selector) button_box.addWidget(mode_button) button_box.addWidget(status_b) button_box.addWidget(prevpacket_b) button_box.addWidget(sci_tm_b) self.lastFrame = QTextEdit(self) self.lastFrame.setReadOnly(True) frame_box = QHBoxLayout() frame_box.addWidget(self.lastFrame) led_grid = QGridLayout() led_grid.columnStretch(1) self.set_led_layout(led_grid) middle_box = QVBoxLayout() sub_middle_box = QVBoxLayout() sub_middle_box.addWidget(self.SOFTWARE_VERSION) sub_middle_box.addWidget(self.reset_type) sub_middle_box.addWidget(self.device_mode) sub_middle_box.addWidget(self.no_cycles) sub_middle_box.addWidget(self.local_time) middle_box.addLayout(mode_box) middle_box.addLayout(sub_middle_box) middle_box.addLayout(led_grid) mainLayout = QHBoxLayout(self) mainLayout.addLayout(button_box) mainLayout.addLayout(middle_box) mainLayout.addWidget(self.lastFrame) self.setGeometry(300, 300, 600, 200) self.setWindowTitle('Toggle button') self.setLayout(mainLayout) self.show() self.start_frame_thread() def update_frame_view_callback(self, frame): if len(frame) > 2: self.lastFrame.insertPlainText( ''.join(["0x%02x " % byte for byte in frame]) + '\n\n') ki._logger.debug(frame) if frame[0] == CHI_COMM_ID_SCI_TM: self.handle_SCI_TM_frame(frame[1:]) elif frame[0] == CHI_COMM_ID_STATUS: self.handle_status_frame(frame[1:]) def start_frame_thread(self): ## Oops! should use signals and slots, not interact directly t = threading.Thread(name='frame_thread', target=frame_thread, args=(self.update_frame_view_callback, )) ##t.daemon = True # stop when main thread stops t.start() def handle_status_frame(self, frame): self.chi_status.SOFTWARE_VERSION = frame[0] self.chi_status.reset_type = frame[1] self.chi_status.device_mode = frame[2] self.chi_status.no_cycles = int.from_bytes(frame[3:5], byteorder='big') self.SOFTWARE_VERSION.setText("CHIMERA Software: V." + str(self.chi_status.SOFTWARE_VERSION)) self.reset_type.setText("Reset type: " + str(self.chi_status.reset_type)) self.device_mode.setText("Device Mode: " + str(self.chi_status.device_mode)) self.no_cycles.setText("Number of Cycles: " + str(self.chi_status.no_cycles)) def handle_SCI_TM_frame(self, frame): self.chi_sci_tm.local_time = int.from_bytes(frame[:4], byteorder='big') self.chi_sci_tm.mem_to_test = int.from_bytes(frame[4:6], byteorder='big') #for i in range(1,13): # self.chi_sci_tm.no_SEU[i-1] = frame[5*i] self.local_time.setText("CHIMERA time: " + str(self.chi_sci_tm.local_time)) ki._logger.debug(len(frame)) memories_lower = frame[4] memories_upper = frame[5] for i in range(0, 8): if (memories_lower >> i & 1): self.leds[i].setStyleSheet("QWidget { background-color: %s }" % self.green.name()) else: self.leds[i].setStyleSheet("QWidget { background-color: %s }" % self.red.name()) for i in range(8, 12): if (memories_upper >> (i - 8) & 1): self.leds[i].setStyleSheet("QWidget { background-color: %s }" % self.green.name()) else: self.leds[i].setStyleSheet("QWidget { background-color: %s }" % self.red.name()) def set_mode(self): frame = b'\x07' if (self.mode_selector.currentIndex() == 0): # read mode frame += b'\x01' elif (self.mode_selector.currentIndex() == 1): # erase program read mode frame += b'\x02' else: frame = b'\x00' memories_lower = 0 memories_upper = 0 for i in range(0, 8): if (self.checkboxes[i].isChecked()): memories_lower |= (1 << i) for i in range(8, 12): if (self.checkboxes[i].isChecked()): memories_upper |= (1 << (i - 8)) frame += bytes([memories_lower, memories_upper]) ki._logger.debug(frame) ki.write(frame) def get_sci_tcm(self, pressed): ki.request_sci_tm() def getStatus(self, pressed): ki.request_status() def get_prev(self): ki.send_nack() def set_led_layout(self, gridlayout): for i in range(12): if i < 9: label = QLabel("0" + str(i + 1), self) else: label = QLabel(str(i + 1), self) self.labels.append(label) gridlayout.addWidget(self.labels[i], 0, i, 1, 1) led = QFrame(self) led.setStyleSheet("QWidget { background-color: %s }" % self.red.name()) self.leds.append(led) gridlayout.addWidget(self.leds[i], 1, i, 1, 1) checkbox = QCheckBox(self) self.checkboxes.append(checkbox) gridlayout.addWidget(self.checkboxes[i], 2, i, 1, 1)
class TimelineDelta(object): """ """ def __init__(self, begin, end=30, title=None, height=30, top=0, parent=None): """ :param begin: :param end: :param title: :param height: :param top: :param parent: """ self._top = top self._height = height self._parent = parent self._title = title self._lock = False self._begin = begin self._end = end self.checkNumberOfTracks() self._defautcolor = parent._tracks[self.track].color ########################################################################## #### HELPERS/FUNCTIONS ################################################### ########################################################################## def checkNumberOfTracks(self): """ :return: """ if self.track >= (self._parent.numberoftracks - 1): for i in range(self._parent.numberoftracks - 1, self.track + 1): self._parent.addTrack() def collide(self, x, y): """ :param x: :param y: :return: """ return self.begin <= x <= self.end and self._top <= y <= (self._top + self._height) def in_range(self, start, end): """ :param start: :param end: :return: """ return start <= self.begin and end >= self.end or \ self.begin <= start <= self.end or \ self.begin <= end <= self.end def canSlideBegin(self, x, y): """ :param x: :param y: :return: """ return not self._lock and x == int(round(self.begin)) and self._top <= y <= (self._top + self._height) def canSlideEnd(self, x, y): """ :param x: :param y: :return: """ return not self._lock and int(round(self.end)) == x and self._top <= y <= (self._top + self._height) def moveEnd(self, x): """ Move the right edge of the event rectangle. :param x: """ # Do nothing if locked if self._lock: return # Do nothing if trying to go over the pther edge if self._end <= self._begin - x and x < 0: return # Increment accordingly self._end += x / self._parent._scale # Minimum begin position is at 0 if self._end > (self._parent.width() / self._parent._scale): self._end = (self._parent.width() / self._parent._scale) def moveBegin(self, x): """ Move the left edge of the event rectangle. :param x: """ # Do nothing if locked if self._lock: return # Do nothing if trying to go over the other edge if self._begin >= self._end - x and x > 0: return # Increment accordingly self._begin += x / self._parent._scale # Minimum begin position is at 0 if self._begin < 0: self._begin = 0 def move(self, x, y): """ :param x: :param y: :return: """ if self._lock: return if (self.begin + x) >= 0 and (self.end + x) <= self._parent.width(): self._begin += x / self._parent._scale self._end += x / self._parent._scale current_track = self.track new_track = Track.whichTrack(y) if current_track != new_track and new_track >= 0 and new_track <= self._parent.numberoftracks: self.track = new_track self.checkNumberOfTracks() def showEditWindow(self): """ :return: """ text, ok = QInputDialog.getText( self._parent, 'Edit event', 'Comment:', text=self._title) if ok: self._title = str(text) self._parent.repaint() def draw(self, painter, showvalues=False): """ :param painter: :param showvalues: :return: """ start, end = self.begin, self.end if self._lock: transparency = 0.1 else: transparency = 0.5 painter.setPen(QColor(0, 0, 0)) painter.setOpacity(transparency) painter.drawRoundedRect( start, self._top, end - start, self._height, 3, 3) painter.setOpacity(1.0) painter.drawText(start + 3, self._top + 19, self._title) if showvalues: painter.drawText( start, self._top + 44, "[%d;%d] delta:%d" % (self._begin, self._end, self._end - self._begin)) def remove(self): """ :return: """ try: self._parent._tracks[self.track].periods.remove(self) except: pass ########################################################################## #### PROPERTIES ########################################################## ########################################################################## @property def title(self): return self._title @property def lock(self): return self._lock @lock.setter def lock(self, value): self._lock = value @property def begin(self): return self._begin * self._parent._scale @begin.setter def begin(self, value): if self._lock: return self._begin = value / self._parent._scale if self._begin < 0: self._begin = 0 @property def end(self): return self._end * self._parent._scale @end.setter def end(self, value): if self._lock: return self._end = value / self._parent._scale if self._end > (self._parent.width() / self._parent._scale): self._end = (self._parent.width() / self._parent._scale) @property def track(self): return Track.whichTrack(self._top) @track.setter def track(self, value): # if the object exists in other track remove it if self.track < len(self._parent._tracks) and self in self._parent._tracks[self.track].periods: self.remove() # Verify if the new track exists. In case not create it self._top = Track.whichTop(value) if self.track >= len(self._parent._tracks): self._parent.addTrack() # if do not exists in the track add it if self not in self._parent._tracks[self.track].periods: self._parent._tracks[self.track].periods.append(self) @property def color(self): return self._defautcolor @color.setter def color(self, value): self._defautcolor = QColor(value) if (type(value) == str) else value @property def bgrcolor(self): return self._defautcolor.blue(), self._defautcolor.green(), self._defautcolor.red() @property def properties(self): return ['P', self._lock, int(round(self._begin)), int(round(self._end)), self._title, self._defautcolor.name(), self.track] @properties.setter def properties(self, value): self._lock = value[1] == 'True' self._begin = int(value[2]) self._end = int(value[3]) self._title = value[4] self._defautcolor = QColor(value[5]) self.track = int(value[6]) self.checkNumberOfTracks()
class Settings(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.setGeometry(550, 250, 385, 450) self.setWindowTitle('Настройки таймера') with open("changes.txt", "rt", encoding="utf8") as f: text = f.read().split(';') color = text[0].replace('(', '').replace(')', '') self.note = text[1] col = [int(i) for i in color.split(', ')] self.col = QColor(col[0], col[1], col[2], col[3]) self.sld1 = QSlider(Qt.Horizontal, self) self.sld1.setFocusPolicy(Qt.NoFocus) self.sld1.setGeometry(50, 80, 150, 20) self.sld1.setTracking(True) self.sld1.setSliderPosition(250 - col[0]) self.sld1.valueChanged[int].connect(self.changeValueR) self.sld2 = QSlider(Qt.Horizontal, self) self.sld2.setFocusPolicy(Qt.NoFocus) self.sld2.setGeometry(50, 120, 150, 20) self.sld2.setTracking(True) self.sld2.setSliderPosition(250 - col[1]) self.sld2.valueChanged[int].connect(self.changeValueG) self.sld3 = QSlider(Qt.Horizontal, self) self.sld3.setFocusPolicy(Qt.NoFocus) self.sld3.setGeometry(50, 160, 150, 20) self.sld3.setTracking(True) self.sld3.setSliderPosition(250 - col[2]) self.sld3.valueChanged[int].connect(self.changeValueB) redlbl = QLabel('R', self) redlbl.resize(20, 20) redlbl.move(30, 78) greenlbl = QLabel('G', self) greenlbl.resize(20, 20) greenlbl.move(30, 118) bluelbl = QLabel('B', self) bluelbl.resize(20, 20) bluelbl.move(30, 158) self.square = QFrame(self) self.square.setGeometry(260, 80, 100, 100) self.square.setStyleSheet("QWidget { background-color: %s }" % self.col.name()) self.lblSetCol = QLabel('Настройки цвета \n(Чтобы принять изменения,' + '\n нажмите Enter в поле для заметки)', self) self.lblSetCol.setAlignment(Qt.AlignCenter) self.lblSetCol.resize(200, 40) self.lblSetCol.move(80, 15) self.lblSetNote = QLabel('Настройки напоминания \n' + '(Изменения принимаются при' + 'нажатии Enter в поле)', self) self.lblSetNote.setAlignment(Qt.AlignCenter) self.lblSetNote.resize(300, 40) self.lblSetNote.move(40, 200) self.lblInstrNote = QLabel('Введите текст (не более 40 символов):', self) self.lblInstrNote.resize(300, 20) self.lblInstrNote.move(50, 250) self.inpNote = QLineEdit(self) self.inpNote.resize(250, 30) self.inpNote.move(50, 276) self.inpNote.returnPressed.connect(self.OkAction) self.btnOk = QPushButton('OK', self) self.btnOk.resize(30, 30) self.btnOk.setEnabled(False) self.btnOk.move(160, 400) self.btnOk.clicked.connect(self.Confirm_changes) self.lblVerdict = QLabel(self) self.lblVerdict.resize(260, 40) self.lblVerdict.setAlignment(Qt.AlignCenter) self.lblVerdict.move(55, 335) self.lblVerdict.show() self.show() self.first_page = First_Main_Page() def changeValueR(self, value): self.col.setRed(250 - value) self.square.setStyleSheet("QFrame { background-color: %s }" % self.col.name()) self.show() def changeValueG(self, value): self.col.setGreen(250 - value) self.square.setStyleSheet("QFrame { background-color: %s }" % self.col.name()) self.show() def changeValueB(self, value): self.col.setBlue(250 - value) self.square.setStyleSheet("QFrame { background-color: %s }" % self.col.name()) self.show() def OkAction(self): self.note = self.inpNote.text() self.checkSettings() def checkSettings(self): class SettingsError(Exception): pass class NoteError(SettingsError): pass self.verdict = '' try: if len(self.note) > 40: msg = 'Количество символов не должно превышать 40.' msg += '\nВведите текст заново.' raise NoteError(msg) self.verdict = 'Изменения приняты.' self.btnOk.setDisabled(False) except NoteError as e: self.verdict = '\n' + str(e) self.btnOk.setEnabled(False) finally: self.lblVerdict.setText(self.verdict) self.lblVerdict.show() def Confirm_changes(self): try: col = self.col.getRgb() with open("changes.txt", "wt", encoding="utf8") as f: f.write(str(col) + ';' + self.note) current_color = QColor(col[0], col[1], col[2], col[3]) self.hide() self.first_page.setStyleSheet("QMainWindow { background-color: %s }" % current_color.name()) self.first_page.show() except Exception as e: print(e)
class Translate_RU(QDialog): def __init__(self, parent, theme): super().__init__() loadUi('qt_ui/torussian.ui', self) self.parent = parent self.theme = theme self.col_false = QColor(255, 0, 0) self.col_true = QColor(0, 255, 0) self.col = QColor(0, 0, 0) self.num_done = 0 self.num_true = 0 self.wrong_words = [] self.themes = self.parent.themes self.words = [] self.all_words = self.parent.words self.addwords() self.initui() self.show() def addwords(self): for word in self.all_words: if word["theme"] == self.theme: self.words.append(word) def initui(self): self.english_word.setText(self.words[self.num_done]['english_word']) # append self.remark.setText(self.words[self.num_done]['remark']) self.buttonANSWER.setText('ANSWER') self.buttonANSWER.autoDefault() self.buttonANSWER.clicked.connect(self.button_answer) self.buttonSTOP.clicked.connect(self.button_stop) self.progress.setRange(1, len(self.words)) # self.ButtonExit.clicked.connect(lambda : self.close()) self.update_progress() def button_stop(self): self.exit_question = Exit_question(self) self.close def update_progress(self): self.progress.setValue(self.num_done + 1) self.partProcess.setText('%s / %s' % (str(self.num_done + 1), str(len(self.words)))) def button_answer(self): print('button ANSWER clicked') self.russian_word.setStyleSheet("QTextEdit { color: %s }" % self.col.name()) if line_treatment(self.russian_word.toPlainText()) == self.words[self.num_done][ 'russian_word']: # если слово введено правильно print('YES') self.russian_word.setStyleSheet( "QTextEdit { color: %s }" % self.col_true.name()) # меняю цвет текста на зеленый self.num_true += 1 self.words[self.num_done]["rating"] -= 10 else: print('NO') self.wrong_words.append(self.words[self.num_done]) self.error.setText(self.words[self.num_done]['russian_word']) # выводим правильный ответ self.russian_word.setStyleSheet( "QTextEdit { color: %s }" % self.col_false.name()) # меняю цвет текста на красный self.buttonANSWER.setText('Next') # меняю название кнопки self.buttonANSWER.clicked.connect(self.answ_next) self.buttonANSWER.clicked.disconnect(self.button_answer) def answ_next(self): print('button NEXT clicked') self.num_done += 1 self.russian_word.setStyleSheet("QTextEdit { color: %s }" % self.col.name()) # возвращаю черный цвет текста self.buttonANSWER.setText('ANSWER') # меняю название кнопки self.buttonANSWER.clicked.connect(self.button_answer) self.buttonANSWER.clicked.disconnect(self.answ_next) print(self.num_done) if self.num_done < len(self.words): self.english_word.clear() self.russian_word.clear() self.error.clear() self.english_word.setText(self.words[self.num_done]['english_word']) # append self.remark.setText(self.words[self.num_done]['remark']) self.update_progress() if self.num_done >= len(self.words): self.complete() def complete(self): print("complete") self.results = Results(self) # вывод результатов - новое окно results self.close()
class mywindow(QtWidgets.QMainWindow): def __init__(self): super(mywindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.size = QDesktopWidget().availableGeometry() self.algorithms = [ "ЦДА", "Брезенхем с действит. числами", "Брезенхем с целыми числами", "Брезенхем с устранением ступенчатости", "Библиотечный (PyQt5)" ] self.singleColor = QColor(Qt.black) self.spectrumColor = QColor(Qt.black) self.singleAlgorithm = Algorithm.DDA self.spectrumAlgorithm = Algorithm.DDA self.__adjustWidgets() def __adjustWidgets(self): self.ui.button_chose_spec_color.clicked.connect(self.choseSpecColor) self.ui.colorButton.clicked.connect(self.choseColor) self.ui.showButton.clicked.connect(self.drawSingle) self.ui.button_draw_spec.clicked.connect(self.drawSpectrum) self.ui.combobox_alg_single.addItems(self.algorithms) self.ui.combobox_alg_spec.addItems(self.algorithms) self.ui.spin_box_xs.setMinimum(0) self.ui.spin_box_xs.setMaximum(self.size.width()) self.ui.spin_box_xe.setMinimum(0) self.ui.spin_box_xe.setMaximum(self.size.width()) self.ui.spin_box_ys.setMinimum(0) self.ui.spin_box_ys.setMaximum(self.size.width()) self.ui.spin_box_ye.setMinimum(0) self.ui.spin_box_ye.setMaximum(self.size.width()) self.ui.spin_box_len.setMinimum(1) self.ui.spin_box_len.setMaximum(self.size.height() / 2 - 20) self.ui.spin_box_step.setMinimum(1) self.ui.spin_box_step.setMaximum(180) def choseSpecColor(self): self.spectrumColor = QColorDialog.getColor() self.ui.widget_spec_color.setStyleSheet( "QWidget { background-color: %s }" % self.spectrumColor.name()) def drawSpectrum(self): len = self.ui.spin_box_len.value() step = self.ui.spin_box_step.value() self.spectrumAlgorithm = self.getAlg( self.ui.combobox_alg_spec.currentText()) drawableObject = SegmentSpectrum(len, step, True, self.spectrumAlgorithm, self.spectrumColor) self.newWindowSpec = Drawing(drawableObject) self.newWindowSpec.show() def drawSingle(self): xs = self.ui.spin_box_xs.value() ys = self.ui.spin_box_ys.value() xe = self.ui.spin_box_xe.value() ye = self.ui.spin_box_ye.value() self.singleAlgorithm = self.getAlg( self.ui.combobox_alg_single.currentText()) if QPoint(xs, ys) != QPoint(xe, ye): drawableObject = Segment(xs, ys, xe, ye, self.singleAlgorithm, self.singleColor) self.newWindow = Drawing(drawableObject) self.newWindow.show() else: self.__showErrorMessage("Начало и конец отрезка совпадают!") def getAlg(self, string): if string == self.algorithms[0]: return Algorithm.DDA elif string == self.algorithms[1]: return Algorithm.BRN elif string == self.algorithms[2]: return Algorithm.BIN elif string == self.algorithms[3]: return Algorithm.BAA elif string == self.algorithms[4]: return Algorithm.LA def choseColor(self): self.singleColor = QColorDialog.getColor() self.ui.widget_color.setStyleSheet("QWidget { background-color: %s }" % self.singleColor.name()) def __showErrorMessage(self, message): error_message = QErrorMessage(self) error_message.setWindowTitle("Error") error_message.showMessage(message)
class AppBuffer(BrowserBuffer): def __init__(self, buffer_id, url, arguments): BrowserBuffer.__init__(self, buffer_id, url, arguments, False) self.config_dir = get_emacs_config_dir() # When arguments is "temp_html_file", browser will load content of html file, then delete temp file. # Usually use for render html mail. if arguments == "temp_html_file": with open(url, "r") as html_file: self.buffer_widget.setHtml(html_file.read()) if os.path.exists(url): os.remove(url) else: self.buffer_widget.setUrl(QUrl(url)) self.history_list = [] if get_emacs_var("eaf-browser-remember-history"): self.history_log_file_path = os.path.join(self.config_dir, "browser", "history", "log.txt") self.history_pattern = re.compile("^(.+)ᛝ(.+)ᛡ(.+)$") self.noprefix_url_pattern = re.compile("^(https?|file)://(.+)") self.nopostfix_url_pattern = re.compile("^[^#\?]*") self.history_close_file_path = os.path.join( self.config_dir, "browser", "history", "close.txt") touch(self.history_log_file_path) with open(self.history_log_file_path, "r", encoding="utf-8") as f: raw_list = f.readlines() for raw_his in raw_list: his_line = re.match(self.history_pattern, raw_his) if his_line is None: # Obsolete Old history format old_his = re.match("(.*)\s((https?|file):[^\s]+)$", raw_his) if old_his is not None: self.history_list.append( HistoryPage(old_his.group(1), old_his.group(2), 1)) else: self.history_list.append( HistoryPage(his_line.group(1), his_line.group(2), his_line.group(3))) self.autofill = PasswordDb( os.path.join(os.path.dirname(self.config_dir), "browser", "password.db")) self.pw_autofill_id = 0 self.pw_autofill_raw = self.buffer_widget.read_js_content( "pw_autofill.js") self.readability_js = open(os.path.join( os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "node_modules", "@mozilla", "readability", "Readability.js"), encoding="utf-8").read() self.close_page.connect(self.record_close_page) self.buffer_widget.titleChanged.connect(self.record_history) self.buffer_widget.titleChanged.connect(self.change_title) self.buffer_widget.translate_selected_text.connect(translate_text) self.buffer_widget.urlChanged.connect(self.set_adblocker) self.buffer_widget.urlChanged.connect(self.caret_exit) # Record url when url changed. self.buffer_widget.urlChanged.connect(self.update_url) self.buffer_widget.urlChanged.connect(self.skip_youtube_ads) # Draw progressbar. self.progressbar_progress = 0 self.progressbar_color = QColor( get_emacs_var("eaf-emacs-theme-foreground-color")) self.progressbar_height = 2 self.buffer_widget.loadStarted.connect(self.start_progress) self.buffer_widget.loadProgress.connect(self.update_progress) self.is_loading = False # Reverse background and foreground color, to help cursor recognition. self.caret_foreground_color = QColor( get_emacs_var("eaf-emacs-theme-background-color")) self.caret_background_color = QColor( get_emacs_var("eaf-emacs-theme-foreground-color")) # Reset to default zoom when page init or page url changed. self.reset_default_zoom() self.buffer_widget.urlChanged.connect( lambda url: self.reset_default_zoom()) # Reset zoom after page loading finish. # Otherwise page won't zoom if we call setUrl api in current page. self.buffer_widget.loadFinished.connect( lambda: self.buffer_widget.zoom_reset()) self.buffer_widget.create_new_window = self.create_new_window def drawForeground(self, painter, rect): # Draw progress bar. if self.progressbar_progress > 0 and self.progressbar_progress < 100: painter.setBrush(self.progressbar_color) painter.drawRect( 0, 0, rect.width() * self.progressbar_progress * 1.0 / 100, self.progressbar_height) @QtCore.pyqtSlot() def start_progress(self): ''' Initialize the Progress Bar.''' self.is_loading = True self.progressbar_progress = 0 self.update() @QtCore.pyqtSlot(int) def update_progress(self, progress): ''' Update the Progress Bar.''' self.progressbar_progress = progress # We need load dark mode js always, otherwise will white flash when loading page. if self.is_dark_mode_enabled: self.buffer_widget.load_dark_mode_js() self.buffer_widget.enable_dark_mode() if progress < 100: # Update progress. self.caret_js_ready = False self.update() elif progress == 100: if self.is_loading: self.is_loading = False self.buffer_widget.load_marker_file() cursor_foreground_color = "" cursor_background_color = "" self.caret_browsing_js = self.buffer_widget.caret_browsing_js_raw.replace( "%1", cursor_foreground_color).replace("%2", cursor_background_color) self.buffer_widget.eval_js(self.caret_browsing_js) self.caret_js_ready = True if self.dark_mode_is_enabled(): if get_emacs_var("eaf-browser-dark-mode") == "follow": cursor_foreground_color = self.caret_background_color.name( ) cursor_background_color = self.caret_foreground_color.name( ) else: cursor_foreground_color = "#FFF" cursor_background_color = "#000" else: if get_emacs_var("eaf-browser-dark-mode") == "follow": cursor_foreground_color = self.caret_background_color.name( ) cursor_background_color = self.caret_foreground_color.name( ) else: cursor_foreground_color = "#000" cursor_background_color = "#FFF" self.after_page_load_hook() # Run after page load hook def after_page_load_hook(self): ''' Hook to run after update_progress hits 100. ''' self.init_pw_autofill() if get_emacs_var("eaf-browser-enable-adblocker"): self.load_adblocker() def handle_input_response(self, callback_tag, result_content): ''' Handle input message.''' if not BrowserBuffer.handle_input_response(self, callback_tag, result_content): if callback_tag == "clear_history": self._clear_history() elif callback_tag == "import_chrome_history": self._import_chrome_history() elif callback_tag == "clear_cookies": self._clear_cookies() def try_start_aria2_daemon(self): ''' Try to start aria2 daemon.''' if not is_port_in_use(6800): with open(os.devnull, "w") as null_file: aria2_args = ["aria2c"] aria2_args.append("-d") # daemon aria2_args.append("-c") # continue download aria2_args.append("--auto-file-renaming={}".format( str(get_emacs_var( "eaf-browser-aria2-auto-file-renaming")))) aria2_args.append("-d {}".format( os.path.expanduser( get_emacs_var("eaf-browser-download-path")))) aria2_proxy_host = get_emacs_var( "eaf-browser-aria2-proxy-host") aria2_proxy_port = get_emacs_var( "eaf-browser-aria2-proxy-port") if aria2_proxy_host != "" and aria2_proxy_port != "": aria2_args.append("--all-proxy") aria2_args.append("http://{0}:{1}".format( aria2_proxy_host, aria2_proxy_port)) aria2_args.append("--enable-rpc") aria2_args.append("--rpc-listen-all") subprocess.Popen(aria2_args, stdout=null_file) @interactive(insert_or_do=True) def open_downloads_setting(self): ''' Open aria2 download manage page. ''' self.try_start_aria2_daemon() index_file = os.path.join(os.path.dirname(__file__), "aria2-ng", "index.html") self.buffer_widget.open_url_new_buffer( QUrl.fromLocalFile(index_file).toString()) def record_close_page(self, url): ''' Record closing pages.''' self.page_closed = True if get_emacs_var( "eaf-browser-remember-history" ) and self.arguments != "temp_html_file" and url != "about:blank": touch(self.history_close_file_path) with open(self.history_close_file_path, "r") as f: close_urls = f.readlines() close_urls.append("{0}\n".format(url)) open(self.history_close_file_path, "w").writelines(close_urls) @interactive(insert_or_do=True) def recover_prev_close_page(self): ''' Recover previous closed pages.''' if os.path.exists(self.history_close_file_path): with open(self.history_close_file_path, "r") as f: close_urls = f.readlines() if len(close_urls) > 0: # We need use rstrip remove \n char from url record. prev_close_url = close_urls.pop().rstrip() open_url_in_new_tab(prev_close_url) open(self.history_close_file_path, "w").writelines(close_urls) message_to_emacs("Recovery {0}".format(prev_close_url)) else: message_to_emacs("No page need recovery.") else: message_to_emacs("No page need recovery.") def load_adblocker(self): self.buffer_widget.load_css( os.path.join(os.path.dirname(__file__), "adblocker.css"), 'adblocker') @interactive def toggle_adblocker(self): ''' Change adblocker status.''' if get_emacs_var("eaf-browser-enable-adblocker"): set_emacs_var("eaf-browser-enable-adblocker", False) self.buffer_widget.remove_css('adblocker', True) message_to_emacs("Successfully disabled adblocker!") elif not get_emacs_var("eaf-browser-enable-adblocker"): set_emacs_var("eaf-browser-enable-adblocker", True) self.load_adblocker() message_to_emacs("Successfully enabled adblocker!") def update_url(self, url): self.url = self.buffer_widget.url().toString() def set_adblocker(self, url): if get_emacs_var( "eaf-browser-enable-adblocker") and not self.page_closed: self.load_adblocker() def skip_youtube_ads(self, url): url = self.buffer_widget.url().toString() if (url.startswith("https://www.youtube.com/") ) and url != "https://www.youtube.com/": # Trick: add dot after 'com' to get free ad url. urls = url.split("https://www.youtube.com") free_ad_url = "https://www.youtube.com." + urls[1] # Use stop and load methods instead setUrl, avoid trigger "urlChanged" signal recursively. self.buffer_widget.stop() self.buffer_widget.load(QUrl(free_ad_url)) def add_password_entry(self): self.buffer_widget.eval_js(self.pw_autofill_raw.replace("%1", "''")) password, form_data = self.buffer_widget.execute_js( "retrievePasswordFromPage();") if password != "": self.autofill.add_entry( urlparse(self.current_url).hostname, password, form_data) message_to_emacs("Successfully recorded this page's password!") return True else: message_to_emacs("There is no password present in this page!") return False def pw_autofill_gen_id(self, id): result = self.autofill.get_entries(urlparse(self.url).hostname, id) new_id = 0 for row in result: new_id = row[0] password = row[2] form_data = row[3] self.buffer_widget.eval_js( self.pw_autofill_raw.replace("%1", form_data)) self.buffer_widget.eval_js('autofillPassword("%s");' % password) break return new_id def init_pw_autofill(self): if get_emacs_var("eaf-browser-enable-autofill"): self.pw_autofill_id = self.pw_autofill_gen_id(0) @interactive def save_page_password(self): ''' Record form data.''' if get_emacs_var("eaf-browser-enable-autofill"): self.add_password_entry() else: message_to_emacs( "Password autofill is not enabled! Enable with `C-t` (default binding)" ) @interactive def toggle_password_autofill(self): ''' Toggle Autofill status for password data''' if not get_emacs_var("eaf-browser-enable-autofill"): set_emacs_var("eaf-browser-enable-autofill", True) self.pw_autofill_id = self.pw_autofill_gen_id(0) message_to_emacs("Successfully enabled autofill!") else: self.pw_autofill_id = self.pw_autofill_gen_id(self.pw_autofill_id) if self.pw_autofill_id == 0: set_emacs_var("eaf-browser-enable-autofill", False) message_to_emacs("Successfully disabled password autofill!") else: message_to_emacs("Successfully changed password autofill id!") def _record_history(self, new_title, new_url): # Throw traceback info if algorithm has bug and protection of historical record is not erased. try: noprefix_new_url_match = re.match(self.noprefix_url_pattern, new_url) if noprefix_new_url_match is not None: found = False for history in self.history_list: noprefix_url_match = re.match(self.noprefix_url_pattern, history.url) if noprefix_url_match is not None: noprefix_url = noprefix_url_match.group(2) noprefix_new_url = noprefix_new_url_match.group(2) nopostfix_new_url_match = re.match( self.nopostfix_url_pattern, noprefix_new_url) if noprefix_url == noprefix_new_url: # found unique url history.title = new_title history.url = new_url history.hit += 0.5 found = True elif nopostfix_new_url_match is not None and noprefix_url == nopostfix_new_url_match.group( ): # also increment parent history.hit += 0.25 if not found: self.history_list.append(HistoryPage( new_title, new_url, 1)) self.history_list.sort(key=lambda x: x.hit, reverse=True) with open(self.history_log_file_path, "w", encoding="utf-8") as f: f.writelines( map( lambda history: history.title + "ᛝ" + history.url + "ᛡ" + str(history.hit) + "\n", self.history_list)) except Exception: import traceback message_to_emacs("Error in record_history: " + str(traceback.print_exc())) def record_history(self, new_title): ''' Record browser history.''' new_url = self.buffer_widget.filter_url(self.buffer_widget.get_url()) if get_emacs_var("eaf-browser-remember-history") and self.buffer_widget.filter_title(new_title) != "" and \ self.arguments != "temp_html_file" and new_title != "about:blank" and new_url != "about:blank": self._record_history(new_title, new_url) @interactive(insert_or_do=True) def new_blank_page(self): ''' Open new blank page.''' eval_in_emacs( 'eaf-open', [get_emacs_var("eaf-browser-blank-page-url"), "browser", "", 't']) def _clear_history(self): if os.path.exists(self.history_log_file_path): os.remove(self.history_log_file_path) message_to_emacs("Cleared browsing history.") else: message_to_emacs("There is no browsing history.") @interactive def clear_history(self): ''' Clear browsing history.''' self.send_input_message( "Are you sure you want to clear all browsing history?", "clear_history", "yes-or-no") def _import_chrome_history(self): dbpath = os.path.expanduser( get_emacs_var("eaf-browser-chrome-history-file")) if not os.path.exists(dbpath): message_to_emacs( "The chrome history file: '{}' not exist, please check your setting." .format(dbpath)) return message_to_emacs("Importing from {}...".format(dbpath)) conn = sqlite3.connect(dbpath) # Keep lastest entry in dict by last_visit_time asc order. sql = 'select title, url from urls order by last_visit_time asc' # May fetch many by many not fetch all, # but this should called only once, so not important now. try: chrome_histories = conn.execute(sql).fetchall() except sqlite3.OperationalError as e: if e.args[0] == 'database is locked': message_to_emacs( "The chrome history file is locked, please close your chrome app first." ) else: message_to_emacs( "Failed to read chrome history entries: {}.".format(e)) return histories = dict( chrome_histories) # Drop duplications with same title. total = len(histories) for i, (title, url) in enumerate(histories.items(), 1): self._record_history(title, url) message_to_emacs("Importing {} / {} ...".format(i, total)) message_to_emacs( "{} chrome history entries imported.".format(total)) @interactive def import_chrome_history(self): ''' Import history entries from chrome history db.''' self.send_input_message( "Are you sure you want to import all history from chrome?", "import_chrome_history", "yes-or-no") def _clear_cookies(self): ''' Clear cookies.''' self.buffer_widget.cookie_storage.clear_cookies( self.buffer_widget.cookie_store) message_to_emacs("Cleared all cookies.") @interactive def clear_cookies(self): ''' Clear cookies.''' self.send_input_message( "Are you sure you want to clear all browsing cookies?", "clear_cookies", "yes-or-no") @interactive(insert_or_do=True) def switch_to_reader_mode(self): self.buffer_widget.eval_js(self.readability_js) html = self.buffer_widget.execute_js( "new Readability(document).parse().content;") if html == None: self.refresh_page() message_to_emacs( "Cannot parse text content of current page, failed to switch reader mode." ) else: self.buffer_widget.setHtml( "<style> #readability-page-1 { width: 60%; margin: auto; } </style>" + html) @interactive(insert_or_do=True) def export_text(self): self.buffer_widget.eval_js(self.readability_js) text = self.buffer_widget.execute_js( "new Readability(document).parse().textContent;") self.refresh_page() eval_in_emacs('eaf--browser-export-text', ["EAF-BROWSER-TEXT-" + self.url, text]) def page_is_loading(self): return self.is_loading @interactive(insert_or_do=True) def translate_page(self): import locale system_language = locale.getdefaultlocale()[0].replace("_", "-") translate_language = get_emacs_var("eaf-browser-translate-language") language = system_language if translate_language == "" else translate_language url = urllib.parse.quote(self.buffer_widget.url().toString(), safe='') open_url_in_new_tab( "https://translate.google.com/translate?hl=en&sl=auto&tl={}&u={}". format(language, url)) message_to_emacs("Translating page...") def get_new_window_buffer_id(self): ''' Return new browser window's buffer ID. ''' import secrets return "{0}-{1}-{2}-{3}-{4}-{5}-{6}".format(secrets.token_hex(2), secrets.token_hex(2), secrets.token_hex(2), secrets.token_hex(2), secrets.token_hex(2), secrets.token_hex(2), secrets.token_hex(2)) def create_new_window(self): ''' Create new browser window.''' # Generate buffer id same as eaf.el does. buffer_id = self.get_new_window_buffer_id() # Create buffer for create new browser window. app_buffer = self.create_buffer(buffer_id, "http://0.0.0.0", self.module_path, "") # Create emacs buffer with buffer id. eval_in_emacs('eaf--create-new-browser-buffer', [buffer_id]) # Return new QWebEngineView for create new browser window. return app_buffer.buffer_widget def dark_mode_is_enabled(self): ''' Return bool of whether dark mode is enabled.''' return (get_emacs_var("eaf-browser-dark-mode") == "force" or \ get_emacs_var("eaf-browser-dark-mode") == True or \ (get_emacs_var("eaf-browser-dark-mode") == "follow" and \ get_emacs_var("eaf-emacs-theme-mode") == "dark")) and \ not self.url.startswith("devtools://")
class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): cb = QCheckBox('Show title', self) cb.move(20,20) cb.toggle() cb.stateChanged.connect(self.changeTitle) self.col = QColor(0,0,0) redb = QPushButton('red', self) redb.setCheckable(True) redb.move(20, 60) redb.clicked[bool].connect(self.setColor) greenb = QPushButton('green', self) greenb.setCheckable(True) greenb.move(20, 110) greenb.clicked[bool].connect(self.setColor) blueb = QPushButton('blue', self) blueb.setCheckable(True) blueb.move(20, 160) blueb.clicked[bool].connect(self.setColor) self.square = QFrame(self) self.square.setGeometry(150, 60, 100, 100) self.square.setStyleSheet("QWidget { background-color: %s }" % self.col.name()) sld = QSlider(Qt.Horizontal, self) sld.setFocusPolicy(Qt.NoFocus) sld.setGeometry(20, 250, 100, 30) sld.valueChanged[int].connect(self.changeValue) self.label = QLabel(self) self.label.setPixmap(QPixmap('mute.gif')) self.label.setGeometry(150, 200, 150, 150) self.pbar = QProgressBar(self) self.pbar.setGeometry(20, 380, 200, 25) self.pbtn = QPushButton('start', self) self.pbtn.move(30, 420) self.pbtn.clicked.connect(self.doAction) self.timer = QBasicTimer() self.step = 0 cal = QCalendarWidget(self) cal.setGridVisible(True) cal.move(20, 510) cal.clicked[QDate].connect(self.showDate) self.lbl = QLabel(self) date = cal.selectedDate() self.lbl.setText(date.toString()) self.lbl.move(230, 510) self.setGeometry(300, 30, 580, 670) self.setWindowTitle('QCheckBox') self.show() def changeTitle(self, state): if state == Qt.Checked: self.setWindowTitle('QCheckBox') else: self.setWindowTitle(' ') def setColor(self, pressed): source = self.sender() if pressed: val = 255 else: val = 0 if source.text() == "red": self.col.setRed(val) elif source.text() == "green": self.col.setGreen(val) else: self.col.setBlue(val) self.square.setStyleSheet("QFrame { background-color: %s }" % self.col.name()) def changeValue(self, value): if value == 0: self.label.setPixmap(QPixmap('mute.gif')) elif value > 0 and value <= 30: self.label.setPixmap(QPixmap('min.gif')) elif value > 30 and value <= 80: self.label.setPixmap(QPixmap('med.gif')) else: self.label.setPixmap(QPixmap('max.gif')) def timerEvent(self, e): if self.step >= 100: self.timer.stop() self.pbtn.setText("finished") return self.step = self.step + 1 self.pbar.setValue(self.step) def doAction(self): if self.timer.isActive(): self.timer.stop() self.pbtn.setText('start') else: self.timer.start(100, self) self.pbtn.setText('stop') def showDate(self, date): self.lbl.setText(date.toString())
class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): # checkbox cb = QCheckBox('show title', self) cb.move(20, 20) cb.toggle() cb.stateChanged.connect(self.changeTitle) # toggle button self.col = QColor(0, 0, 0) redb = QPushButton('red', self) redb.setCheckable(True) redb.move(20, 40) redb.clicked[bool].connect(self.setColor) greenb = QPushButton('green', self) greenb.setCheckable(True) greenb.move(20, 60) greenb.clicked[bool].connect(self.setColor) blueb = QPushButton('blue', self) blueb.setCheckable(True) blueb.move(20, 80) blueb.clicked[bool].connect(self.setColor) self.square = QFrame(self) self.square.setGeometry(150, 20, 100, 100) self.square.setStyleSheet('QWidget {background-color: %s}' % self.col.name()) # slider sld = QSlider(Qt.Horizontal, self) sld.setFocusPolicy(Qt.NoFocus) sld.setGeometry(20, 160, 100, 20) sld.valueChanged[int].connect(self.changeValue) self.label = QLabel('0', self) self.label.setGeometry(140, 155, 80, 30) # progressbar self.pbar = QProgressBar(self) self.pbar.setGeometry(20, 200, 200, 25) self.btn = QPushButton('start', self) self.btn.move(20, 230) self.btn.clicked.connect(self.doAction) self.timer = QBasicTimer() self.step = 0 # calendar cal = QCalendarWidget(self) cal.setGridVisible(True) cal.move(20, 300) cal.clicked[QDate].connect(self.showDate) self.lbl = QLabel(self) date = cal.selectedDate() self.lbl.setText(date.toString()) self.lbl.move(20, 280) self.setGeometry(300, 300, 400, 550) self.setWindowTitle('widgets') self.show() def showDate(self, date): self.lbl.setText(date.toString()) def timerEvent(self, e): if self.step >= 100: self.timer.stop() self.btn.setText('finished') return self.step = self.step + 1 self.pbar.setValue(self.step) def doAction(self): if self.timer.isActive(): self.timer.stop() else: self.timer.start(100, self) self.btn.setText('stop') def changeValue(self, value): self.label.setText(str(value)) def setColor(self, pressed): source = self.sender() if pressed: val = 255 else: val = 0 if source.text() == 'red': self.col.setRed(val) elif source.text() == 'green': self.col.setGreen(val) else: self.col.setBlue(val) self.square.setStyleSheet('QFrame {background-color: %s}' % self.col.name()) def changeTitle(self, state): if state == Qt.Checked: self.setWindowTitle('widgets') else: self.setWindowTitle('')
class FancyPushButton(QtWidgets.QPushButton): clicked = pyqtSignal() """ Button with animation effect. color1 is the color on the right, color2 on the left. """ def __init__(self, width, height, parent=None, *args, **kwargs): super().__init__(parent) self.setMinimumSize(width, height) if len(kwargs) == 0: self.color1 = QColor(240, 53, 218) self.color2 = QColor(61, 217, 245) else: self.color1 = QColor( kwargs.get('color1', None)[0], kwargs.get('color1', None)[1], kwargs.get('color1', None)[2]) self.color2 = QColor( kwargs.get('color2', None)[0], kwargs.get('color2', None)[1], kwargs.get('color2', None)[2]) self._animation = QVariantAnimation(self, valueChanged=self._animate, startValue=0.00001, endValue=0.9999, duration=250) # self.setStyleSheet("QPushButton:disabled {color:white;background-color: grey; border-style: outset;border-radius: 8px;border-width: 2px;font: bold 12px;padding: 6px}") self.setGraphicsEffect( QGraphicsDropShadowEffect(blurRadius=3, xOffset=2, yOffset=2)) def _animate(self, value): qss = """ font: 75 8pt "Microsoft YaHei UI"; font-weight: bold; color: rgb(255, 255, 255); border-style: solid; border-radius:8px; """ grad = "background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 {color1}, stop:{value} {color2}, stop: 1.0 {color1});".format( color1=self.color1.name(), color2=self.color2.name(), value=value) qss += grad self.setStyleSheet(qss) def enterEvent(self, event): self._animation.setDirection(QAbstractAnimation.Forward) self._animation.start() super().enterEvent(event) def leaveEvent(self, event): self._animation.setDirection(QAbstractAnimation.Backward) self._animation.start() super().enterEvent(event) def mousePressEvent(self, event): self._animation.setDirection(QAbstractAnimation.Forward) self._animation.start() self.clicked.emit() super().enterEvent(event)