예제 #1
0
class OrpheusLibrarySearch(QWidget):
    
    def __init__(self):
        super().__init__()
        self.initUI()
        self.populateList()
        
    def initUI(self):
        #palette = QPalette()
        #palette.setColor(QPalette.Background, QColor('#383C4A'))        
        #palette.setColor(QPalette.WindowText, QColor('#C1C1C1'))        
        #self.setPalette(palette)
        
        self.setMaximumSize(492, 653)
        self.setMinimumSize(492, 653)
        
        le = QLineEdit(self)
        le.textChanged[str].connect(self.onChanged)
        le.returnPressed.connect(self.onActivation)
        le.setClearButtonEnabled(True)
        le.setPlaceholderText('Start typing to search...')
        self.lw = QListWidget()
        self.visibleLw = QListWidget()
        #palette.setColor(QPalette.Base, QColor('#383C4A'))                        
        #self.visibleLw.setPalette(palette)        
        self.visibleLw.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.visibleLw.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)        
        self.visibleLw.itemActivated.connect(self.onActivation)
        self.scrollBar = QScrollBar()
        self.visibleLw.verticalScrollBar().valueChanged.connect(self.scrollBar.setValue)
        self.scrollBar.valueChanged.connect(self.visibleLw.verticalScrollBar().setValue)
        vbox = QVBoxLayout()
        vbox.setSpacing(3)
        #vbox.setContentsMargins(3, 3, 3, 3)
        vbox.setContentsMargins(0, 4, 0, 0)        
        vbox.addWidget(le)       
        hbox = QHBoxLayout()
        hbox.setSpacing(0)
        #hbox.setContentsMargins(0, 0, 0, 0)                
        hbox.addWidget(self.visibleLw)
        hbox.addWidget(self.scrollBar)
        vbox.addLayout(hbox)
        self.setLayout(vbox)
        
        self.setWindowTitle('Music Library')
        
        icon = QIcon.fromTheme('musique')
        self.setWindowIcon(icon)
        
    def populateList(self):
        self.client = MPDClient()
        self.client.connect('localhost', 6600)        
        self.playlistinfo = self.client.playlistinfo()
        self.client.disconnect()
                
        self.playlist = []
        
        #backgroundColor = QColor('#383C4A')
        #foregroundColor = QColor('#C1C1C1')
        
        for i in self.playlistinfo:
            row = ''
            if 'album' in i:
                row = row + i['album'] + ' - '
            if 'title' in i:
                if isinstance(i['title'], str):
                    row = row + i['title']
                else:
                    row = row + i['title'][0]
            if 'artist' in i:
                row = row + ' - ' + i['artist']
            self.playlist.append(row)
            #newRow = QListWidgetItem(row)
            #newRow.setBackground(backgroundColor)
            #newRow.setForeground(foregroundColor)
            #self.lw.addItem(newRow)
        self.visibleLw.addItems(self.playlist)
        self.visibleLw.setCurrentRow(0)
        
    def get_matches(self, pattern):
        self.visibleLw.clear()
        pattern = '.*' + pattern.replace(' ', '.*').lower()
        regexp = re.compile(pattern)
        for i in self.playlist:
            if regexp.match(i.lower()):
                self.visibleLw.addItem(i)                
                
    def formatScrollBar(self):            
        self.scrollBar.setMaximum(self.visibleLw.verticalScrollBar().maximum())                    
        self.scrollBar.setPageStep(self.visibleLw.verticalScrollBar().pageStep())
        
    def onChanged(self, text):
        self.get_matches(text)
        self.visibleLw.setCurrentRow(0)
        self.scrollBar.setMaximum(self.visibleLw.verticalScrollBar().maximum())        
        if self.visibleLw.verticalScrollBar().maximum() == 0:
            self.scrollBar.setVisible(False)
        else:
            self.scrollBar.setVisible(True)

    def onActivation(self):
        selected_song = self.visibleLw.currentItem().text()
        for i in range(0, len(self.playlist)):
            if selected_song == self.playlist[i]:
                self.client.connect('localhost', 6600)
                self.client.play(i)
                self.client.disconnect()       
        
    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Down:
            self.visibleLw.setFocus()
        elif e.key() == Qt.Key_Escape:
            self.close()
