Ejemplo n.º 1
0
class DesktopWideOverlay(QMainWindow):
    _instances: Dict[int, QGraphicsItem]
    view: QGraphicsView
    scene: QGraphicsScene

    def __init__(self):
        super().__init__(flags=Qt.Widget
                         | Qt.FramelessWindowHint
                         | Qt.BypassWindowManagerHint
                         | Qt.WindowTransparentForInput
                         | Qt.WindowStaysOnTopHint)
        self.logger = logging.getLogger(__name__ + "." +
                                        self.__class__.__name__)
        self.setAttribute(Qt.WA_NoSystemBackground, True)
        self.setAttribute(Qt.WA_TranslucentBackground, True)
        self.setAttribute(Qt.WA_DeleteOnClose, True)
        self.setStyleSheet("background: transparent")
        self._instances = {}

        virtual_screen = QRect(0, 0, 0, 0)

        for screen in QGuiApplication.screens():
            # TODO: Handle screen change
            geom = screen.virtualGeometry()
            virtual_screen = virtual_screen.united(geom)

        self.scene = QGraphicsScene(0,
                                    0,
                                    virtual_screen.width(),
                                    virtual_screen.height(),
                                    parent=self)

        self.view = QGraphicsView(self.scene, self)
        self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setStyleSheet("background: transparent")
        self.view.setGeometry(0, 0, virtual_screen.width(),
                              virtual_screen.height())
        self.view.setInteractive(False)

        self.transparent_pen = QPen()
        self.transparent_pen.setBrush(Qt.NoBrush)

        self.setGeometry(virtual_screen)

    def add_instance(
            self, instance: "GameInstance"
    ) -> Tuple[QGraphicsItem, Callable[[], None]]:
        """Add instance to manage, return a disconnect function and the canvas"""
        positionChanged = lambda rect: self.on_instance_moved(instance, rect)
        instance.positionChanged.connect(positionChanged)

        focusChanged = lambda focus: self.on_instance_focus_change(
            instance, focus)
        instance.focusChanged.connect(focusChanged)

        instance_pos = instance.get_position()
        gfx = QGraphicsRectItem(rect=instance_pos)
        gfx.setPen(self.transparent_pen)
        gfx.setPos(instance_pos.x(), instance_pos.y())
        self.scene.addItem(gfx)
        self._instances[instance.wid] = gfx

        def disconnect():
            gfx.hide()
            self.scene.removeItem(gfx)
            instance.positionChanged.disconnect(positionChanged)
            instance.focusChanged.disconnect(focusChanged)

        return gfx, disconnect

    def on_instance_focus_change(self, instance, focus):
        # self._instances[instance.wid].setVisible(focus)
        pass

    def on_instance_moved(self, instance, pos: QRect):
        rect = self._instances[instance.wid]
        rect.setRect(0, 0, pos.width(), pos.height())
        rect.setPos(pos.x(), pos.y())

    def check_compatibility(self):
        QTimer.singleShot(300, self._check_compatibility)

    def _check_compatibility(self):
        # If we cause black screen then hide ourself out of shame...
        screenshot = QGuiApplication.primaryScreen().grabWindow(0)
        image = qpixmap_to_np(screenshot)
        black_pixels = np.count_nonzero(
            np.all(image[:, :, :3] == [0, 0, 0], axis=-1))
        total_pixels = len(image[:, :, 0].flatten())
        black_percent = black_pixels / total_pixels

        self.logger.debug("Screen black ratio %.2f%%", black_percent * 100)
        if black_percent > 0.95:
            self.logger.warning(
                "Detected black screen at %.2f%%. Disabling overlay",
                black_percent * 100,
            )
        self.hide()
