예제 #1
0
    def show_error(self, scroll_view: QWidget, txt: str):
        if self.error_widget is not None:
            self.error_widget.hide()
            del self.error_widget

        geometry = scroll_view.geometry()

        self.error_widget = QTextEdit(parent=scroll_view)
        self.error_widget.setGeometry(25,
                                      geometry.height() - 85,
                                      geometry.width() - 50,
                                      60)  #25, 400, 732, 62)
        self.error_widget.setStyleSheet(
            'background-color: rgb(240, 60, 60); border-radius: 10px;')

        self.error_widget.setHtml(txt)
        self.error_widget.setReadOnly(True)

        self.error_widget.show()
예제 #2
0
class SandyScreen(QWidget):
    def __init__(self, root):
        QWidget.__init__(self)
        self.root = root

        # Setting state vars
        self.app_running = True
        self.ctrl_down = False
        self.in_fullscreen = False
        self.in_menu = False
        self.on_pause = True

        # Setting animation vars
        self.timer_delay = 10
        self.phase = 1
        self.delta_per_tick = 1 / 30
        self.xpmsz = None
        self.geo = [0, 0, 0, 0]

        # Creating timer and sandpile
        self.timer = QTimer(self)
        self.seed = None
        self.piletype = None
        self.sandpile = None
        self.reroll_pile()

        # Generating pause icon
        self.pause_icon = Image.new('RGBA', size=(60, 60))
        for i in range(60):
            for j in range(60):
                self.pause_icon.putpixel(
                    (j, i), (255, 255, 255, 0 if 20 < j < 40 else 100))

        # Initialising UI and running
        self.init_ui()
        self.show()

    def init_ui(self):
        self.setMinimumSize(600, 400)
        self.setWindowTitle('Sandy Screen')

        # Menu widget
        self.menu = SandyMenu(self)

        # Sandbox container widget and its background and canvas label stack
        self.sandbox = QWidget(self)
        self.sandbox.setGeometry(0, 0, 600, 400)
        self.sandbox_bg = QLabel(self.sandbox)
        self.sandbox_bg.setGeometry(0, 0, 600, 400)
        self.sandbox_bg.setPixmap(
            QPixmap(['1 1 1 1', '1 c #000000',
                     '1']).scaled(self.sandbox_bg.size()))
        self.canvases = [QLabel(self.sandbox), QLabel(self.sandbox)]
        for c in self.canvases:
            c.setAlignment(Qt.AlignCenter)
            c.setGeometry(0, 0, 600, 400)
        self.canvases[1].setPixmap(QPixmap(generate_xpm(self.sandpile)[0]))
        self.sandpile.topple_step()
        self.canvases[0].setPixmap(QPixmap(generate_xpm(self.sandpile)[0]))

        # Opacity effect on the upper frame label
        self.opeff = QGraphicsOpacityEffect(self.canvases[-1])
        self.opeff.setOpacity(1)
        self.canvases[-1].setGraphicsEffect(self.opeff)

        # Main stack layout
        self.layout = QStackedLayout(self)
        self.layout.addWidget(self.sandbox)
        self.layout.addWidget(self.menu)

        # Overlay pause icon label
        self.pause_label = QLabel(self)
        self.pause_label.setAlignment(Qt.AlignCenter)
        self.pause_label.setPixmap(QPixmap(ImageQt.ImageQt(self.pause_icon)))

    def restart_pile(self):
        del self.sandpile
        self.sandpile = self.piletype(copy.deepcopy(self.seed),
                                      frozen=True,
                                      timed=False,
                                      vocal=False)
        print('restart called')

    def reroll_pile(self, piletype=None, seed=None):
        if seed:
            self.seed = seed
        else:
            v = random.randint(8, 33)
            self.seed = [[v for j in range(_X)] for i in range(_Y)]
        if piletype:
            self.piletype = piletype
        else:
            v = random.randint(0, 3)
            self.piletype = [t4f, t6hf, t6vf, t8f][v]
        self.sandpile = self.piletype(copy.deepcopy(self.seed),
                                      frozen=True,
                                      timed=False,
                                      vocal=False)

    def run(self):
        self.root.exec_()

    def closeEvent(self, event):
        self.timer.stop()
        self.app_running = False

    def keyPressEvent(self, event):
        k = event.key()
        if k == 16777236:
            self.update_sandbox(1)  #
        if k == _CTRL:
            self.ctrl_down = True
        if self.ctrl_down:
            if k == _M:
                self.toggle_menu()  # Menu toggled on Ctrl+M
            elif k == _R:
                self.reroll_pile()
        else:
            if k == _F11:
                self.toggle_fullscreen()
            elif k == _SPACE and not self.in_menu:
                self.toggle_pause()

    def keyReleaseEvent(self, event):
        if event.key() == _CTRL:
            self.ctrl_down = False

    def resizeEvent(self, event):
        self.pause_label.setGeometry(self.rect())
        sbg = self.sandbox.geometry()
        sbs = self.sandbox.size()
        self.sandbox_bg.setGeometry(sbg)
        self.sandbox_bg.setPixmap(self.sandbox_bg.pixmap().scaled(
            self.sandbox_bg.size()))
        for c in self.canvases:
            c.setGeometry(sbg)
            c.setPixmap(c.pixmap().scaled(sbs, Qt.KeepAspectRatio))
        ### Fix this.

    def toggle_fullscreen(self):
        self.in_fullscreen = not self.in_fullscreen
        self.showFullScreen() if self.in_fullscreen else self.showNormal()

    def toggle_menu(self):
        self.in_menu = not self.in_menu
        if self.in_menu:
            self.layout.setCurrentIndex(1)
            self.pause_label.setVisible(False)
            self.on_pause = True
            self.root.restoreOverrideCursor()
        else:
            self.layout.setCurrentIndex(0)
            if self.on_pause:
                self.pause_label.raise_()
                self.pause_label.setVisible(True)
            else:
                self.root.setOverrideCursor(Qt.BlankCursor)
        self.resizeEvent(None)

    def toggle_pause(self):
        self.on_pause = not self.on_pause
        if self.on_pause:
            self.timer.stop()
            self.pause_label.raise_()
            self.pause_label.setVisible(True)
            self.root.restoreOverrideCursor()
        else:
            self.pause_label.setVisible(False)
            self.timer.singleShot(self.timer_delay,
                                  lambda: self.update_sandbox(0))
            self.root.setOverrideCursor(Qt.BlankCursor)

    def update_sandbox(self, mode):
        if not self.in_menu:
            if mode == self.on_pause:
                self.phase -= self.delta_per_tick
                if self.phase <= 0:
                    self.canvases[-1].setPixmap(self.canvases[0].pixmap())
                    self.phase = 1
                    self.opeff.setOpacity(self.phase)
                    if not self.sandpile.topple_step() and not self.on_pause:
                        self.toggle_pause()
                    xpm, sz = generate_xpm(self.sandpile)
                    self.canvases[0].setPixmap(
                        QPixmap(xpm).scaled(self.sandbox.size(),
                                            Qt.KeepAspectRatio))
                else:
                    self.opeff.setOpacity(
                        math.pow(math.sin(math.pi * self.phase / 2), 2))
                if mode == 0 and self.app_running:
                    self.timer.singleShot(self.timer_delay,
                                          lambda: self.update_sandbox(0))