예제 #2
0
class PdfDrawWidget(QWidget):
    horizontalScrollbar = None
    verticalScrollbar = None

    pdfVis: Document = None
    pageNum: int = 0
    zoom: float = 1

    __controlIsPressed = False

    __pressStart: Tuple[float, float] = None

    def __init__(self, parent: QWidget = None, painter: QPainter = QPainter()):
        super().__init__(parent)
        self.painter = painter
        self.horizontalScrollbar = QScrollBar(Qt.Horizontal)
        self.verticalScrollbar = QScrollBar(Qt.Vertical)
        self.horizontalScrollbar.setVisible(False)
        self.verticalScrollbar.setVisible(False)

        self.horizontalScrollbar.valueChanged.connect(lambda: self.update())
        self.verticalScrollbar.valueChanged.connect(lambda: self.update())
        self.setMouseTracking(True)

    def paintEvent(self, event: QPaintEvent):
        """All Drawing Actions are activated here"""
        self.__drawPDF(event)

    __viewchanged = True
    __zoomed = True
    __pdfImages: List[Tuple[int, QImage]] = [
    ]  # List of Tuples where first index is the hightoffset
    __pageoffsets: List[int] = []

    def __drawPDF(self, event: QPaintEvent):
        """Draws the Pdf centered onto the self Object as long as the self.pdfVis variable isn't None.
           self.verticalScrollbar &  self.horizontalScrollbar will be manipulated in range and visibility"""
        if self.pdfVis is not None:

            if self.__viewchanged:
                if self.__zoomed:
                    hightCount = 0
                    self.__pageoffsets = [0]
                    for page in self.pdfVis.pages():
                        hightCount += page.rect.height * self.zoom
                        self.__pageoffsets.append(hightCount)
                    hightCount -= self.height()
                    if self.height() < hightCount:
                        self.verticalScrollbar.setRange(0, hightCount)
                        self.verticalScrollbar.setVisible(True)
                    else:
                        self.verticalScrollbar.setVisible(False)
                        self.verticalScrollbar.setRange(0, 0)

            mat = fitz.Matrix(self.zoom, self.zoom)

            self.__pdfImages = []
            lowestVisablePage = next(
                i for i in range(len(self.__pageoffsets) - 1)
                if self.__pageoffsets[i + 1] >= self.verticalScrollbar.value())
            try:
                highestVisablePage = next(
                    i for i in range(len(self.__pageoffsets) - 1)
                    if self.__pageoffsets[i + 1] >=
                    self.verticalScrollbar.value() + self.height()) + 1
            except StopIteration:
                highestVisablePage = self.pdfVis.pageCount

            for falseI, page in enumerate(
                    self.pdfVis.pages(lowestVisablePage, highestVisablePage)):
                i = falseI + lowestVisablePage
                clipx0 = (page.rect.width * self.zoom / 2 - self.width() / 2 + self.horizontalScrollbar.value()) \
                    if (
                               page.rect.width * self.zoom / 2 - self.width() / 2 + self.horizontalScrollbar.value()) > 0 else 0
                clipy0 = (self.verticalScrollbar.value() - self.__pageoffsets[i]) / self.zoom \
                    if self.verticalScrollbar.value() >= self.__pageoffsets[i] else 0
                # clipx1 =
                # clipy1 =
                print(clipy0, clipx0)
                # print(self.verticalScrollbar.value())
                pix: Pixmap = page.getPixmap(mat)  # , clip=Rect(0,0,110,110))
                fmt = QImage.Format_RGBA8888 if pix.alpha else QImage.Format_RGB888
                self.__pdfImages.append((self.__pageoffsets[i],
                                         QImage(pix.samples, pix.width,
                                                pix.height, pix.stride, fmt)))

            if self.__pdfImages[0][1].width() > self.width():
                self.horizontalScrollbar.setRange(
                    self.width() - self.__pdfImages[0][1].width(),
                    self.__pdfImages[0][1].width() - self.width())
                self.horizontalScrollbar.setVisible(True)
            else:
                self.horizontalScrollbar.setVisible(False)
                self.horizontalScrollbar.setRange(0, 0)

                self.__viewchanged = False

            self.painter.begin(self)
            for i, (y, img) in enumerate(self.__pdfImages):
                self.painter.drawImage(
                    self.painter.viewport().width() / 2 - img.width() / 2 -
                    self.horizontalScrollbar.value(),
                    y + 5 * i - self.verticalScrollbar.value(), img)
            self.painter.end()
        else:
            pass

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

    def wheelEvent(self, event: QWheelEvent):
        if self.__controlIsPressed:
            if self.zoom + 0.005 * event.angleDelta().y() > 0:
                self.zoom += 0.005 * event.angleDelta().y()
            else:
                self.zoom = 0.1
            self.__zoomed = True
        else:
            self.verticalScrollbar.setValue(self.verticalScrollbar.value() -
                                            event.angleDelta().y())
        self.__viewchanged = True
        self.update()

    def keyPressEvent(self, event: QKeyEvent):
        if event.key() == Qt.Key_Control:
            self.__controlIsPressed = True

    def keyReleaseEvent(self, event: QKeyEvent):
        if event.key() == Qt.Key_Control:
            self.__controlIsPressed = False

    def mousePressEvent(self, event: QMouseEvent):
        self.__pressStart = (event.x(), event.y())

    def mouseMoveEvent(self, event: QMouseEvent):
        if self.__pressStart is not None:
            pass
            # Todo Draw Rectangle around all Textboxes

    def loadDocument(self, path: str):
        self.pdfVis = fitz.Document(path)
        self.update()
