Ejemplo n.º 1
0
class ScrollWindow(QScrollArea):
    def __init__(self, *args, **kwargs):
        super(ScrollWindow, self).__init__(*args, **kwargs)
        # self.setAcceptDrops(True)  # 2
        self.resize(800, 600)
        self.setFrameShape(self.NoFrame)
        self.setWidgetResizable(True)
        self.setAlignment(Qt.AlignCenter)
        self._loadStart = False
        # 网格窗口
        self._widget = GridWidget(self)
        self._widget.loadStarted.connect(self.setLoadStarted)
        self.setWidget(self._widget)
        ####################################################
        # 连接竖着的滚动条滚动事件
        # self.verticalScrollBar().actionTriggered.connect(self.onActionTriggered)
        ####################################################
        # 进度条
        self.loadWidget = QSvgWidget(self,
                                     minimumHeight=180,
                                     minimumWidth=180,
                                     visible=False)
        self.loadWidget.load(Svg_icon_loading)

    def setLoadStarted(self, started):
        self._loadStart = started
        self.loadWidget.setVisible(started)

    def onActionTriggered(self, action):
        # 这里要判断action=QAbstractSlider.SliderMove,可以避免窗口大小改变的问题
        # 同时防止多次加载同一个url
        if action != QAbstractSlider.SliderMove or self._loadStart:
            return
        # 使用sliderPosition获取值可以同时满足鼠标滑动和拖动判断
        if self.verticalScrollBar().sliderPosition() == self.verticalScrollBar(
        ).maximum():
            # 可以下一页了
            self._widget.load()

    def resizeEvent(self, event):
        super(ScrollWindow, self).resizeEvent(event)
        self.loadWidget.setGeometry(
            int((self.width() - self.loadWidget.minimumWidth()) / 2),
            int((self.height() - self.loadWidget.minimumHeight()) / 2),
            self.loadWidget.minimumWidth(), self.loadWidget.minimumHeight())
Ejemplo n.º 2
0
class Window(QListWidget):
    Page = 0

    def __init__(self, *args, **kwargs):
        super(Window, self).__init__(*args, **kwargs)
        self.resize(800, 600)
        self.setFrameShape(self.NoFrame)  # 无边框
        self.setFlow(self.LeftToRight)  # 从左到右
        self.setWrapping(True)  # 这三个组合可以达到和FlowLayout一样的效果
        self.setResizeMode(self.Adjust)

        self._loadStart = False
        # 连接竖着的滚动条滚动事件
        self.verticalScrollBar().actionTriggered.connect(
            self.onActionTriggered)
        # 进度条
        self.loadWidget = QSvgWidget(self,
                                     minimumHeight=120,
                                     minimumWidth=120,
                                     visible=False)
        self.loadWidget.load(Svg_icon_loading)

        # 异步网络下载管理器
        self._manager = QNetworkAccessManager(self)
        self._manager.finished.connect(self.onFinished)

    def load(self):
        if self.Page == -1:
            return
        self._loadStart = True
        self.loadWidget.setVisible(True)
        # 延迟一秒后调用目的在于显示进度条
        QTimer.singleShot(1000, self._load)

    def _load(self):
        print("load url:", Url.format(self.Page * 30))
        url = QUrl(Url.format(self.Page * 30))
        self._manager.get(QNetworkRequest(url))

    def onFinished(self, reply):
        # 请求完成后会调用该函数
        req = reply.request()  # 获取请求
        iwidget = req.attribute(QNetworkRequest.User + 1, None)
        path = req.attribute(QNetworkRequest.User + 2, None)
        html = reply.readAll().data()
        reply.deleteLater()
        del reply
        if iwidget and path and html:
            # 这里是图片下载完毕
            open(path, "wb").write(html)
            iwidget.setCover(path)
            return
        # 解析网页
        self._parseHtml(html)
        self._loadStart = False
        self.loadWidget.setVisible(False)

    def _parseHtml(self, html):
        #         encoding = chardet.detect(html) or {}
        #         html = html.decode(encoding.get("encoding","utf-8"))
        html = HTML(html)
        # 查找所有的li list_item
        lis = html.xpath("//li[@class='list_item']")
        if not lis:
            self.Page = -1  # 后面没有页面了
            return
        self.Page += 1
        self._makeItem(lis)

    def _makeItem(self, lis):
        for li in lis:
            a = li.find("a")
            video_url = a.get("href")  # 视频播放地址
            img = a.find("img")
            cover_url = "http:" + img.get("r-lazyload")  # 封面图片
            figure_title = img.get("alt")  # 电影名
            figure_info = a.find("div/span")
            figure_info = "" if figure_info is None else figure_info.text  # 影片信息
            figure_score = "".join(li.xpath(".//em/text()"))  # 评分
            # 主演
            figure_desc = "<span style=\"font-size: 12px;\">主演:</span>" + \
                          "".join([Actor.format(**dict(fd.items()))
                                   for fd in li.xpath(".//div[@class='figure_desc']/a")])
            # 播放数
            figure_count = (
                li.xpath(".//div[@class='figure_count']/span/text()")
                or [""])[0]
            path = "cache/{0}.jpg".format(
                os.path.splitext(os.path.basename(video_url))[0])
            cover_path = "Data/pic_v.png"
            if os.path.isfile(path):
                cover_path = path
            iwidget = ItemWidget(cover_path, figure_info, figure_title,
                                 figure_score, figure_desc, figure_count,
                                 video_url, cover_url, path, self._manager,
                                 self)
            item = QListWidgetItem(self)
            item.setSizeHint(iwidget.sizeHint())
            self.setItemWidget(item, iwidget)

    def onActionTriggered(self, action):
        # 这里要判断action=QAbstractSlider.SliderMove,可以避免窗口大小改变的问题
        # 同时防止多次加载同一个url
        if action != QAbstractSlider.SliderMove or self._loadStart:
            return
        # 使用sliderPosition获取值可以同时满足鼠标滑动和拖动判断
        if self.verticalScrollBar().sliderPosition() == self.verticalScrollBar(
        ).maximum():
            # 可以下一页了
            self.load()

    def resizeEvent(self, event):
        super(Window, self).resizeEvent(event)
        self.loadWidget.setGeometry(
            int((self.width() - self.loadWidget.minimumWidth()) / 2),
            int((self.height() - self.loadWidget.minimumHeight()) / 2),
            self.loadWidget.minimumWidth(), self.loadWidget.minimumHeight())