예제 #3
0
class Grabber(QWidget):
    dirty = True

    def __init__(self, x, y, w, h, inputs_queue, update_position_queue,
                 update_position_lock):
        QWidget.__init__(self)
        self.setWindowTitle('ReLuu FaceReader')
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        self.inputs_queue = inputs_queue
        self.update_position_queue = update_position_queue
        self.update_position_lock = update_position_lock
        self.setGeometry(self.x, self.y, self.w, self.h)
        self.acceptDrops()
        # Window stays on top, and the other 2 combine to remove the min/close/expand buttons
        self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.CustomizeWindowHint
                            | Qt.WindowTitleHint)

        layout = QVBoxLayout()
        self.setLayout(layout)
        # limit widget AND layout margins
        layout.setContentsMargins(0, 0, 0, 0)
        self.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)

        # create a "placeholder" widget for the screen grab geometry
        self.grabWidget = QWidget()
        self.grabWidget.setSizePolicy(QSizePolicy.Expanding,
                                      QSizePolicy.Expanding)
        layout.addWidget(self.grabWidget)
        self.show()

    def updateMask(self):
        # get the *whole* window geometry, including its titlebar and borders
        frameRect = self.frameGeometry()

        # get the grabWidget geometry and remap it to global coordinates
        grabGeometry = self.grabWidget.geometry()
        grabGeometry.moveTopLeft(self.grabWidget.mapToGlobal(QPoint(0, 0)))

        self.update_position_lock.acquire()
        #Sends info to the input queue
        x1 = grabGeometry.getRect()[0]
        y1 = grabGeometry.getRect()[1]
        width = grabGeometry.getRect()[2]
        height = grabGeometry.getRect()[3]
        message = f"UPDATE {x1} {y1} {width} {height}"
        # if not self.update_position_queue.empty():
        #     _ = self.update_position_queue.get()
        #     self.update_position_queue.put(message)
        # else:
        #     self.update_position_queue.put(message)

        self.inputs_queue.put(message)

        self.update_position_lock.release()

        # get the actual margins between the grabWidget and the window margins
        left = frameRect.left() - grabGeometry.left()
        top = frameRect.top() - grabGeometry.top()
        right = frameRect.right() - grabGeometry.right()
        bottom = frameRect.bottom() - grabGeometry.bottom()

        # reset the geometries to get "0-point" rectangles for the mask
        frameRect.moveTopLeft(QPoint(0, 0))
        grabGeometry.moveTopLeft(QPoint(0, 0))

        # create the base mask region, adjusted to the margins between the
        # grabWidget and the window as computed above
        region = QRegion(frameRect.adjusted(left, top, right, bottom))
        # "subtract" the grabWidget rectangle to get a mask that only contains
        # the window titlebar, margins and panel
        region -= QRegion(grabGeometry)
        self.setMask(region)

        # update the grab size according to grabWidget geometry
        # self.widthLabel.setText(str(self.grabWidget.width()))
        # self.heightLabel.setText(str(self.grabWidget.height()))

    def resizeEvent(self, event):
        super(Grabber, self).resizeEvent(event)
        # the first resizeEvent is called *before* any first-time showEvent and
        # paintEvent, there's no need to update the mask until then; see below
        if not self.dirty:
            # print("rezise event")
            self.updateMask()

    def moveEvent(self, event):
        super(Grabber, self).moveEvent(event)
        if not self.dirty:
            # print("Moving it")
            self.updateMask()

    def paintEvent(self, event):
        super(Grabber, self).paintEvent(event)
        # on Linux the frameGeometry is actually updated "sometime" after show()
        # is called; on Windows and MacOS it *should* happen as soon as the first
        # non-spontaneous showEvent is called (programmatically called: showEvent
        # is also called whenever a window is restored after it has been
        # minimized); we can assume that all that has already happened as soon as
        # the first paintEvent is called; before then the window is flagged as
        # "dirty", meaning that there's no need to update its mask yet.
        # Once paintEvent has been called the first time, the geometries should
        # have been already updated, we can mark the geometries "clean" and then
        # actually apply the mask.
        if self.dirty:
            self.updateMask()
            self.dirty = False

    def close_window(self):
        self.close()