예제 #3
0
class _s_CentralWidget(QWidget):

###############################################################################
# CentralWidget SIGNALS
###############################################################################

    """
    splitterCentralRotated()
    """
    splitterCentralRotated = pyqtSignal()

###############################################################################

    def __init__(self, parent=None):
        super(_s_CentralWidget, self).__init__(parent)
        self.parent = parent
        #This variables are used to save the splitter sizes before hide
        self._splitterMainSizes = None
        self._splitterAreaSizes = None
        self.lateralPanel = None

        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(0, 0, 0, 0)
        hbox.setSpacing(0)
        #Create Splitters to divide the UI in: MainPanel, Explorer, Misc
        self._splitterArea = QSplitter(Qt.Horizontal)
        self._splitterMain = QSplitter(Qt.Vertical)

        #Create scrollbar for follow mode
        self.scrollBar = QScrollBar(Qt.Vertical, self)
        self.scrollBar.setFixedWidth(20)
        self.scrollBar.setToolTip('Follow Mode: Scroll the Editors together')
        self.scrollBar.hide()
        self.scrollBar.valueChanged[int].connect(self.move_follow_scrolls)

        #Add to Main Layout
        hbox.addWidget(self.scrollBar)
        hbox.addWidget(self._splitterArea)

    def insert_central_container(self, container):
        self.mainContainer = container
        self._splitterMain.insertWidget(0, container)

    def insert_lateral_container(self, container):
        self.lateralPanel = LateralPanel(container)
        self._splitterArea.insertWidget(0, self.lateralPanel)

    def insert_bottom_container(self, container):
        self.misc = container
        self._splitterMain.insertWidget(1, container)

    def showEvent(self, event):
        #Show Event
        QWidget.showEvent(self, event)
        #Avoid recalculate the panel sizes if they are already loaded
        if self._splitterArea.count() == 2:
            return
        #Rearrange widgets on Window
        self._splitterArea.insertWidget(0, self._splitterMain)
        if not event.spontaneous():
            self.change_misc_visibility()
        if bin(settings.UI_LAYOUT)[-1] == '1':
            self.splitter_central_rotate()
        if bin(settings.UI_LAYOUT >> 1)[-1] == '1':
            self.splitter_misc_rotate()
        if bin(settings.UI_LAYOUT >> 2)[-1] == '1':
            self.splitter_central_orientation()
        qsettings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat)
        #Lists of sizes as list of QVariant- heightList = [QVariant, QVariant]
        heightList = list(qsettings.value("window/central/mainSize",
            [(self.height() / 3) * 2, self.height() / 3]))
        widthList = list(qsettings.value("window/central/areaSize",
            [(self.width() / 6) * 5, self.width() / 6]))
        self._splitterMainSizes = [int(heightList[0]), int(heightList[1])]
        self._splitterAreaSizes = [int(widthList[0]), int(widthList[1])]
        #Set the sizes to splitters
        #self._splitterMain.setSizes(self._splitterMainSizes)
        self._splitterMain.setSizes(self._splitterMainSizes)
        self._splitterArea.setSizes(self._splitterAreaSizes)
        self.misc.setVisible(
            qsettings.value("window/show_misc", False, type=bool))

    def change_misc_visibility(self, on_start=False):
        if self.misc.isVisible():
            self._splitterMainSizes = self._splitterMain.sizes()
            self.misc.hide()
            widget = self.mainContainer.get_actual_widget()
            if widget:
                widget.setFocus()
        else:
            self.misc.show()
            self.misc.gain_focus()

    def change_main_visibility(self):
        if self.mainContainer.isVisible():
            self.mainContainer.hide()
        else:
            self.mainContainer.show()

    def change_explorer_visibility(self, force_hide=False):
        if self.lateralPanel.isVisible() or force_hide:
            self._splitterAreaSizes = self._splitterArea.sizes()
            self.lateralPanel.hide()
        else:
            self.lateralPanel.show()

    def splitter_central_rotate(self):
        w1, w2 = self._splitterArea.widget(0), self._splitterArea.widget(1)
        self._splitterArea.insertWidget(0, w2)
        self._splitterArea.insertWidget(1, w1)
        self.splitterCentralRotated.emit()

    def splitter_central_orientation(self):
        if self._splitterArea.orientation() == Qt.Horizontal:
            self._splitterArea.setOrientation(Qt.Vertical)
        else:
            self._splitterArea.setOrientation(Qt.Horizontal)

    def splitter_misc_rotate(self):
        w1, w2 = self._splitterMain.widget(0), self._splitterMain.widget(1)
        self._splitterMain.insertWidget(0, w2)
        self._splitterMain.insertWidget(1, w1)

    def splitter_misc_orientation(self):
        if self._splitterMain.orientation() == Qt.Horizontal:
            self._splitterMain.setOrientation(Qt.Vertical)
        else:
            self._splitterMain.setOrientation(Qt.Horizontal)

    def get_area_sizes(self):
        if self.lateralPanel.isVisible():
            self._splitterAreaSizes = self._splitterArea.sizes()
        return self._splitterAreaSizes

    def get_main_sizes(self):
        if self.misc.isVisible():
            self._splitterMainSizes = self._splitterMain.sizes()
        return self._splitterMainSizes

    def enable_follow_mode_scrollbar(self, val):
        if val:
            editorWidget = self.mainContainer.get_actual_editor()
            maxScroll = editorWidget.verticalScrollBar().maximum()
            position = editorWidget.verticalScrollBar().value()
            self.scrollBar.setMaximum(maxScroll)
            self.scrollBar.setValue(position)
        self.scrollBar.setVisible(val)

    def move_follow_scrolls(self, val):
        widget = self.mainContainer._tabMain.currentWidget()
        diff = widget._sidebarWidget.highest_line - val
        s1 = self.mainContainer._tabMain.currentWidget().verticalScrollBar()
        s2 = self.mainContainer._tabSecondary.\
            currentWidget().verticalScrollBar()
        s1.setValue(val)
        s2.setValue(val + diff)