Ejemplo n.º 2
0
class DesktopWideOverlay(QMainWindow):
    _instances: Dict[int, QGraphicsItem]
    view: QGraphicsView
    scene: QGraphicsScene

    def __init__(self):
        super().__init__(flags=Qt.Widget
                         | Qt.FramelessWindowHint
                         | Qt.BypassWindowManagerHint
                         | Qt.WindowTransparentForInput
                         | Qt.WindowStaysOnTopHint)
        self.setAttribute(Qt.WA_NoSystemBackground, True)
        self.setAttribute(Qt.WA_TranslucentBackground, True)
        self.setAttribute(Qt.WA_DeleteOnClose, True)
        self._instances = {}

        virtual_screen = QRect(0, 0, 0, 0)

        for screen in QGuiApplication.screens():
            # TODO: Handle screen change
            geom = screen.virtualGeometry()
            virtual_screen = virtual_screen.united(geom)

        self.scene = QGraphicsScene(0,
                                    0,
                                    virtual_screen.width(),
                                    virtual_screen.height(),
                                    parent=self)

        self.view = QGraphicsView(self.scene, self)
        self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setStyleSheet("background: transparent")
        self.view.setGeometry(0, 0, virtual_screen.width(),
                              virtual_screen.height())
        self.view.setInteractive(False)

        self.transparent_pen = QPen()
        self.transparent_pen.setBrush(Qt.NoBrush)

        self.setGeometry(virtual_screen)

    def add_instance(
            self, instance: "GameInstance"
    ) -> Tuple[QGraphicsItem, Callable[[], None]]:
        """Add instance to manage, return a disconnect function and the canvas"""
        positionChanged = lambda rect: self.on_instance_moved(instance, rect)
        instance.positionChanged.connect(positionChanged)

        focusChanged = lambda focus: self.on_instance_focus_change(
            instance, focus)
        instance.focusChanged.connect(focusChanged)

        instance_pos = instance.get_position()
        gfx = QGraphicsRectItem(rect=instance_pos)
        gfx.setPen(self.transparent_pen)
        gfx.setPos(instance_pos.x(), instance_pos.y())
        self.scene.addItem(gfx)
        self._instances[instance.wid] = gfx

        def disconnect():
            gfx.hide()
            self.scene.removeItem(gfx)
            instance.positionChanged.disconnect(positionChanged)
            instance.focusChanged.disconnect(focusChanged)

        return gfx, disconnect

    def on_instance_focus_change(self, instance, focus):
        # self._instances[instance.wid].setVisible(focus)
        pass

    def on_instance_moved(self, instance, pos: QRect):
        rect = self._instances[instance.wid]
        rect.setRect(0, 0, pos.width(), pos.height())
        rect.setPos(pos.x(), pos.y())
Ejemplo n.º 3
0
class QGameOfLife(QWidget):

    Games = {
        "Game of Life": (GameOfLife, {
            'fill_rate': 0.50
        }),
        "Bacteria": (GrayScottDiffusion, {
            'coeffs': (0.16, 0.08, 0.035, 0.065)
        }),
        "Coral": (GrayScottDiffusion, {
            'coeffs': (0.16, 0.08, 0.062, 0.062)
        }),
        "Fingerprint": (GrayScottDiffusion, {
            'coeffs': (0.19, 0.05, 0.060, 0.062)
        }),
        "Spirals": (GrayScottDiffusion, {
            'coeffs': (0.10, 0.10, 0.018, 0.050)
        }),
        "Unstable": (GrayScottDiffusion, {
            'coeffs': (0.16, 0.08, 0.020, 0.055)
        }),
        "Worms": (GrayScottDiffusion, {
            'coeffs': (0.16, 0.08, 0.050, 0.065)
        }),
        "Zebrafish": (GrayScottDiffusion, {
            'coeffs': (0.16, 0.08, 0.035, 0.060)
        }),
    }

    def __init__(self, size=(400, 400)):
        super(QGameOfLife, self).__init__()
        self.size = size
        self.game = None
        self.initUI()
        self.show()

    def initUI(self):
        self.setWindowTitle(self.tr("Game of Life"))
        self.setLayout(QVBoxLayout())
        self.layout().setSpacing(0)
        self.layout().setContentsMargins(0, 0, 0, 0)

        self.comboBox = QComboBox()
        self.comboBox.addItems([*QGameOfLife.Games.keys()])
        self.comboBox.currentTextChanged.connect(self.select)
        self.layout().addWidget(self.comboBox)

        self.scene = QGraphicsScene()
        self.view = QGraphicsView(self.scene)
        self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setSizePolicy(
            QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred))
        self.view.setFrameShape(QFrame.NoFrame)
        self.layout().addWidget(self.view)

        self.item = None
        self.timer = QTimer()
        self.timer.setInterval(10)
        self.timer.timeout.connect(self.tick)
        initialGame = random.choice([*QGameOfLife.Games.keys()])
        self.select(initialGame)
        self.view.fitInView(self.item, Qt.KeepAspectRatioByExpanding)
        self.comboBox.setCurrentText(initialGame)

    def select(self, name: str):
        self.timer.stop()
        Game, args = QGameOfLife.Games[name]
        self.game = Game(self.size, **args)
        self.tick()
        self.timer.start()

    def tick(self):
        self.game.tick()
        bitmap = self.game.visualize()
        image = QImage(bitmap.data, bitmap.shape[1], bitmap.shape[0],
                       QImage.Format_Grayscale8)
        self.scene.removeItem(self.item)
        pixmap = QPixmap.fromImage(image)
        self.item = self.scene.addPixmap(pixmap)

    def resizeEvent(self, event: QResizeEvent):
        self.view.fitInView(self.item, Qt.KeepAspectRatioByExpanding)

    def sizeHint(self) -> QSize:
        return QSize(self.size[0], self.size[1])