예제 #4
0
class MediaText(Media):

    def __init__(self, media, parent_widget):
        super(MediaText, self).__init__(media, parent_widget)
        self.widget = QWidget(parent_widget)
        self.process = QProcess(self.widget)
        self.process.setObjectName('%s-process' % self.objectName())
        self.std_out = []
        self.errors = []
        self.stopping = False
        self.mute = False
        self.widget.setGeometry(media['geometry'])
        self.connect(self.process, SIGNAL('error()'), self.process_error)
        self.connect(self.process, SIGNAL('finished()'), self.process_finished)
        self.connect(self.process, SIGNAL('started()'), self.process_started)
        self.set_default_widget_prop()
        self.stop_timer = QTimer(self)
        self.stop_timer.setSingleShot(True)
        self.stop_timer.setInterval(1000)
        self.stop_timer.timeout.connect(self.process_timeout)
        self.rect = self.widget.geometry()

    @Slot()
    def process_timeout(self):
        os.kill(self.process.pid(), signal.SIGTERM)
        self.stopping = False
        if  not self.is_started():
            self.started_signal.emit()
        super(MediaText, self).stop()

    @Slot(object)
    def process_error(self, err):
        print('---- process error ----')
        self.errors.append(err)
        self.stop()

    @Slot()
    def process_finished(self):
        self.stop()

    @Slot()
    def process_started(self):
        self.stop_timer.stop()
        if  float(self.duration) > 0:
            self.play_timer.setInterval(int(float(self.duration) * 1000))
            self.play_timer.start()
        self.started_signal.emit()
        pass

    @Slot()
    def play(self):
        self.finished = 0
        self.widget.show()
        self.widget.raise_()
        #---- kong ----
        path = f'file:///home/pi/rdtone/urd/content/{self.layout_id}_{self.region_id}_{self.id}.html'
        
        print(path)
        
        l = str(self.rect.left())
        t = str(self.rect.top())
        w = str(self.rect.width())
        h = str(self.rect.height())
        s = f'--window-size={w},{h}'
        p = f'--window-position={l},{t}'
        args = [
            '--kiosk', s, p, path
            #l, t, w, h, path
        ]
        self.process.start('chromium-browser', args)
        #self.process.start('./xWeb', args)
        self.stop_timer.start()
        #----

    @Slot()
    def stop(self, delete_widget=False):
        #---- kong ----
        if  not self.widget:
            return False
        if  self.stopping or self.is_finished():
            return False
        self.stop_timer.start()
        self.stopping = True
        if  self.process.state() == QProcess.ProcessState.Running:
            #---- kill process ----
            os.system('pkill chromium')
            #os.system('pkill xWeb')
            #----
            self.process.waitForFinished()
            self.process.close()
        super(MediaText, self).stop(delete_widget)
        self.stopping = False
        self.stop_timer.stop()
        return True
