hotplaylist
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
|
@ -21,7 +21,7 @@ from PyQt5.QtSvg import QSvgWidget
|
||||||
from PyQt5.QtWidgets import QWidget, QApplication, QVBoxLayout, QLabel,\
|
from PyQt5.QtWidgets import QWidget, QApplication, QVBoxLayout, QLabel,\
|
||||||
QHBoxLayout, QSpacerItem, QSizePolicy, QScrollArea, QAbstractSlider
|
QHBoxLayout, QSpacerItem, QSizePolicy, QScrollArea, QAbstractSlider
|
||||||
|
|
||||||
from flowlayout import FlowLayout # @UnresolvedImport
|
from Lib.flowlayout import FlowLayout # @UnresolvedImport
|
||||||
from lxml.etree import HTML # @UnresolvedImport
|
from lxml.etree import HTML # @UnresolvedImport
|
||||||
|
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ class GridWidget(QWidget):
|
||||||
li.xpath(".//div[@class='figure_count']/span/text()") or [""])[0]
|
li.xpath(".//div[@class='figure_count']/span/text()") or [""])[0]
|
||||||
path = "cache/{0}.jpg".format(
|
path = "cache/{0}.jpg".format(
|
||||||
os.path.splitext(os.path.basename(video_url))[0])
|
os.path.splitext(os.path.basename(video_url))[0])
|
||||||
cover_path = "pic_v.png"
|
cover_path = "Data/pic_v.png"
|
||||||
if os.path.isfile(path):
|
if os.path.isfile(path):
|
||||||
cover_path = path
|
cover_path = path
|
||||||
iwidget = ItemWidget(cover_path, figure_info, figure_title,
|
iwidget = ItemWidget(cover_path, figure_info, figure_title,
|
18
QFlowLayout/README.md
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# QListView
|
||||||
|
|
||||||
|
## 1、腾讯视频热播列表
|
||||||
|
[运行](HotPlaylist.py)
|
||||||
|
|
||||||
|
简单思路说明:
|
||||||
|
|
||||||
|
- 利用`QScrollArea`滚动显示,自定义的`QFlowLayout`做布局来放置自定义的Widget
|
||||||
|
- `QNetworkAccessManager`异步下载网页和图片
|
||||||
|
- `QScrollArea`滚动到底部触发下一页加载
|
||||||
|
|
||||||
|
自定义控件说明:
|
||||||
|
|
||||||
|
- 主要是多个layout和控件的结合,其中图片`QLabel`为自定义,通过`setPixmap`设置图片,重写`paintEvent`绘制底部渐变矩形框和白色文字
|
||||||
|
- 字体颜色用qss设置
|
||||||
|
- 图标利用了`QSvgWidget`显示,可以是svg 动画(如圆形加载图)
|
||||||
|
|
||||||
|
![HotPlaylist](ScreenShot/HotPlaylist.gif)
|
Before Width: | Height: | Size: 5 MiB After Width: | Height: | Size: 5 MiB |
BIN
QGridLayout/Data/pic_v.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
|
@ -275,7 +275,7 @@ class GridWidget(QWidget):
|
||||||
li.xpath(".//div[@class='figure_count']/span/text()") or [""])[0]
|
li.xpath(".//div[@class='figure_count']/span/text()") or [""])[0]
|
||||||
path = "cache/{0}.jpg".format(
|
path = "cache/{0}.jpg".format(
|
||||||
os.path.splitext(os.path.basename(video_url))[0])
|
os.path.splitext(os.path.basename(video_url))[0])
|
||||||
cover_path = "pic_v.png"
|
cover_path = "Data/pic_v.png"
|
||||||
if os.path.isfile(path):
|
if os.path.isfile(path):
|
||||||
cover_path = path
|
cover_path = path
|
||||||
iwidget = ItemWidget(cover_path, figure_info, figure_title,
|
iwidget = ItemWidget(cover_path, figure_info, figure_title,
|
18
QGridLayout/README.md
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# QListView
|
||||||
|
|
||||||
|
## 1、腾讯视频热播列表
|
||||||
|
[运行](HotPlaylist.py)
|
||||||
|
|
||||||
|
简单思路说明:
|
||||||
|
|
||||||
|
- 利用`QScrollArea`滚动显示,`QGridLayout`做布局来放置自定义的Widget
|
||||||
|
- `QNetworkAccessManager`异步下载网页和图片
|
||||||
|
- `QScrollArea`滚动到底部触发下一页加载
|
||||||
|
|
||||||
|
自定义控件说明:
|
||||||
|
|
||||||
|
- 主要是多个layout和控件的结合,其中图片`QLabel`为自定义,通过`setPixmap`设置图片,重写`paintEvent`绘制底部渐变矩形框和白色文字
|
||||||
|
- 字体颜色用qss设置
|
||||||
|
- 图标利用了`QSvgWidget`显示,可以是svg 动画(如圆形加载图)
|
||||||
|
|
||||||
|
![HotPlaylist](ScreenShot/HotPlaylist.gif)
|
Before Width: | Height: | Size: 4.3 MiB After Width: | Height: | Size: 4.3 MiB |
BIN
QListWidget/Data/pic_v.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
|
@ -274,7 +274,7 @@ class Window(QListWidget):
|
||||||
li.xpath(".//div[@class='figure_count']/span/text()") or [""])[0]
|
li.xpath(".//div[@class='figure_count']/span/text()") or [""])[0]
|
||||||
path = "cache/{0}.jpg".format(
|
path = "cache/{0}.jpg".format(
|
||||||
os.path.splitext(os.path.basename(video_url))[0])
|
os.path.splitext(os.path.basename(video_url))[0])
|
||||||
cover_path = "pic_v.png"
|
cover_path = "Data/pic_v.png"
|
||||||
if os.path.isfile(path):
|
if os.path.isfile(path):
|
||||||
cover_path = path
|
cover_path = path
|
||||||
iwidget = ItemWidget(cover_path, figure_info, figure_title,
|
iwidget = ItemWidget(cover_path, figure_info, figure_title,
|
|
@ -1,29 +0,0 @@
|
||||||
# 腾讯视频热播列表
|
|
||||||
|
|
||||||
简单思路说明:
|
|
||||||
|
|
||||||
- 利用QScrollArea滚动显示,QGridLayout或者FlowLayout做布局来放置自定义的Widget
|
|
||||||
- QNetworkAccessManager异步下载网页和图片
|
|
||||||
- QScrollArea滚动到底部触发下一页加载
|
|
||||||
|
|
||||||
自定义控件说明:
|
|
||||||
|
|
||||||
- 主要是多个layout和控件的结合,其中图片QLabel为自定义,通过setPixmap设置图片,重写paintEvent绘制底部渐变矩形框和白色文字
|
|
||||||
- 字体颜色用qss设置
|
|
||||||
- 图标利用了QSvgWidget显示,可以是svg 动画(如圆形加载图)
|
|
||||||
|
|
||||||
|
|
||||||
# 截图
|
|
||||||
|
|
||||||
使用QGridLayout 固定列数效果图
|
|
||||||
|
|
||||||
![截图1](ScreenShot/1.gif)
|
|
||||||
|
|
||||||
使用自定义布局FlowLayout 自动列数效果图
|
|
||||||
![截图2](ScreenShot/2.gif)
|
|
||||||
|
|
||||||
使用QListWidget 配合setFlow(QListWidget.LeftToRight)和
|
|
||||||
setWrapping(True)和
|
|
||||||
setResizeMode(QListWidget.Adjust)达到类似FlowLayout的效果
|
|
||||||
|
|
||||||
![截图3](ScreenShot/3.gif)
|
|
|
@ -1,161 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
|
|
||||||
#############################################################################
|
|
||||||
##
|
|
||||||
# Copyright (C) 2013 Riverbank Computing Limited.
|
|
||||||
# Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
|
||||||
# All rights reserved.
|
|
||||||
##
|
|
||||||
# This file is part of the examples of PyQt.
|
|
||||||
##
|
|
||||||
# $QT_BEGIN_LICENSE:BSD$
|
|
||||||
# You may use this file under the terms of the BSD license as follows:
|
|
||||||
##
|
|
||||||
# "Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions are
|
|
||||||
# met:
|
|
||||||
# * Redistributions of source code must retain the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer.
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer in
|
|
||||||
# the documentation and/or other materials provided with the
|
|
||||||
# distribution.
|
|
||||||
# * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
|
||||||
# the names of its contributors may be used to endorse or promote
|
|
||||||
# products derived from this software without specific prior written
|
|
||||||
# permission.
|
|
||||||
##
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
|
||||||
# $QT_END_LICENSE$
|
|
||||||
##
|
|
||||||
#############################################################################
|
|
||||||
|
|
||||||
|
|
||||||
from PyQt5.QtCore import QPoint, QRect, QSize, Qt
|
|
||||||
from PyQt5.QtWidgets import (QApplication, QLayout, QPushButton, QSizePolicy,
|
|
||||||
QWidget)
|
|
||||||
|
|
||||||
|
|
||||||
class Window(QWidget):
|
|
||||||
def __init__(self):
|
|
||||||
super(Window, self).__init__()
|
|
||||||
|
|
||||||
flowLayout = FlowLayout()
|
|
||||||
flowLayout.addWidget(QPushButton("Short"))
|
|
||||||
flowLayout.addWidget(QPushButton("Longer"))
|
|
||||||
flowLayout.addWidget(QPushButton("Different text"))
|
|
||||||
flowLayout.addWidget(QPushButton("More text"))
|
|
||||||
flowLayout.addWidget(QPushButton("Even longer button text"))
|
|
||||||
self.setLayout(flowLayout)
|
|
||||||
|
|
||||||
self.setWindowTitle("Flow Layout")
|
|
||||||
|
|
||||||
|
|
||||||
class FlowLayout(QLayout):
|
|
||||||
def __init__(self, parent=None, margin=0, spacing=-1):
|
|
||||||
super(FlowLayout, self).__init__(parent)
|
|
||||||
|
|
||||||
if parent is not None:
|
|
||||||
self.setContentsMargins(margin, margin, margin, margin)
|
|
||||||
|
|
||||||
self.setSpacing(spacing)
|
|
||||||
|
|
||||||
self.itemList = []
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
item = self.takeAt(0)
|
|
||||||
while item:
|
|
||||||
item = self.takeAt(0)
|
|
||||||
|
|
||||||
def addItem(self, item):
|
|
||||||
self.itemList.append(item)
|
|
||||||
|
|
||||||
def count(self):
|
|
||||||
return len(self.itemList)
|
|
||||||
|
|
||||||
def itemAt(self, index):
|
|
||||||
if index >= 0 and index < len(self.itemList):
|
|
||||||
return self.itemList[index]
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def takeAt(self, index):
|
|
||||||
if index >= 0 and index < len(self.itemList):
|
|
||||||
return self.itemList.pop(index)
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def expandingDirections(self):
|
|
||||||
return Qt.Orientations(Qt.Orientation(0))
|
|
||||||
|
|
||||||
def hasHeightForWidth(self):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def heightForWidth(self, width):
|
|
||||||
height = self.doLayout(QRect(0, 0, width, 0), True)
|
|
||||||
return height
|
|
||||||
|
|
||||||
def setGeometry(self, rect):
|
|
||||||
super(FlowLayout, self).setGeometry(rect)
|
|
||||||
self.doLayout(rect, False)
|
|
||||||
|
|
||||||
def sizeHint(self):
|
|
||||||
return self.minimumSize()
|
|
||||||
|
|
||||||
def minimumSize(self):
|
|
||||||
size = QSize()
|
|
||||||
|
|
||||||
for item in self.itemList:
|
|
||||||
size = size.expandedTo(item.minimumSize())
|
|
||||||
|
|
||||||
margin, _, _, _ = self.getContentsMargins()
|
|
||||||
|
|
||||||
size += QSize(2 * margin, 2 * margin)
|
|
||||||
return size
|
|
||||||
|
|
||||||
def doLayout(self, rect, testOnly):
|
|
||||||
x = rect.x()
|
|
||||||
y = rect.y()
|
|
||||||
lineHeight = 0
|
|
||||||
|
|
||||||
for item in self.itemList:
|
|
||||||
wid = item.widget()
|
|
||||||
spaceX = self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton,
|
|
||||||
QSizePolicy.PushButton, Qt.Horizontal)
|
|
||||||
spaceY = self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton,
|
|
||||||
QSizePolicy.PushButton, Qt.Vertical)
|
|
||||||
nextX = x + item.sizeHint().width() + spaceX
|
|
||||||
if nextX - spaceX > rect.right() and lineHeight > 0:
|
|
||||||
x = rect.x()
|
|
||||||
y = y + lineHeight + spaceY
|
|
||||||
nextX = x + item.sizeHint().width() + spaceX
|
|
||||||
lineHeight = 0
|
|
||||||
|
|
||||||
if not testOnly:
|
|
||||||
item.setGeometry(QRect(QPoint(x, y), item.sizeHint()))
|
|
||||||
|
|
||||||
x = nextX
|
|
||||||
lineHeight = max(lineHeight, item.sizeHint().height())
|
|
||||||
|
|
||||||
return y + lineHeight - rect.y()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
app = QApplication(sys.argv)
|
|
||||||
mainWin = Window()
|
|
||||||
mainWin.show()
|
|
||||||
sys.exit(app.exec_())
|
|
|
@ -13,4 +13,27 @@
|
||||||
## 2、自定义可拖拽Item
|
## 2、自定义可拖拽Item
|
||||||
[运行](DragDrop.py)
|
[运行](DragDrop.py)
|
||||||
|
|
||||||
![CustomWidgetSortItem](ScreenShot/DragDrop.gif)
|
![CustomWidgetSortItem](ScreenShot/DragDrop.gif)
|
||||||
|
|
||||||
|
## 3、腾讯视频热播列表
|
||||||
|
[运行](HotPlaylist.py)
|
||||||
|
|
||||||
|
简单思路说明:
|
||||||
|
|
||||||
|
- 利用`QListWidget`设置一些特殊的参数达到可以横向自动显示
|
||||||
|
- `QNetworkAccessManager`异步下载网页和图片
|
||||||
|
- 滚动到底部触发下一页加载
|
||||||
|
|
||||||
|
自定义控件说明:
|
||||||
|
|
||||||
|
- 主要是多个layout和控件的结合,其中图片`QLabel`为自定义,通过`setPixmap`设置图片,重写`paintEvent`绘制底部渐变矩形框和白色文字
|
||||||
|
- 字体颜色用qss设置
|
||||||
|
- 图标利用了`QSvgWidget`显示,可以是svg 动画(如圆形加载图)
|
||||||
|
|
||||||
|
`QListWidget`的参数设置
|
||||||
|
|
||||||
|
1. `setFlow(QListWidget.LeftToRight)`
|
||||||
|
2. `setWrapping(True)`
|
||||||
|
3. `setResizeMode(QListWidget.Adjust)`
|
||||||
|
|
||||||
|
![HotPlaylist](ScreenShot/HotPlaylist.gif)
|
Before Width: | Height: | Size: 6.6 MiB After Width: | Height: | Size: 6.6 MiB |