예제 #4
0
파일: TextArea.py 프로젝트: kamiyong/pyqt5
class TextArea(QWidget):
    """
    自定义文本展示区域(PS:不能键盘输入那种)
    功能:能自动拉长文本区域并且带有滑动条
    """

    def __init__(self, parent):
        super().__init__(parent)
        self.setContentsMargins(0, 0, 0, 0)
        # 滚动条的宽度
        # 对于水平方向的滚动条其实是高度
        self.scrollBarWidth = 15

        # 文本区
        self.textContainer = TextView(self)
        self.textContainer.setContentsMargins(5, 0, 0, 0)
        # 设置居顶部显示
        self.textContainer.setAlignment(Qt.AlignTop)
        # 设置文本区域根据文本进行自适应
        self.textContainer.adjustSize()
        self.textContainer.setCallback(self.sizeChange)

        # 垂直滚动条
        self.vBar = QScrollBar(Qt.Vertical, self)
        # self.vBar.sliderMoved.connect(self.dragV)
        self.vBar.valueChanged.connect(self.changeVertical)
        # 一开始隐藏
        self.vBar.setVisible(False)
        # 在水平方向上文字的总长度是否超过容器的宽度标志位
        # 只要出现一次超过,那么 self.overHorizontal就永远是True
        # 除非将超过容器宽度的文本都去除
        self.overHorizontal = False
        # 水平方向上滑块上一次的值
        self.hPreValue = 0

        # 水平滚动条
        self.hBar = QScrollBar(Qt.Horizontal, self)
        # self.hBar.sliderMoved.connect(self.dragH)
        self.hBar.valueChanged.connect(self.changeHorizontal)
        # 初始化的时候隐藏自身
        self.hBar.setVisible(False)

        # 在垂直方向上文字的总高度是否超过容器的高度标志位
        # 只要出现一次超过,那么 self.overVertical就永远是True
        # 除非将超过容器高度的文本都去除
        self.overVertical = False
        # 垂直方向上滑块上一次的值
        self.vPreValue = 0

    def setSize(self, width, height):
        """
        设置TextArea的宽度和高度
        :param width:  宽度
        :param height: 高度
        :return: no return
        """
        self.resize(width, height)
        self.setMaximumSize(width, height)
        self.setMinimumSize(width, height)

        # 设置垂直方向ScrollBar的宽度和高度
        # 垂直方向ScrollBar的高度等于TextArea的高度
        self.vBar.resize(self.scrollBarWidth, height - self.scrollBarWidth)
        # 移动到指定位置
        self.vBar.move(width - self.scrollBarWidth, 0)

        # 设置水平方向的ScrollBar的宽度和高度
        # 水平方向ScrollBar的高度为self.scrollBarWidth
        self.hBar.resize(width, self.scrollBarWidth)
        self.hBar.move(0, height - self.scrollBarWidth)

        # 设置文本区域的高度和宽度
        self.textContainer.resize(width, height)
        self.setStyleSheet("background-color: #088A68;")
        self.textContainer.setStyleSheet("border: 1px solid #FF0000; color: #FFFFFF;")

    def setMaximumSize(self, maxw: int, maxh: int) -> None:
        super().setMaximumSize(maxw, maxh)

    def setClassName(self, textAreaName=None, labelName=None, vBarName=None, hBarName=None):
        """
        设置ObjectName
        :param textAreaName: TextArea的ObjectName
        :param labelName: 文本区域的ObjectName
        :param vBarName: 垂直ScrollBar的ObjectName
        :param hBarName: 水平ScrollBar的ObjectName
        :return:
        """
        self.setObjectName(textAreaName)
        self.textContainer.setObjectName(labelName)
        self.hBar.setObjectName(hBarName)
        self.vBar.setObjectName(vBarName)

    def append(self, text):
        self.textContainer.adjustSize()
        self.textContainer.append(text)

        margin = self.contentsMargins()
        # 如果文本长度超过了容器的宽度, 将标准位置为True
        # 并且显示水平滑动条
        if self.textContainer.width() > (self.width() - margin.left() - margin.right()):
            self.overHorizontal = True
            self.hBar.setVisible(True)

        # 如果文本总高度度超过了容器的宽度, 将标准位置为True
        # 并且显示垂直滑动条
        if self.textContainer.height() > (self.height() - margin.top() - margin.bottom()):
            self.overVertical = True
            self.vBar.setVisible(True)

    def dragHortizontal(self, value):
        """
        滑块水平方向上的拖拽事件
        :argument value
        :return:
        """
        print("H: " + str(value))

    def dragVertical(self, value):
        """
        滑块垂直方向上的拖拽事件
        :argument value
        :return:
        """
        print("V: " + str(value))

    def changeHorizontal(self, v):
        """
        垂直滑块的值发生改变时
        :param v:
        :return:
        """
        if v == 0:
            # 由于下列的操作会产生浮点型数据,所以在计算坐标的时候总有偏差
            # 所以在 v = 0, 也就是滑动条回到最开始的地方,
            # self.textContainer对应方向上的坐标也归0,那样就不会出问题了
            self.textContainer.move(0, self.textContainer.y())
            # 将当前值作为下一次的preValue
            self.hPreValue = v
            return

        # print("change H: {}".format(v))
        textW = self.textContainer.width()
        # 最大值(从0开始计算)
        maximum = self.hBar.maximum() + 1
        # 计算每次改变值对应 self.textContainer在水平方向上需要移动的尺寸
        stepW = textW / maximum
        # 当前值与上一次的值得差
        change = v - self.hPreValue

        move = int(self.textContainer.x() - stepW * change)

        self.textContainer.move(move, self.textContainer.y())
        # 将当前值作为下一次的preValue
        self.hPreValue = v

    def changeVertical(self, v):
        """
        水平滑块的值发生改变时
        :param v:
        :return:
        """
        if v == 0:
            # 由于下列的操作会产生浮点型数据,所以在计算坐标的时候总有偏差
            # 所以在 v = 0, 也就是滑动条回到最开始的地方,
            # self.textContainer对应方向上的坐标也归0,那样就不会出问题了
            self.textContainer.move(self.textContainer.x(), 0)
            self.vPreValue = v
            return

        # print("change V: {}".format(v))
        textH = self.textContainer.width()
        # 最大值(从0开始计算)
        maximum = self.vBar.maximum() - self.vBar.minimum() + self.vBar.pageStep()
        # 计算每次改变值对应 self.textContainer在水平方向上需要移动的尺寸
        stepH = float(textH) / maximum
        # 当前值与上一次的值得差
        change = v - self.vPreValue
        move = int(self.textContainer.y() - stepH * change)

        self.textContainer.move(self.textContainer.x(),  move)
        # 将当前值作为下一次的preValue
        self.vPreValue = v

    def sizeChange(self, obj: QLabel):
        print("size change:{},{} ".format(obj.width(), obj.height()))