예제 #5
0
class WebMediaView(MediaView):
    def __init__(self, media, parent):
        super(WebMediaView, self).__init__(media, parent)
        self.widget = QWidget(parent)
        self.process = QProcess(self.widget)
        self.process.setObjectName('%s-process' % self.objectName())
        self.std_out = []
        self.errors = []
        self.stopping = False
        self.mute = False
        self.widget.setGeometry(media['geometry'])
        self.connect(self.process, SIGNAL('error()'), self.process_error)
        self.connect(self.process, SIGNAL('finished()'), self.process_finished)
        self.connect(self.process, SIGNAL('started()'), self.process_started)
        self.set_default_widget_prop()
        self.stop_timer = QTimer(self)
        self.stop_timer.setSingleShot(True)
        self.stop_timer.setInterval(1000)
        self.stop_timer.timeout.connect(self.process_timeout)
        self.rect = self.widget.geometry()

    @Slot()
    def process_timeout(self):
        os.kill(self.process.pid(), signal.SIGTERM)
        self.stopping = False
        if not self.is_started():
            self.started_signal.emit()
        super(WebMediaView, self).stop()

    @Slot(object)
    def process_error(self, err):
        print('---- process error ----')
        self.errors.append(err)
        self.stop()

    @Slot()
    def process_finished(self):
        self.stop()

    @Slot()
    def process_started(self):
        self.stop_timer.stop()
        if float(self.duration) > 0:
            self.play_timer.setInterval(int(float(self.duration) * 1000))
            self.play_timer.start()
        self.started_signal.emit()
        pass

    @Slot()
    def play(self):
        self.finished = 0
        self.widget.show()
        self.widget.raise_()
        #---- kong ----
        url = self.options['uri']
        args = [
            str(self.rect.left()),
            str(self.rect.top()),
            str(self.rect.width()),
            str(self.rect.height()),
            QUrl.fromPercentEncoding(QByteArray(url.encode('utf-8')))
        ]
        #self.process.start('dist/web.exe', args) # for windows
        #self.process.start('./dist/web', args) # for RPi
        self.stop_timer.start()
        #----

    @Slot()
    def stop(self, delete_widget=False):
        #---- kong ----
        if not self.widget:
            return False
        if self.stopping or self.is_finished():
            return False
        self.stop_timer.start()
        self.stopping = True
        if self.process.state() == QProcess.ProcessState.Running:
            #---- kill process ----
            self.process.terminate()  # for windows
            self.process.kill()  # for linux
            #os.system('pkill web') # for RPi
            #----
            self.process.waitForFinished()
            self.process.close()
        super(WebMediaView, self).stop(delete_widget)
        self.stopping = False
        self.stop_timer.stop()
        return True