Ejemplo n.º 4
0
class colorPicker(QDialog):
    "custom colorDialog from Orthallelous"
    currentColorChanged = Signal(QColor)
    colorSelected = Signal(QColor)

    def __init__(self, initial=None, parent=None):
        super(colorPicker, self).__init__(parent)
        self.setup()
        self.setColor(initial)

    def currentColor(self):
        return self._color

    def setColor(self, qcolor=None):
        if qcolor is None: self._color = QColor('#ffffff')
        else: self._color = QColor(qcolor)
        self._colorEdited()

    @staticmethod
    def getColor(initial=None, parent=None, title=None):
        dialog = colorPicker(initial, parent)
        if title: dialog.setWindowTitle(title)
        result = dialog.exec_()
        color = dialog._color
        return color

    def closeValid(self):
        "emits colorSelected signal with valid color on OK"
        self.currentColorChanged.emit(self._color)
        self.colorSelected.emit(self._color)
        self.close()

    def closeInvalid(self):
        "emits colorSelected signal with invalid color on Cancel"
        self._color = QColor()
        self.colorSelected.emit(QColor())
        self.close()

    def setOption(self, option, Bool=True):
        if option == QColorDialog.NoButtons:
            if not Bool:
                self.dialogButtons.blockSignals(False)
                self.dialogButtons.setEnabled(True)
                self.dialogButtons.show()
            else:
                self.dialogButtons.blockSignals(True)
                self.dialogButtons.setEnabled(False)
                self.dialogButtons.hide()
        self.setFixedSize(self.sizeHint())

    def _colorEdited(self):
        "internal color editing"
        sender, color = self.sender(), self._color
        for i in self.inputs:
            i.blockSignals(True)

        # get values
        if sender in self.rgbInputs:  # RGB
            color.setRgb(*[i.value() for i in self.rgbInputs])
        elif sender in self.hsvInputs:  # HSV
            color.setHsv(*[i.value() for i in self.hsvInputs])
        elif sender in self.cmykInputs:  # CMYK
            color.setCmyk(*[i.value() for i in self.cmykInputs])
        elif sender is self.htmlInput:  # HTML
            color.setNamedColor('#' + str(self.htmlInput.text()).lower())
        elif sender is self.colorWheel:  # WHEEL
            color = self._color = self.colorWheel.getColor()
        elif sender is self.colorNamesCB:  # NAMED
            dat = self.colorNamesCB.itemData(self.colorNamesCB.currentIndex())
            try:
                color = self._color = QColor(dat.toString())  # PyQt
            except:
                color = self._color = QColor(str(dat))  # PySide
            self.colorNamesCB.setToolTip(self.colorNamesCB.currentText())
        else:
            pass

        # set values
        for i, j in zip(color.getRgb()[:-1], self.rgbInputs):
            j.setValue(i)
        for i, j in zip(color.getHsv()[:-1], self.hsvInputs):
            j.setValue(i)
        for i, j in zip(color.getCmyk()[:-1], self.cmykInputs):
            j.setValue(i)
        self.htmlInput.setText(color.name()[1:])
        self.colorWheel.setColor(color)
        idx = self.colorNamesCB.findData(color.name())
        self.colorNamesCB.setCurrentIndex(idx)  # will be blank if not in list

        pal = self.colorDisplay.palette()
        pal.setColor(self.colorDisplay.backgroundRole(), color)
        self.colorDisplay.setPalette(pal)
        #self.colorDisplay.setStyleSheet('background:' + color.name())

        for i in self.inputs:
            i.blockSignals(False)
        self.currentColorChanged.emit(color)

    def pickColor(self):
        "pick a color on the screen, part 1"
        # screenshot desktop
        self._img = QApplication.primaryScreen().grabWindow(0)

        self._view = QGraphicsView(self)
        scene = QGraphicsScene(self)  # display screenshot at full size

        self._view.setWindowFlags(Qt.FramelessWindowHint)
        self._view.setWindowFlags(Qt.WindowType_Mask)
        self._view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self._view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scene.addPixmap(self._img)  #; self._view.setScene(scene)

        self._mag = magnifier()
        self._mag.setBackground(self._img)
        self._mag.setSize(11, 11)
        scene.addItem(self._mag)
        self._view.setScene(scene)

        self._appview = QApplication
        self._appview.setOverrideCursor(Qt.CrossCursor)

        self._view.showFullScreen()
        self._view.mousePressEvent = self._pickedColor

    def _pickedColor(self, event):
        "pick a color on the screen, part 2"
        color = QColor(self._img.toImage().pixel(event.globalPos()))

        self._view.hide()
        self._appview.restoreOverrideCursor()
        self._color = color
        self._colorEdited()
        self._mag = self._appview = self._view = self._img = None

    def showColors(self):
        "show location of colors on color wheel"
        if self.showButton.isChecked(): self.colorWheel.showNamedColors(True)
        else: self.colorWheel.showNamedColors(False)

    def useRandom(self, state=True):
        "toggles show colors button and random color button"
        if state:
            self.showButton.blockSignals(True)
            self.showButton.setChecked(False)
            self.showButton.hide()
            self.showColors()
            self.rndButton.blockSignals(False)
            self.rndButton.show()
        else:
            self.showButton.blockSignals(False)
            self.showButton.show()
            self.rndButton.blockSignals(True)
            self.rndButton.hide()

    def randomColor(self):
        "select a random color"
        rand = random.randint
        col = QColor()
        col.setHsv(rand(0, 359), rand(0, 255), rand(0, 255))
        #col.setRgb(rand(0, 255), rand(0, 255), rand(0, 255))
        self.setColor(col)
        return col

    def getNamedColors(self):
        "returns a list [(name, #html)] from the named colors combobox"
        lst = []
        for i in range(self.colorNamesCB.count()):
            name = str(self.colorNamesCB.itemText(i))
            try:  # PyQt
                html = str(self.colorNamesCB.itemData(i).toString())
            except AttributeError:  # PySide
                html = str(self.colorNamesCB.itemData(i))
            lst.append((name, html))
        return lst

    def addNamedColors(self, lst):
        "add a list [('name', '#html'), ] of named colors (repeats removed)"
        col = self.getNamedColors() + lst
        lst = [(i[0], QColor(i[1])) for i in col]
        sen = set()
        add = sen.add  # http://stackoverflow.com/a/480227
        uni = [x for x in lst if not (x[1].name() in sen or add(x[1].name()))]

        self.colorNamesCB.clear()
        for i, j in sorted(uni, key=lambda q: q[1].getHsv()):
            icon = QPixmap(16, 16)
            icon.fill(j)
            self.colorNamesCB.addItem(QIcon(icon), i, j.name())
        self.colorWheel.setNamedColors([(i, j.name()) for i, j in uni])
        self.cNameLabel.setToolTip('Named colors\n{:,} colors'.format(
            len(uni)))

    def setup(self):
        self.setAttribute(Qt.WA_DeleteOnClose)
        fixed = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        rightCenter = (Qt.AlignRight | Qt.AlignVCenter)

        # all the input boxes
        self.inputGrid = QGridLayout()
        self.inputGrid.setSpacing(5)
        h_spc = self.inputGrid.horizontalSpacing()
        v_spc = self.inputGrid.verticalSpacing()

        # RGB
        self.redInput = QSpinBox()
        self.grnInput = QSpinBox()
        self.bluInput = QSpinBox()
        self.rgbInputs = [self.redInput, self.grnInput, self.bluInput]

        self.redLabel = QLabel('&R:')
        self.redLabel.setToolTip('Red')
        self.grnLabel = QLabel('&G:')
        self.grnLabel.setToolTip('Green')
        self.bluLabel = QLabel('&B:')
        self.bluLabel.setToolTip('Blue')
        self.rgbLabels = [self.redLabel, self.grnLabel, self.bluLabel]

        self.redLabel.setBuddy(self.redInput)
        self.grnLabel.setBuddy(self.grnInput)
        self.bluLabel.setBuddy(self.bluInput)

        # HSV
        self.hueInput = QSpinBox()
        self.satInput = QSpinBox()
        self.valInput = QSpinBox()
        self.hsvInputs = [self.hueInput, self.satInput, self.valInput]
        self.hueInput.setWrapping(True)

        self.hueLabel = QLabel('&H:')
        self.hueLabel.setToolTip('Hue')
        self.satLabel = QLabel('&S:')
        self.satLabel.setToolTip('Saturation')
        self.valLabel = QLabel('&V:')
        self.valLabel.setToolTip('Value')
        self.hsvLabels = [self.hueLabel, self.satLabel, self.valLabel]

        self.hueLabel.setBuddy(self.hueInput)
        self.satLabel.setBuddy(self.satInput)
        self.valLabel.setBuddy(self.valInput)

        # CMYK
        self.cInput = QSpinBox()
        self.mInput = QSpinBox()
        self.yInput = QSpinBox()
        self.kInput = QSpinBox()
        self.cmykInputs = [self.cInput, self.mInput, self.yInput, self.kInput]

        self.cLabel = QLabel('&C:')
        self.cLabel.setToolTip('Cyan')
        self.mLabel = QLabel('&M:')
        self.mLabel.setToolTip('Magenta')
        self.yLabel = QLabel('&Y:')
        self.yLabel.setToolTip('Yellow')
        self.kLabel = QLabel('&K:')
        self.kLabel.setToolTip('Black')
        self.cmykLabels = [self.cLabel, self.mLabel, self.yLabel, self.kLabel]

        self.cLabel.setBuddy(self.cInput)
        self.mLabel.setBuddy(self.mInput)
        self.yLabel.setBuddy(self.yInput)
        self.kLabel.setBuddy(self.kInput)

        for i in self.rgbInputs + self.hsvInputs + self.cmykInputs:
            i.setRange(0, 255)
            i.setFixedSize(35, 22)
            i.setAlignment(Qt.AlignCenter)
            i.setButtonSymbols(QAbstractSpinBox.NoButtons)
        self.hueInput.setRange(0, 359)

        # HTML
        self.htmlInput = QLineEdit()
        self.htmlInput.setFixedSize(35 + 22 + h_spc, 22)  # spans 2 cols
        self.htmlInput.setPlaceholderText('html')
        self.htmlInput.setAlignment(Qt.AlignCenter)
        regex = QRegExp('[0-9A-Fa-f]{1,6}')
        valid = QRegExpValidator(regex)
        self.htmlInput.setValidator(valid)

        self.htmlLabel = QLabel('&#')
        self.htmlLabel.setToolTip('Web color')
        self.htmlLabel.setBuddy(self.htmlInput)

        self.inputLabels = (self.rgbLabels + self.hsvLabels + self.cmykLabels +
                            [
                                self.htmlLabel,
                            ])
        for i in self.inputLabels:
            i.setFixedSize(22, 22)
            i.setAlignment(rightCenter)
            #i.setFrameShape(QFrame.Box)

        self.inputs = self.rgbInputs + self.hsvInputs + self.cmykInputs
        for i in self.inputs:
            i.valueChanged.connect(self._colorEdited)
        self.htmlInput.editingFinished.connect(self._colorEdited)

        # picker button
        self.pickButton = QPushButton('&Pick')
        self.pickButton.setToolTip('Pick a color from the screen')
        self.pickButton.setFixedSize(35, 22)
        self.pickButton.clicked.connect(self.pickColor)

        # color display
        self.colorDisplay = QFrame()
        self.colorDisplay.setFixedSize(55, 4 * 22 + 3 * v_spc)  # spans 4 rows
        self.colorDisplay.setFrameShape(QFrame.Panel)
        self.colorDisplay.setFrameShadow(QFrame.Sunken)
        self.colorDisplay.setAutoFillBackground(True)

        # show button / random button
        self.showButton = QPushButton('Sho&w')
        self.showButton.setToolTip('Show named colors on color wheel')
        self.showButton.setFixedSize(35, 22)
        self.showButton.setCheckable(True)
        self.showButton.clicked.connect(self.showColors)

        self.rndButton = QPushButton('R&and')
        self.rndButton.setToolTip('Select a random color')
        self.rndButton.setFixedSize(35, 22)
        self.rndButton.clicked.connect(self.randomColor)

        # color wheel
        self.colorWheel = wheel()
        self.colorWheel.setFixedSize(256, 256)  #265, 265)
        self.colorWheel.currentColorChanged.connect(self.setColor)

        # named colors combo box
        self.colorNamesCB = QComboBox()
        self.colorNamesCB.setFixedSize(70 + 66 + 4 * h_spc, 22)  # spans 5 cols
        #self.colorNamesCB.addItem('- Color Names -')

        self.cNameLabel = QLabel('&Named:')
        self.cNameLabel.setBuddy(self.colorNamesCB)
        self.cNameLabel.setAlignment(rightCenter)
        #self.cNameLabel.setFrameShape(QFrame.Box)
        self.cNameLabel.setFixedSize(55, 22)

        lst = [i for i in QColor.colorNames() if str(i) != 'transparent']
        lst = [(i, QColor(i)) for i in lst]
        lst.append(('Cosmic latte', '#fff8e7'))
        lst.append(('rebeccapurple', '#663399'))
        self.addNamedColors(lst)
        self.colorNamesCB.currentIndexChanged.connect(self._colorEdited)

        self.inputs += [self.htmlInput, self.colorWheel, self.colorNamesCB]

        # ok/cancel buttons
        self.dialogButtons = QDialogButtonBox(QDialogButtonBox.Ok
                                              | QDialogButtonBox.Cancel)
        self.dialogButtons.accepted.connect(self.closeValid)
        self.dialogButtons.rejected.connect(self.closeInvalid)
        self.dialogButtons.setCenterButtons(True)
        # pass QColorDialog.NoButtons, False to setOption to remove

        # assemble grid!
        #    0  1   2  3   4  5   6
        #
        # color wheeeeeeeeeeeeellll   0
        # disp r: rrr h: hhh c: ccc   1
        # disp g: ggg s: sss m: mmm   2
        # disp b: bbb v: vvv y: yyy   3
        # disp ## -html- pic k: kkk   4
        # name coooommmboooobox rnd   5

        #.addWidget(widget, row, col, rspan, cspan)
        self.inputGrid.addWidget(self.colorWheel, 0, 0, 1, 7)
        self.inputGrid.addWidget(self.colorDisplay, 1, 0, 4, 1)

        for i, lab in enumerate(self.rgbLabels, 1):
            self.inputGrid.addWidget(lab, i, 1, 1, 1)
        self.inputGrid.addWidget(self.htmlLabel, 4, 1, 1, 1)

        for i, wid in enumerate(self.rgbInputs, 1):
            self.inputGrid.addWidget(wid, i, 2)
        self.inputGrid.addWidget(self.htmlInput, 4, 2, 1, 2)

        for i, lab in enumerate(self.hsvLabels, 1):
            self.inputGrid.addWidget(lab, i, 3, 1, 1)

        for i, wid in enumerate(self.hsvInputs, 1):
            self.inputGrid.addWidget(wid, i, 4, 1, 1)
        self.inputGrid.addWidget(self.pickButton, 4, 4, 1, 1)

        for i, lab in enumerate(self.cmykLabels, 1):
            self.inputGrid.addWidget(lab, i, 5, 1, 1)

        for i, wid in enumerate(self.cmykInputs, 1):
            self.inputGrid.addWidget(wid, i, 6, 1, 1)

        self.inputGrid.addWidget(self.colorNamesCB, 5, 1, 1, 5)
        self.inputGrid.addWidget(self.cNameLabel, 5, 0, 1, 1)
        self.inputGrid.addWidget(self.showButton, 5, 6, 1, 1)
        self.inputGrid.addWidget(self.rndButton, 5, 6, 1, 1)
        self.inputGrid.addWidget(self.dialogButtons, 6, 0, 1, 7)

        self.setWindowTitle('Select color')
        ico = self.style().standardIcon(QStyle.SP_DialogResetButton)
        self.setWindowIcon(ico)
        self.setLayout(self.inputGrid)
        self.setFixedSize(self.sizeHint())
        self.useRandom()  #False)