예제 #6
0
class ImageBox(QWidget):
    dirty = True

    def __init__(self, start_box_x1, start_box_y1, start_box_x2, start_box_y2,
                 inputs_queue, update_position_lock):
        super(ImageBox, self).__init__()
        self.setWindowTitle('ReLuu')
        cur_dir = os.getcwd()
        # os.chdir(sys._MEIPASS)
        icon = QIcon("auxiliary_files\\logo_transparent_background.png")
        self.setWindowIcon(icon)
        os.chdir(cur_dir)

        self.start_box_x1 = start_box_x1
        self.start_box_y1 = start_box_y1
        self.start_box_x2 = start_box_x2
        self.start_box_y2 = start_box_y2
        self.inputs_queue = inputs_queue
        self.update_position_lock = update_position_lock
        self.setGeometry(self.start_box_x1, self.start_box_y1,
                         self.start_box_x2, self.start_box_y2)
        self.acceptDrops()
        # Window stays on top, and the other 2 combine to remove the min/close/expand buttons
        self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.CustomizeWindowHint
                            | Qt.WindowTitleHint)

        layout = QVBoxLayout()
        self.setLayout(layout)
        # limit widget AND layout margins
        layout.setContentsMargins(0, 0, 0, 0)
        self.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)

        # create a "placeholder" widget for the screen grab geometry
        self.grabWidget = QWidget()
        self.grabWidget.setSizePolicy(QSizePolicy.Expanding,
                                      QSizePolicy.Expanding)
        layout.addWidget(self.grabWidget)
        self.show()

    def updateMask(self):
        # get the *whole* window geometry, including its titlebar and borders
        frameRect = self.frameGeometry()

        # get the grabWidget geometry and remap it to global coordinates
        grabGeometry = self.grabWidget.geometry()
        grabGeometry.moveTopLeft(self.grabWidget.mapToGlobal(QPoint(0, 0)))

        self.update_position_lock.acquire()
        #Sends info to the input queue
        x1 = grabGeometry.getRect()[0]
        y1 = grabGeometry.getRect()[1]
        width = grabGeometry.getRect()[2]
        height = grabGeometry.getRect()[3]
        message = f"UPDATE {x1} {y1} {width} {height}"

        self.inputs_queue.put(message)

        self.update_position_lock.release()

        # get the actual margins between the grabWidget and the window margins
        left = frameRect.left() - grabGeometry.left()
        top = frameRect.top() - grabGeometry.top()
        right = frameRect.right() - grabGeometry.right()
        bottom = frameRect.bottom() - grabGeometry.bottom()

        # reset the geometries to get "0-point" rectangles for the mask
        frameRect.moveTopLeft(QPoint(0, 0))
        grabGeometry.moveTopLeft(QPoint(0, 0))

        # create the base mask region, adjusted to the margins between the
        # grabWidget and the window as computed above
        region = QRegion(frameRect.adjusted(left, top, right, bottom))
        # "subtract" the grabWidget rectangle to get a mask that only contains
        # the window titlebar, margins and panel
        region -= QRegion(grabGeometry)
        self.setMask(region)

        # update the grab size according to grabWidget geometry
        # self.widthLabel.setText(str(self.grabWidget.width()))
        # self.heightLabel.setText(str(self.grabWidget.height()))

    def resizeEvent(self, event):
        super(ImageBox, self).resizeEvent(event)
        # the first resizeEvent is called *before* any first-time showEvent and
        # paintEvent, there's no need to update the mask until then; see below
        if not self.dirty:
            self.updateMask()

    def moveEvent(self, event):
        super(ImageBox, self).moveEvent(event)
        if not self.dirty:
            self.updateMask()

    def paintEvent(self, event):
        super(ImageBox, self).paintEvent(event)
        if self.dirty:
            self.updateMask()
            self.dirty = False

    def close_window(self):
        self.close()