Ejemplo n.º 5
0
class QGameOfLife(QWidget):

    Games = {
        "Game of Life": (GameOfLife, {'fill_rate': 0.50}),
        "Bacteria": (GrayScottDiffusion, {'coeffs': (0.16, 0.08, 0.035, 0.065)}),
        "Coral": (GrayScottDiffusion, {'coeffs': (0.16, 0.08, 0.062, 0.062)}),
        "Fingerprint": (GrayScottDiffusion, {'coeffs': (0.19, 0.05, 0.060, 0.062)}),
        "Spirals": (GrayScottDiffusion, {'coeffs': (0.10, 0.10, 0.018, 0.050)}),
        "Unstable": (GrayScottDiffusion, {'coeffs': (0.16, 0.08, 0.020, 0.055)}),
        "Worms": (GrayScottDiffusion, {'coeffs': (0.16, 0.08, 0.050, 0.065)}),
        "Zebrafish": (GrayScottDiffusion, {'coeffs': (0.16, 0.08, 0.035, 0.060)}),
    }

    def __init__(self, size=(400, 400)):
        super(QGameOfLife, self).__init__()
        self.size = size
        self.game = None
        self.initUI()
        self.show()

    def initUI(self):
        self.setWindowTitle(self.tr("Game of Life"))
        self.setLayout(QVBoxLayout())
        self.layout().setSpacing(0)
        self.layout().setContentsMargins(0, 0, 0, 0)

        self.comboBox = QComboBox()
        self.comboBox.addItems([*QGameOfLife.Games.keys()])
        self.comboBox.currentTextChanged.connect(self.select)
        self.layout().addWidget(self.comboBox)

        self.scene = QGraphicsScene()
        self.view = QGraphicsView(self.scene)
        self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred))
        self.view.setFrameShape(QFrame.NoFrame)
        self.layout().addWidget(self.view)

        self.item = None
        self.timer = QTimer()
        self.timer.setInterval(10)
        self.timer.timeout.connect(self.tick)
        initialGame = random.choice([*QGameOfLife.Games.keys()])
        self.select(initialGame)
        self.view.fitInView(self.item, Qt.KeepAspectRatioByExpanding)
        self.comboBox.setCurrentText(initialGame)

    def select(self, name: str):
        self.timer.stop()
        Game, args = QGameOfLife.Games[name]
        self.game = Game(self.size, **args)
        self.tick()
        self.timer.start()

    def tick(self):
        self.game.tick()
        bitmap = self.game.visualize()
        image = QImage(bitmap.data, bitmap.shape[1], bitmap.shape[0], QImage.Format_Grayscale8)
        self.scene.removeItem(self.item)
        pixmap = QPixmap.fromImage(image)
        self.item = self.scene.addPixmap(pixmap)

    def resizeEvent(self, event: QResizeEvent):
        self.view.fitInView(self.item, Qt.KeepAspectRatioByExpanding)

    def sizeHint(self) -> QSize:
        return QSize(self.size[0], self.size[1])