Merge pull request #1 from 892768447/master

New pull request
This commit is contained in:
625781186 2018-04-11 01:16:18 +08:00 committed by GitHub
commit 6daff6b9f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 2781 additions and 5 deletions

4
.gitignore vendored
View file

@ -10,4 +10,6 @@
/.setting/*
tmp
.project
.pydevproject
.pydevproject
.README.md.html
README.md.html

View file

@ -1,5 +1,6 @@
eclipse.preferences.version=1
encoding//ActiveX\u7A97\u53E3/AxWidget.py=utf-8
encoding//Json\u751F\u6210QTreeWidget/Json\u751F\u6210\u6811\u5F62\u7ED3\u6784.py=utf-8
encoding//PyQtChart\u7EC3\u4E60/ChartView/ChartView.py=utf-8
encoding//PyQtChart\u7EC3\u4E60/ChartView/ChatWidget.py=utf-8
encoding//PyQtChart\u7EC3\u4E60/charts/bar/BarStack.py=utf-8
@ -8,17 +9,28 @@ encoding//PyQtChart\u7EC3\u4E60/test/LineChart.py=utf-8
encoding//PyQtChart\u7EC3\u4E60/test/LineChart\u81EA\u5B9A\u4E49xy\u8F74.py=utf-8
encoding//PyQtChart\u7EC3\u4E60/test/ToolTip.py=utf-8
encoding//PyQtChart\u7EC3\u4E60/test/ToolTip2.py=utf-8
encoding//QGraphicsView\u7EC3\u4E60/ImageView.py=utf-8
encoding//QGraphicsView\u7EC3\u4E60/\u4E16\u754C\u5730\u56FE/WorldMap.py=utf-8
encoding//QGraphicsView\u7EC3\u4E60/\u6DFB\u52A0QWidget.py=utf-8
encoding//QGraphicsView\u7EC3\u4E60/\u7B80\u5355\u56FE\u50CF\u5904\u7406/SimpleImagePs.py=utf-8
encoding//QGraphicsView\u7EC3\u4E60/\u7B80\u5355\u56FE\u50CF\u5904\u7406/SimpleImageThread.py=utf-8
encoding//QGraphicsView\u7EC3\u4E60/\u7B80\u5355\u56FE\u50CF\u5904\u7406/SimpleImageView.py=utf-8
encoding//tmp/LocalClient.py=utf-8
encoding//tmp/Material/Effect/LineEffect.py=utf-8
encoding//tmp/Material/Utils/Colors.py=utf-8
encoding//tmp/Material/Utils/MaterialProperty.py=utf-8
encoding//tmp/Material/Widget/LineEdit.py=utf-8
encoding//tmp/Material/test/TestLineEdit.py=utf-8
encoding//tmp/QtServer.py=utf-8
encoding//tmp/error.py=utf-8
encoding//tmp/json\u751F\u6210\u6811\u5F62\u7ED3\u6784.py=utf-8
encoding//tmp/\u622A\u56FE\u753B\u77E9\u5F62/DrawRectangle.py=utf-8
encoding//tmp/\u7B80\u5355\u63D2\u4EF6/Widget.py=utf-8
encoding//tmp/\u8BFB\u53D6\u526A\u5207\u677F\u56FE\u7247.py=utf-8
encoding//\u4E0B\u62C9\u9009\u62E9\u8054\u52A8/ComboBox.py=utf-8
encoding//\u4EBA\u8138\u63CF\u70B9\u68C0\u6D4B/OpencvWidget.py=utf-8
encoding//\u4EFFQQ\u8BBE\u7F6E\u9762\u677F/SettingUi.py=utf-8
encoding//\u4EFFQQ\u8BBE\u7F6E\u9762\u677F/Window.py=utf-8
encoding//\u5168\u5C40\u70ED\u952E/HotKey.py=utf-8
encoding//\u5206\u5272\u7A97\u53E3\u7684\u5206\u5272\u6761\u91CD\u5199/Splitter.py=utf-8
encoding//\u53F3\u4E0B\u89D2\u5F39\u51FA\u6846/WindowNotify.py=utf-8
@ -50,11 +62,14 @@ encoding//\u754C\u9762\u7F8E\u5316/QPushButton\u8FDB\u5EA6\u52A8\u753B/PushButto
encoding//\u754C\u9762\u7F8E\u5316/QSS\u7F8E\u5316\u4F8B\u5B50/QProgressBar\u8FDB\u5EA6\u6761\u6837\u5F0F/ProgressBar.py=utf-8
encoding//\u754C\u9762\u7F8E\u5316/QSS\u7F8E\u5316\u4F8B\u5B50/QPushButton\u6309\u94AE/ButtonHover.py=utf-8
encoding//\u754C\u9762\u7F8E\u5316/QScrollBar\u6EDA\u52A8\u6761\u6837\u5F0F/ScrollBar.py=utf-8
encoding//\u754C\u9762\u7F8E\u5316/\u6C34\u6CE2\u7EB9\u8FDB\u5EA6\u6761/ProgressBar.py=utf-8
encoding//\u754C\u9762\u7F8E\u5316/\u6C34\u6CE2\u7EB9\u8FDB\u5EA6\u6761/TestWidget.py=utf-8
encoding//\u7A0B\u5E8F\u91CD\u542F/AutoRestart.py=utf-8
encoding//\u7A97\u53E3\u91CD\u542F/RestartMainWindow.py=utf-8
encoding//\u7B80\u5355\u7684\u7A97\u53E3\u8D34\u8FB9\u9690\u85CF/WeltHideWindow.py=utf-8
encoding//\u817E\u8BAF\u89C6\u9891\u70ED\u64AD\u5217\u8868/TencentMovieHotPlay.py=utf-8
encoding//\u817E\u8BAF\u89C6\u9891\u70ED\u64AD\u5217\u8868/TencentMovieHotPlay_Flow.py=utf-8
encoding//\u817E\u8BAF\u89C6\u9891\u70ED\u64AD\u5217\u8868/TencentMovieHotPlay_ListWidget.py=utf-8
encoding//\u81EA\u52A8\u66F4\u65B0/mylibs/testlibs.py=utf-8
encoding//\u81EA\u52A8\u66F4\u65B0/test.py=utf-8
encoding//\u81EA\u5B9A\u4E49QWidget\u7684QSS\u6837\u5F0F/CustomPaintWidget.py=utf-8

View file

@ -0,0 +1,2 @@
eclipse.preferences.version=1
org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false

View file

@ -0,0 +1,152 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2018年4月8日
@author: Irony
@site: https://github.com/892768447
@email: 892768447@qq.com
@file:
@description:
"""
import json
import webbrowser
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QWidget,\
QLabel, QSpacerItem, QSizePolicy, QHBoxLayout
import chardet
__Author__ = """By: Irony
QQ: 892768447
Email: 892768447@qq.com"""
__Copyright__ = "Copyright (c) 2018 Irony"
__Version__ = "Version 1.0"
class ItemWidget(QWidget):
"""自定义的item"""
def __init__(self, text, badge, *args, **kwargs):
super(ItemWidget, self).__init__(*args, **kwargs)
layout = QHBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.addWidget(QLabel(text, self, styleSheet='color: white;'))
layout.addSpacerItem(QSpacerItem(
60, 1, QSizePolicy.Maximum, QSizePolicy.Minimum))
if badge and len(badge) == 2: # 后面带颜色的标签
layout.addWidget(QLabel(
badge[0], self, alignment=Qt.AlignCenter,
styleSheet="""min-width: 80px;
max-width: 80px;
min-height: 38px;
max-height: 38px;
color: white;
border:none;
border-radius: 4px;
background: %s""" % badge[1]
))
class JsonTreeWidget(QTreeWidget):
def __init__(self, *args, **kwargs):
super(JsonTreeWidget, self).__init__(*args, **kwargs)
self.setEditTriggers(self.NoEditTriggers)
self.header().setVisible(False)
# 帮点单击事件
self.itemClicked.connect(self.onItemClicked)
def onItemClicked(self, item):
"""item单击事件"""
if item.url: # 调用浏览器打开网址
webbrowser.open_new_tab(item.url)
def parseData(self, datas, parent=None):
"""解析json数据"""
for data in datas:
url = data.get('url', '')
items = data.get('items', [])
# 生成item
_item = QTreeWidgetItem(parent)
_item.setIcon(0, QIcon(data.get('icon', '')))
_widget = ItemWidget(
data.get('name', ''),
data.get('badge', []),
self
)
_item.url = url # 可以直接设置变量值
self.setItemWidget(_item, 0, _widget)
if url:
continue # 跳过
# 解析儿子
if items:
self.parseData(items, _item)
def loadData(self, path):
"""加载json数据"""
datas = open(path, 'rb').read()
datas = datas.decode(chardet.detect(datas).get('encoding', 'utf-8'))
self.parseData(json.loads(datas), self)
if __name__ == '__main__':
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
app.setStyleSheet("""QTreeView {
outline: 0px;
background: rgb(47, 64, 78);
}
QTreeView::item {
min-height: 92px;
}
QTreeView::item:hover {
background: rgb(41, 56, 71);
}
QTreeView::item:selected {
background: rgb(41, 56, 71);
}
QTreeView::item:selected:active{
background: rgb(41, 56, 71);
}
QTreeView::item:selected:!active{
background: rgb(41, 56, 71);
}
QTreeView::branch:open:has-children {
background: rgb(41, 56, 71);
}
QTreeView::branch:has-siblings:!adjoins-item {
background: green;
}
QTreeView::branch:closed:has-children:has-siblings {
background: rgb(47, 64, 78);
}
QTreeView::branch:has-children:!has-siblings:closed {
background: rgb(47, 64, 78);
}
QTreeView::branch:open:has-children:has-siblings {
background: rgb(41, 56, 71);
}
QTreeView::branch:open:has-children:!has-siblings {
background: rgb(41, 56, 71);
}
QTreeView:branch:hover {
background: rgb(41, 56, 71);
}
QTreeView:branch:selected {
background: rgb(41, 56, 71);
}
""")
w = JsonTreeWidget()
w.show()
w.loadData('data.json')
sys.exit(app.exec_())

View file

@ -0,0 +1,8 @@
# 通过json数据生成QTreeWidget树形结构
### [Python3.4.4 or Python3.5][PyQt5]
emmmmmm,原理就是那样,,解析每一层json数据中的list,美化就不想弄了.
# 截图
![截图1](ScreenShot/1.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

View file

@ -0,0 +1,56 @@
[
{
"name": "仪表盘",
"icon": "xxx.png"
},
{
"name": "微信管理",
"icon": "weixin.png",
"badge": [
"火爆",
"#F8AC54"
],
"items": [
{
"name": "爬虫项目管理",
"icon": "xxx.png",
"badge": [
"推荐",
"#23C6C9"
],
"items": [
{
"name": "腾讯课堂"
},
{
"name": "淘宝"
},
{
"name": "京东"
},
{
"name": "天猫"
},
{
"name": "拉钩"
},
{
"name": "BOSS直聘"
}
]
}
]
},
{
"name": "爬虫部署管理",
"icon": "xxx.png"
},
{
"name": "爬虫监控管理",
"icon": "xxx.png"
},
{
"name": "PyQt",
"url": "https://github.com/892768447/PyQt"
}
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1,108 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2018年3月23日
@author: Irony
@site: https://github.com/892768447
@email: 892768447@qq.com
@file: ImageView
@description: 图片查看
"""
from PyQt5.QtCore import QStandardPaths, Qt
from PyQt5.QtGui import QColor, QPainter, QPixmap
from PyQt5.QtOpenGL import QGLFormat
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, \
QGraphicsItem
__Author__ = 'By: Irony\nQQ: 892768447\nEmail: 892768447@qq.com'
__Copyright__ = 'Copyright (c) 2018 Irony'
__Version__ = 1.0
class GraphicsView(QGraphicsView):
# 背景区域颜色
backgroundColor = QColor(28, 31, 34)
def __init__(self, *args, **kwargs):
super(GraphicsView, self).__init__(*args, **kwargs)
self.resize(800, 600)
# 设置背景颜色
self.setBackgroundBrush(self.backgroundColor)
# 缓存背景
self.setCacheMode(self.CacheBackground)
# 设置拖拽样式
# self.setDragMode(self.ScrollHandDrag)
self.setRenderHints(
QPainter.Antialiasing | QPainter.TextAntialiasing | QPainter.SmoothPixmapTransform)
# opengl
if QGLFormat.hasOpenGL():
self.setRenderHint(QPainter.HighQualityAntialiasing)
# 尝试通过分析需要重绘的区域来找到最佳的更新模式
self.setViewportUpdateMode(self.SmartViewportUpdate)
self._scene = QGraphicsScene(-400, -300, 800, 600, self)
self.setScene(self._scene)
# 图片item
self._itemImage = None
def keyReleaseEvent(self, event):
"""按键处理事件"""
self._scaleImage(event)
super(GraphicsView, self).keyReleaseEvent(event)
def closeEvent(self, event):
"""窗口关闭时清空场景中的所有item"""
self._scene.clear()
self._itemImage = None
super(GraphicsView, self).closeEvent(event)
def _scaleImage(self, event):
"""缩放图片操作"""
if not self._itemImage:
return
scale = self._itemImage.scale()
if event.key() == Qt.Key_Plus:
# 放大
if scale >= 0.91:
return
self._itemImage.setScale(scale + 0.1)
elif event.key() == Qt.Key_Minus:
# 缩小
if scale <= 0.11:
return
self._itemImage.setScale(scale - 0.1)
def loadImage(self):
path, _ = QFileDialog.getOpenFileName(
self, '请选择图片', QStandardPaths.writableLocation(QStandardPaths.DesktopLocation), '图片文件(*.jpg *.png)')
if not path:
return
if self._itemImage:
# 删除以前的item
self._scene.removeItem(self._itemImage)
del self._itemImage
self._itemImage = self._scene.addPixmap(QPixmap(path))
self._itemImage.setFlag(QGraphicsItem.ItemIsMovable)
self._itemImage.setScale(0.1) # 默认加载比例
size = self._itemImage.pixmap().size()
# 调整图片在中间
self._itemImage.setPos(
-size.width() * self._itemImage.scale() / 2,
-size.height() * self._itemImage.scale() / 2
)
if __name__ == '__main__':
import sys
import os
print(os.getpid())
from PyQt5.QtWidgets import QApplication, QPushButton
app = QApplication(sys.argv)
w = GraphicsView()
w.show()
ww = QPushButton('选择文件', clicked=w.loadImage)
ww.show()
sys.exit(app.exec_())

View file

@ -5,4 +5,7 @@
### [1.世界地图](世界地图/)
### [2.添加QWidget](添加QWidget.py)
![添加QWidget](ScreenShot/1.png)
![添加QWidget](ScreenShot/1.png)
### [3.显示图片及缩放](ImageView.py) - 按下小键盘-为缩小, +为放大
![显示图片及缩放](ScreenShot/ImageView.gif)

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 KiB

View file

@ -0,0 +1,78 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2018年3月24日
@author: Irony
@site: https://github.com/892768447
@email: 892768447@qq.com
@file: SimpleImagePs
@description: 图片查看
"""
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QCursor
from PyQt5.QtWidgets import QMainWindow, QToolBar
from SimpleImageView import SimpleImageView # @UnresolvedImport
__Author__ = """By: Irony
QQ: 892768447
Email: 892768447@qq.com"""
__Copyright__ = 'Copyright (c) 2018 Irony'
__Version__ = 1.0
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
# 获取可用主屏桌面大小
screenRect = QApplication.instance().desktop().availableGeometry()
# 设置为桌面的2/3大
self.resize(
int(screenRect.width() * 2 / 3), int(screenRect.height() * 2 / 3))
# 初始化中心控件
self._imageView = SimpleImageView(self)
self.setCentralWidget(self._imageView)
# 初始化菜单栏
self._initMenuBar()
# 初始化工具条
self._initToolBar()
def _initMenuBar(self):
"""菜单栏"""
menuBar = self.menuBar()
menu = menuBar.addMenu('文件')
menu.addAction('打开', self._imageView.loadImage)
menu.addAction('关闭')
menu.addAction('退出')
def _initToolBar(self):
"""工具条"""
toolBar = QToolBar('工具栏', self)
self.addToolBar(Qt.LeftToolBarArea, toolBar)
toolBar.addAction('灰度', self._imageView._greyScale)
toolBar.addAction('亮度')
toolBar.addAction('暖色调')
toolBar.addAction('冷色调')
toolBar.addAction('饱和度')
toolBar.addAction('模糊')
toolBar.addAction('锐化', self._ruihua)
def _ruihua(self):
# 得到按钮的大概位置
print(self.mapFromGlobal(QCursor.pos()))
if __name__ == '__main__':
import sys
import os
print('pid:', os.getpid())
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
app.setApplicationDisplayName('简单图片处理')
app.setApplicationName('简单图片处理')
app.setApplicationVersion('1.0')
w = MainWindow()
w.show()
sys.exit(app.exec_())

View file

@ -0,0 +1,19 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PyQt5.QtCore import QObject
# Created on 2018年3月26日
# author: Irony
# site: https://github.com/892768447
# email: 892768447@qq.com
# file: QGraphicsView练习.简单图像处理.SimpleImageThread
# description:
__Author__ = """By: Irony
QQ: 892768447
Email: 892768447@qq.com"""
__Copyright__ = 'Copyright (c) 2018 Irony'
__Version__ = 1.0
class ToGrey(QObject):
pass

View file

@ -0,0 +1,158 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2018年3月24日
@author: Irony
@site: https://github.com/892768447
@email: 892768447@qq.com
@file: SimpleImageView
@description: 图片视图
"""
import struct
from time import time
from PIL import Image
from PIL.Image import fromarray
from PIL.ImageQt import fromqpixmap
from PyQt5.QtCore import QStandardPaths, Qt
from PyQt5.QtGui import QColor, QPainter, QPixmap, QImage, qRgb, qRed, qGreen,\
qBlue, QCursor
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, \
QGraphicsItem
import numpy
try:
from PyQt5.QtOpenGL import QGLFormat # , QGL, QGLWidget
hasOpenGL = True
except Exception as e:
print(e)
hasOpenGL = False
__Author__ = """By: Irony
QQ: 892768447
Email: 892768447@qq.com"""
__Copyright__ = 'Copyright (c) 2018 Irony'
__Version__ = 1.0
class SimpleImageView(QGraphicsView):
# 背景区域颜色
backgroundColor = QColor(28, 31, 34)
def __init__(self, *args, **kwargs):
super(SimpleImageView, self).__init__(*args, **kwargs)
# 设置背景颜色
self.setBackgroundBrush(self.backgroundColor)
# 缓存背景
self.setCacheMode(self.CacheBackground)
# 设置拖拽样式
# self.setDragMode(self.ScrollHandDrag)
self.setRenderHints(
QPainter.Antialiasing | QPainter.TextAntialiasing | QPainter.SmoothPixmapTransform)
# opengl
if hasOpenGL and QGLFormat.hasOpenGL():
# self.setViewport(QGLWidget(QGLFormat(QGL.SampleBuffers), self))
self.setRenderHint(QPainter.HighQualityAntialiasing)
self.setViewportUpdateMode(self.FullViewportUpdate)
else:
# 尝试通过分析需要重绘的区域来找到最佳的更新模式
self.setViewportUpdateMode(self.SmartViewportUpdate)
self._scene = QGraphicsScene(self)
self.setScene(self._scene)
# 图片item
self._itemImage = None
self._itemImageNew = None
def keyReleaseEvent(self, event):
"""按键处理事件"""
self._scaleImage(event)
super(SimpleImageView, self).keyReleaseEvent(event)
def closeEvent(self, event):
"""窗口关闭时清空场景中的所有item"""
self._scene.clear()
self._itemImage = None
self._itemImageNew = None
super(SimpleImageView, self).closeEvent(event)
def _scaleImage(self, event):
"""缩放图片操作"""
item = self._scene.focusItem()
if not item:
item = self._scene.items()
if not item:
return
item = item[0]
# 获取item的缩放度
scale = item.scale()
if event.key() == Qt.Key_Plus:
# 放大
if scale >= 0.91:
return
item.setScale(scale + 0.1)
elif event.key() == Qt.Key_Minus:
# 缩小
if scale <= 0.11:
return
item.setScale(scale - 0.1)
def loadImage(self):
path, _ = QFileDialog.getOpenFileName(
self, '请选择图片', QStandardPaths.writableLocation(QStandardPaths.DesktopLocation), '图片文件(*.jpg *.png)')
if not path:
return
if self._itemImageNew:
self._scene.removeItem(self._itemImageNew)
del self._itemImageNew
self._itemImageNew = None
if self._itemImage:
# 删除以前的item
self._scene.removeItem(self._itemImage)
del self._itemImage
self._itemImage = None
self._itemImage = self._scene.addPixmap(QPixmap(path))
self._itemImage.setFlag(QGraphicsItem.ItemIsMovable)
self._itemImage.setFlag(QGraphicsItem.ItemIsFocusable)
self._itemImage.setScale(0.1) # 默认加载比例
self._scene.setFocusItem(self._itemImage)
print(self._itemImage.zValue())
size = self._itemImage.pixmap().size()
# 调整图片在中间
self._itemImage.setPos(
-size.width() * self._itemImage.scale() / 2,
-size.height() * self._itemImage.scale() / 2
)
def _greyScale(self):
if not self._itemImage:
return
if self._itemImageNew:
self._scene.removeItem(self._itemImageNew)
del self._itemImageNew
self._itemImageNew = None
t = time()
# QPixmap 转 PIL Image 转 numpy array
image = numpy.array(fromqpixmap(self._itemImage.pixmap()).convert('L'))
image = fromarray(image).toqpixmap()
self._itemImageNew = self._scene.addPixmap(image)
self._itemImageNew.setFlag(QGraphicsItem.ItemIsFocusable)
self._itemImageNew.setFlag(QGraphicsItem.ItemIsMovable)
self._itemImageNew.setScale(self._itemImage.scale()) # 默认加载比例
self._scene.setFocusItem(self._itemImageNew)
print(self._itemImageNew.zValue())
print(time() - t)
if __name__ == '__main__':
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
w = SimpleImageView()
w.resize(800, 600)
w.show()
sys.exit(app.exec_())

View file

@ -25,6 +25,9 @@
- [1.18 人脸描点检测](人脸描点检测/)
- [1.19 腾讯视频热播列表](腾讯视频热播列表/)
- [1.20 exec()动态生成控件](partner_625781186/1.exec动态生成控件/)
- [1.21 仿QQ设置面板](仿QQ设置面板/)
- [1.22 Json生成QTreeWidget](Json生成QTreeWidget/)
### [2.QGraphicsView练习](QGraphicsView练习/)
- [2.1 世界地图](QGraphicsView练习/世界地图)
@ -44,9 +47,13 @@
- [4.6 QFileSystemModel图标](界面美化/QFileSystemModel图标)
- [4.7 QPushButton进度动画](界面美化/QPushButton进度动画)
- [4.8 折叠动画效果](partner_625781186/2.折叠控件/)
- [4.9 水波纹进度条](界面美化/水波纹进度条)
# QQ群
- [PyQt & PySide](https://jq.qq.com/?_wv=1027&k=50LWvn9)
- [PyQt学习互助](https://jq.qq.com/?_wv=1027&k=5QVVEdF)
# [Donate](Donate/)
# [Donate-打赏](Donate/)
# Wiki
- [一些Qt写的三方APP](https://github.com/892768447/PyQt/wiki/3rd-party-applications)

View file

@ -0,0 +1,16 @@
# 仿QQ设置面板简单例子
左侧:
使用QListWidget点击左侧时得到索引然后根据索引去找右侧的widget_0之类的
右侧:
使用QScrollArea控件设置QVBoxLayout布局然后一次添加Widget
事件:
- 1. 绑定左侧QListWidget的itemClicked的到该item的索引
- 2. 绑定右侧滚动条的valueChanged事件得到pos
注意当itemClicked时定位滚动条的值时需要设置一个标志位用来避免valueChanged重复调用item的定位
## 截图
![截图](ScreenShot/1.gif)

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 KiB

View file

@ -0,0 +1,494 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'setting.ui'
#
# Created by: PyQt5 UI code generator 5.5.1
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Setting(object):
def setupUi(self, Setting):
Setting.setObjectName("Setting")
Setting.resize(498, 498)
self.horizontalLayout = QtWidgets.QHBoxLayout(Setting)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setSpacing(0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.listWidget = QtWidgets.QListWidget(Setting)
self.listWidget.setFrameShape(QtWidgets.QFrame.NoFrame)
self.listWidget.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.listWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.listWidget.setObjectName("listWidget")
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
self.horizontalLayout.addWidget(self.listWidget)
self.scrollArea = QtWidgets.QScrollArea(Setting)
self.scrollArea.setFrameShape(QtWidgets.QFrame.NoFrame)
self.scrollArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, -810, 460, 1308))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.verticalLayout = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
self.verticalLayout.setContentsMargins(35, 20, 35, 20)
self.verticalLayout.setSpacing(20)
self.verticalLayout.setObjectName("verticalLayout")
self.widget_0 = QtWidgets.QWidget(self.scrollAreaWidgetContents)
self.widget_0.setObjectName("widget_0")
self.formLayout = QtWidgets.QFormLayout(self.widget_0)
self.formLayout.setContentsMargins(0, 0, 0, 0)
self.formLayout.setObjectName("formLayout")
self.titleLabel1 = QtWidgets.QLabel(self.widget_0)
self.titleLabel1.setObjectName("titleLabel1")
self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.titleLabel1)
self.CheckBox = QtWidgets.QCheckBox(self.widget_0)
self.CheckBox.setObjectName("CheckBox")
self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.CheckBox)
self.checkBox = QtWidgets.QCheckBox(self.widget_0)
self.checkBox.setChecked(True)
self.checkBox.setObjectName("checkBox")
self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.checkBox)
self.checkBox_2 = QtWidgets.QCheckBox(self.widget_0)
self.checkBox_2.setChecked(True)
self.checkBox_2.setObjectName("checkBox_2")
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.checkBox_2)
self.checkBox_3 = QtWidgets.QCheckBox(self.widget_0)
self.checkBox_3.setObjectName("checkBox_3")
self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.checkBox_3)
self.checkBox_4 = QtWidgets.QCheckBox(self.widget_0)
self.checkBox_4.setObjectName("checkBox_4")
self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.checkBox_4)
self.checkBox_5 = QtWidgets.QCheckBox(self.widget_0)
self.checkBox_5.setObjectName("checkBox_5")
self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.checkBox_5)
self.checkBox_6 = QtWidgets.QCheckBox(self.widget_0)
self.checkBox_6.setObjectName("checkBox_6")
self.formLayout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.checkBox_6)
self.verticalLayout.addWidget(self.widget_0)
self.widget_1 = QtWidgets.QWidget(self.scrollAreaWidgetContents)
self.widget_1.setObjectName("widget_1")
self.formLayout_8 = QtWidgets.QFormLayout(self.widget_1)
self.formLayout_8.setContentsMargins(0, 0, 0, 0)
self.formLayout_8.setObjectName("formLayout_8")
self.titleLabel2 = QtWidgets.QLabel(self.widget_1)
self.titleLabel2.setObjectName("titleLabel2")
self.formLayout_8.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.titleLabel2)
self.checkBox_26 = QtWidgets.QCheckBox(self.widget_1)
self.checkBox_26.setObjectName("checkBox_26")
self.formLayout_8.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.checkBox_26)
self.checkBox_27 = QtWidgets.QCheckBox(self.widget_1)
self.checkBox_27.setObjectName("checkBox_27")
self.formLayout_8.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.checkBox_27)
self.checkBox_28 = QtWidgets.QCheckBox(self.widget_1)
self.checkBox_28.setObjectName("checkBox_28")
self.formLayout_8.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.checkBox_28)
self.checkBox_29 = QtWidgets.QCheckBox(self.widget_1)
self.checkBox_29.setObjectName("checkBox_29")
self.formLayout_8.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.checkBox_29)
self.label_10 = QtWidgets.QLabel(self.widget_1)
self.label_10.setObjectName("label_10")
self.formLayout_8.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.label_10)
self.right1 = QtWidgets.QRadioButton(self.widget_1)
self.right1.setObjectName("right1")
self.formLayout_8.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.right1)
self.right2 = QtWidgets.QRadioButton(self.widget_1)
self.right2.setChecked(True)
self.right2.setObjectName("right2")
self.formLayout_8.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.right2)
self.label_11 = QtWidgets.QLabel(self.widget_1)
self.label_11.setObjectName("label_11")
self.formLayout_8.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.label_11)
self.right3 = QtWidgets.QPushButton(self.widget_1)
self.right3.setObjectName("right3")
self.formLayout_8.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.right3)
self.verticalLayout.addWidget(self.widget_1)
self.widget_2 = QtWidgets.QWidget(self.scrollAreaWidgetContents)
self.widget_2.setObjectName("widget_2")
self.formLayout_9 = QtWidgets.QFormLayout(self.widget_2)
self.formLayout_9.setContentsMargins(0, 0, 0, 0)
self.formLayout_9.setObjectName("formLayout_9")
self.titleLabel3 = QtWidgets.QLabel(self.widget_2)
self.titleLabel3.setObjectName("titleLabel3")
self.formLayout_9.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.titleLabel3)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.label_13 = QtWidgets.QLabel(self.widget_2)
self.label_13.setObjectName("label_13")
self.horizontalLayout_2.addWidget(self.label_13)
self.comboBox = QtWidgets.QComboBox(self.widget_2)
self.comboBox.setObjectName("comboBox")
self.comboBox.addItem("")
self.comboBox.addItem("")
self.comboBox.addItem("")
self.comboBox.addItem("")
self.comboBox.addItem("")
self.comboBox.addItem("")
self.horizontalLayout_2.addWidget(self.comboBox)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_2.addItem(spacerItem)
self.formLayout_9.setLayout(0, QtWidgets.QFormLayout.FieldRole, self.horizontalLayout_2)
self.checkBox_30 = QtWidgets.QCheckBox(self.widget_2)
self.checkBox_30.setObjectName("checkBox_30")
self.formLayout_9.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.checkBox_30)
self.right4 = QtWidgets.QLabel(self.widget_2)
self.right4.setObjectName("right4")
self.formLayout_9.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.right4)
self.checkBox_31 = QtWidgets.QCheckBox(self.widget_2)
self.checkBox_31.setObjectName("checkBox_31")
self.formLayout_9.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.checkBox_31)
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.pushButton_5 = QtWidgets.QPushButton(self.widget_2)
self.pushButton_5.setObjectName("pushButton_5")
self.horizontalLayout_3.addWidget(self.pushButton_5)
self.pushButton_4 = QtWidgets.QPushButton(self.widget_2)
self.pushButton_4.setObjectName("pushButton_4")
self.horizontalLayout_3.addWidget(self.pushButton_4)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_3.addItem(spacerItem1)
self.formLayout_9.setLayout(4, QtWidgets.QFormLayout.FieldRole, self.horizontalLayout_3)
self.verticalLayout.addWidget(self.widget_2)
self.widget_3 = QtWidgets.QWidget(self.scrollAreaWidgetContents)
self.widget_3.setObjectName("widget_3")
self.formLayout_2 = QtWidgets.QFormLayout(self.widget_3)
self.formLayout_2.setContentsMargins(0, 0, 0, 0)
self.formLayout_2.setObjectName("formLayout_2")
self.titleLabel4 = QtWidgets.QLabel(self.widget_3)
self.titleLabel4.setObjectName("titleLabel4")
self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.titleLabel4)
self.CheckBox_2 = QtWidgets.QCheckBox(self.widget_3)
self.CheckBox_2.setChecked(True)
self.CheckBox_2.setObjectName("CheckBox_2")
self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.CheckBox_2)
self.checkBox_7 = QtWidgets.QCheckBox(self.widget_3)
self.checkBox_7.setObjectName("checkBox_7")
self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.checkBox_7)
self.checkBox_8 = QtWidgets.QCheckBox(self.widget_3)
self.checkBox_8.setObjectName("checkBox_8")
self.formLayout_2.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.checkBox_8)
self.checkBox_9 = QtWidgets.QCheckBox(self.widget_3)
self.checkBox_9.setChecked(True)
self.checkBox_9.setObjectName("checkBox_9")
self.formLayout_2.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.checkBox_9)
self.checkBox_10 = QtWidgets.QCheckBox(self.widget_3)
self.checkBox_10.setChecked(True)
self.checkBox_10.setObjectName("checkBox_10")
self.formLayout_2.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.checkBox_10)
self.checkBox_11 = QtWidgets.QCheckBox(self.widget_3)
self.checkBox_11.setChecked(True)
self.checkBox_11.setObjectName("checkBox_11")
self.formLayout_2.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.checkBox_11)
self.checkBox_12 = QtWidgets.QCheckBox(self.widget_3)
self.checkBox_12.setChecked(True)
self.checkBox_12.setObjectName("checkBox_12")
self.formLayout_2.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.checkBox_12)
self.checkBox_13 = QtWidgets.QCheckBox(self.widget_3)
self.checkBox_13.setChecked(True)
self.checkBox_13.setObjectName("checkBox_13")
self.formLayout_2.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.checkBox_13)
self.checkBox_14 = QtWidgets.QCheckBox(self.widget_3)
self.checkBox_14.setChecked(True)
self.checkBox_14.setObjectName("checkBox_14")
self.formLayout_2.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.checkBox_14)
self.checkBox_15 = QtWidgets.QCheckBox(self.widget_3)
self.checkBox_15.setChecked(True)
self.checkBox_15.setObjectName("checkBox_15")
self.formLayout_2.setWidget(9, QtWidgets.QFormLayout.FieldRole, self.checkBox_15)
self.verticalLayout.addWidget(self.widget_3)
self.widget_4 = QtWidgets.QWidget(self.scrollAreaWidgetContents)
self.widget_4.setObjectName("widget_4")
self.formLayout_3 = QtWidgets.QFormLayout(self.widget_4)
self.formLayout_3.setContentsMargins(0, 0, 0, 0)
self.formLayout_3.setObjectName("formLayout_3")
self.titleLabel5 = QtWidgets.QLabel(self.widget_4)
self.titleLabel5.setObjectName("titleLabel5")
self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.titleLabel5)
self.checkBox_16 = QtWidgets.QCheckBox(self.widget_4)
self.checkBox_16.setChecked(True)
self.checkBox_16.setObjectName("checkBox_16")
self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.checkBox_16)
self.checkBox_17 = QtWidgets.QCheckBox(self.widget_4)
self.checkBox_17.setChecked(True)
self.checkBox_17.setObjectName("checkBox_17")
self.formLayout_3.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.checkBox_17)
self.checkBox_18 = QtWidgets.QCheckBox(self.widget_4)
self.checkBox_18.setChecked(True)
self.checkBox_18.setObjectName("checkBox_18")
self.formLayout_3.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.checkBox_18)
self.checkBox_19 = QtWidgets.QCheckBox(self.widget_4)
self.checkBox_19.setChecked(True)
self.checkBox_19.setObjectName("checkBox_19")
self.formLayout_3.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.checkBox_19)
self.verticalLayout.addWidget(self.widget_4)
self.widget_5 = QtWidgets.QWidget(self.scrollAreaWidgetContents)
self.widget_5.setObjectName("widget_5")
self.formLayout_4 = QtWidgets.QFormLayout(self.widget_5)
self.formLayout_4.setContentsMargins(0, 0, 0, 0)
self.formLayout_4.setObjectName("formLayout_4")
self.titleLabel6 = QtWidgets.QLabel(self.widget_5)
self.titleLabel6.setObjectName("titleLabel6")
self.formLayout_4.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.titleLabel6)
self.checkBox_20 = QtWidgets.QCheckBox(self.widget_5)
self.checkBox_20.setObjectName("checkBox_20")
self.formLayout_4.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.checkBox_20)
self.checkBox_21 = QtWidgets.QCheckBox(self.widget_5)
self.checkBox_21.setObjectName("checkBox_21")
self.formLayout_4.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.checkBox_21)
self.checkBox_22 = QtWidgets.QCheckBox(self.widget_5)
self.checkBox_22.setObjectName("checkBox_22")
self.formLayout_4.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.checkBox_22)
self.checkBox_23 = QtWidgets.QCheckBox(self.widget_5)
self.checkBox_23.setObjectName("checkBox_23")
self.formLayout_4.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.checkBox_23)
self.checkBox_24 = QtWidgets.QCheckBox(self.widget_5)
self.checkBox_24.setObjectName("checkBox_24")
self.formLayout_4.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.checkBox_24)
self.right5 = QtWidgets.QLabel(self.widget_5)
self.right5.setObjectName("right5")
self.formLayout_4.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.right5)
self.label_3 = QtWidgets.QLabel(self.widget_5)
self.label_3.setObjectName("label_3")
self.formLayout_4.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.label_3)
self.label_4 = QtWidgets.QLabel(self.widget_5)
self.label_4.setObjectName("label_4")
self.formLayout_4.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.label_4)
self.radioButton = QtWidgets.QRadioButton(self.widget_5)
self.radioButton.setObjectName("radioButton")
self.formLayout_4.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.radioButton)
self.radioButton_2 = QtWidgets.QRadioButton(self.widget_5)
self.radioButton_2.setObjectName("radioButton_2")
self.formLayout_4.setWidget(9, QtWidgets.QFormLayout.FieldRole, self.radioButton_2)
self.radioButton_3 = QtWidgets.QRadioButton(self.widget_5)
self.radioButton_3.setChecked(True)
self.radioButton_3.setObjectName("radioButton_3")
self.formLayout_4.setWidget(10, QtWidgets.QFormLayout.FieldRole, self.radioButton_3)
self.formLayout_5 = QtWidgets.QFormLayout()
self.formLayout_5.setObjectName("formLayout_5")
self.listWidgetUser = QtWidgets.QListWidget(self.widget_5)
self.listWidgetUser.setFrameShape(QtWidgets.QFrame.NoFrame)
self.listWidgetUser.setObjectName("listWidgetUser")
self.formLayout_5.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.listWidgetUser)
self.pushButton = QtWidgets.QPushButton(self.widget_5)
self.pushButton.setObjectName("pushButton")
self.formLayout_5.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.pushButton)
self.formLayout_4.setLayout(11, QtWidgets.QFormLayout.FieldRole, self.formLayout_5)
self.verticalLayout.addWidget(self.widget_5)
self.widget_6 = QtWidgets.QWidget(self.scrollAreaWidgetContents)
self.widget_6.setObjectName("widget_6")
self.formLayout_6 = QtWidgets.QFormLayout(self.widget_6)
self.formLayout_6.setContentsMargins(0, 0, 0, 0)
self.formLayout_6.setObjectName("formLayout_6")
self.titleLabel7 = QtWidgets.QLabel(self.widget_6)
self.titleLabel7.setObjectName("titleLabel7")
self.formLayout_6.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.titleLabel7)
self.label_6 = QtWidgets.QLabel(self.widget_6)
self.label_6.setObjectName("label_6")
self.formLayout_6.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.label_6)
self.pushButton_2 = QtWidgets.QPushButton(self.widget_6)
self.pushButton_2.setObjectName("pushButton_2")
self.formLayout_6.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.pushButton_2)
self.verticalLayout.addWidget(self.widget_6)
self.widget_7 = QtWidgets.QWidget(self.scrollAreaWidgetContents)
self.widget_7.setObjectName("widget_7")
self.formLayout_7 = QtWidgets.QFormLayout(self.widget_7)
self.formLayout_7.setContentsMargins(0, 0, 0, 0)
self.formLayout_7.setObjectName("formLayout_7")
self.titleLabel8 = QtWidgets.QLabel(self.widget_7)
self.titleLabel8.setObjectName("titleLabel8")
self.formLayout_7.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.titleLabel8)
self.checkBox_25 = QtWidgets.QCheckBox(self.widget_7)
self.checkBox_25.setObjectName("checkBox_25")
self.formLayout_7.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.checkBox_25)
self.right6 = QtWidgets.QLabel(self.widget_7)
self.right6.setObjectName("right6")
self.formLayout_7.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.right6)
self.verticalLayout.addWidget(self.widget_7)
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.horizontalLayout.addWidget(self.scrollArea)
self.retranslateUi(Setting)
self.listWidget.setCurrentRow(0)
QtCore.QMetaObject.connectSlotsByName(Setting)
Setting.setTabOrder(self.listWidget, self.scrollArea)
Setting.setTabOrder(self.scrollArea, self.CheckBox)
Setting.setTabOrder(self.CheckBox, self.checkBox)
Setting.setTabOrder(self.checkBox, self.checkBox_2)
Setting.setTabOrder(self.checkBox_2, self.checkBox_3)
Setting.setTabOrder(self.checkBox_3, self.checkBox_4)
Setting.setTabOrder(self.checkBox_4, self.checkBox_5)
Setting.setTabOrder(self.checkBox_5, self.checkBox_6)
Setting.setTabOrder(self.checkBox_6, self.checkBox_26)
Setting.setTabOrder(self.checkBox_26, self.checkBox_27)
Setting.setTabOrder(self.checkBox_27, self.checkBox_28)
Setting.setTabOrder(self.checkBox_28, self.checkBox_29)
Setting.setTabOrder(self.checkBox_29, self.right1)
Setting.setTabOrder(self.right1, self.right2)
Setting.setTabOrder(self.right2, self.right3)
Setting.setTabOrder(self.right3, self.comboBox)
Setting.setTabOrder(self.comboBox, self.checkBox_30)
Setting.setTabOrder(self.checkBox_30, self.checkBox_31)
Setting.setTabOrder(self.checkBox_31, self.pushButton_5)
Setting.setTabOrder(self.pushButton_5, self.pushButton_4)
Setting.setTabOrder(self.pushButton_4, self.CheckBox_2)
Setting.setTabOrder(self.CheckBox_2, self.checkBox_7)
Setting.setTabOrder(self.checkBox_7, self.checkBox_8)
Setting.setTabOrder(self.checkBox_8, self.checkBox_9)
Setting.setTabOrder(self.checkBox_9, self.checkBox_10)
Setting.setTabOrder(self.checkBox_10, self.checkBox_11)
Setting.setTabOrder(self.checkBox_11, self.checkBox_12)
Setting.setTabOrder(self.checkBox_12, self.checkBox_13)
Setting.setTabOrder(self.checkBox_13, self.checkBox_14)
Setting.setTabOrder(self.checkBox_14, self.checkBox_15)
Setting.setTabOrder(self.checkBox_15, self.checkBox_16)
Setting.setTabOrder(self.checkBox_16, self.checkBox_17)
Setting.setTabOrder(self.checkBox_17, self.checkBox_18)
Setting.setTabOrder(self.checkBox_18, self.checkBox_19)
Setting.setTabOrder(self.checkBox_19, self.checkBox_20)
Setting.setTabOrder(self.checkBox_20, self.checkBox_21)
Setting.setTabOrder(self.checkBox_21, self.checkBox_22)
Setting.setTabOrder(self.checkBox_22, self.checkBox_23)
Setting.setTabOrder(self.checkBox_23, self.checkBox_24)
Setting.setTabOrder(self.checkBox_24, self.radioButton)
Setting.setTabOrder(self.radioButton, self.radioButton_2)
Setting.setTabOrder(self.radioButton_2, self.radioButton_3)
Setting.setTabOrder(self.radioButton_3, self.listWidgetUser)
Setting.setTabOrder(self.listWidgetUser, self.pushButton)
Setting.setTabOrder(self.pushButton, self.pushButton_2)
Setting.setTabOrder(self.pushButton_2, self.checkBox_25)
def retranslateUi(self, Setting):
_translate = QtCore.QCoreApplication.translate
Setting.setWindowTitle(_translate("Setting", "仿QQ设置面板"))
__sortingEnabled = self.listWidget.isSortingEnabled()
self.listWidget.setSortingEnabled(False)
item = self.listWidget.item(0)
item.setText(_translate("Setting", "登录"))
item = self.listWidget.item(1)
item.setText(_translate("Setting", "主面板"))
item = self.listWidget.item(2)
item.setText(_translate("Setting", "状态"))
item = self.listWidget.item(3)
item.setText(_translate("Setting", "会话窗口"))
item = self.listWidget.item(4)
item.setText(_translate("Setting", "信息展示"))
item = self.listWidget.item(5)
item.setText(_translate("Setting", "提醒"))
item = self.listWidget.item(6)
item.setText(_translate("Setting", "热键"))
item = self.listWidget.item(7)
item.setText(_translate("Setting", "显示"))
item = self.listWidget.item(8)
item.setText(_translate("Setting", "声音"))
item = self.listWidget.item(9)
item.setText(_translate("Setting", "软件更新"))
item = self.listWidget.item(10)
item.setText(_translate("Setting", "文件管理"))
item = self.listWidget.item(11)
item.setText(_translate("Setting", "文件共享"))
item = self.listWidget.item(12)
item.setText(_translate("Setting", "音视频通话"))
self.listWidget.setSortingEnabled(__sortingEnabled)
self.titleLabel1.setText(_translate("Setting", "登录:"))
self.CheckBox.setText(_translate("Setting", "开机时自动启动QQ"))
self.checkBox.setText(_translate("Setting", "启动QQ时为我自动登录"))
self.checkBox_2.setText(_translate("Setting", "总是打开登录提示"))
self.checkBox_3.setText(_translate("Setting", "离线自动启动QQ手机版仅支持Android"))
self.checkBox_4.setText(_translate("Setting", "登录后自动运行QQ宠物"))
self.checkBox_5.setText(_translate("Setting", "订阅“腾讯视频”,获取量身定制视频资讯"))
self.checkBox_6.setText(_translate("Setting", "订阅“每日精选”,了解最新商品资讯"))
self.titleLabel2.setText(_translate("Setting", "主面板:"))
self.checkBox_26.setText(_translate("Setting", "始终保持在其他窗口前端"))
self.checkBox_27.setText(_translate("Setting", "停靠在桌面边缘时自动隐藏"))
self.checkBox_28.setText(_translate("Setting", "在任务栏通知区域显示QQ图标"))
self.checkBox_29.setText(_translate("Setting", "显示天气"))
self.label_10.setText(_translate("Setting", "关闭主面板时:"))
self.right1.setText(_translate("Setting", "隐藏到任务栏通知区域,不退出程序"))
self.right2.setText(_translate("Setting", "退出程序"))
self.label_11.setText(_translate("Setting", "您可以自由定制适合您的面板和功能使用QQ更有效率"))
self.right3.setText(_translate("Setting", "界面管理器"))
self.titleLabel3.setText(_translate("Setting", "状态:"))
self.label_13.setText(_translate("Setting", "登陆后状态为:"))
self.comboBox.setItemText(0, _translate("Setting", "我在线上"))
self.comboBox.setItemText(1, _translate("Setting", "Q我吧"))
self.comboBox.setItemText(2, _translate("Setting", "离开"))
self.comboBox.setItemText(3, _translate("Setting", "忙碌"))
self.comboBox.setItemText(4, _translate("Setting", "请勿打扰"))
self.comboBox.setItemText(5, _translate("Setting", "隐身"))
self.checkBox_30.setText(_translate("Setting", "运行全屏程序时切换至“忙碌“状态””"))
self.right4.setText(_translate("Setting", "仅在“Q我吧”和“我在线上”状态下生效"))
self.checkBox_31.setText(_translate("Setting", "离开、忙碌、请勿打扰时自动回复100字以内"))
self.pushButton_5.setText(_translate("Setting", "自动回复设置"))
self.pushButton_4.setText(_translate("Setting", "快捷回复设置"))
self.titleLabel4.setText(_translate("Setting", "会话窗口:"))
self.CheckBox_2.setText(_translate("Setting", "使用多彩气泡聊天"))
self.checkBox_7.setText(_translate("Setting", "不显示广告(会员设置项)"))
self.checkBox_8.setText(_translate("Setting", "允许来消息时自动弹出窗口"))
self.checkBox_9.setText(_translate("Setting", "默认使用腾讯视频播放视频文件"))
self.checkBox_10.setText(_translate("Setting", "允许自动播放魔法表情和超级表情"))
self.checkBox_11.setText(_translate("Setting", "允许使用QQ秀聊天随动表情"))
self.checkBox_12.setText(_translate("Setting", "总是显示好友聊天窗口侧边栏"))
self.checkBox_13.setText(_translate("Setting", "允许接收窗口抖动"))
self.checkBox_14.setText(_translate("Setting", "显示热词搜索提示"))
self.checkBox_15.setText(_translate("Setting", "显示历史消息记录"))
self.titleLabel5.setText(_translate("Setting", "信息展示:"))
self.checkBox_16.setText(_translate("Setting", "在资料卡和迷你信息卡上显示等级图标"))
self.checkBox_17.setText(_translate("Setting", "在资料卡和迷你卡上显示更新搜索"))
self.checkBox_18.setText(_translate("Setting", "在聊天窗口内展示好友的更新摘要"))
self.checkBox_19.setText(_translate("Setting", "在聊天窗口内展示好友互动标识"))
self.titleLabel6.setText(_translate("Setting", "提醒:"))
self.checkBox_20.setText(_translate("Setting", "会话消息提醒"))
self.checkBox_21.setText(_translate("Setting", "新邮件提醒"))
self.checkBox_22.setText(_translate("Setting", "启用QQ看点消息"))
self.checkBox_23.setText(_translate("Setting", "启用一声问候消息"))
self.checkBox_24.setText(_translate("Setting", "启用设备连接提醒"))
self.right5.setText(_translate("Setting", "当插入安卓设备时提示安装或者更新QQ手机版"))
self.label_3.setText(_translate("Setting", "<html><head/><body><p>您可以设置是否在屏幕右下角收到来自QQ空间的通知<a href=\"#\"><span style=\" text-decoration: none; color:#00aaff;\">进入设置</span></a>。</p></body></html>"))
self.label_4.setText(_translate("Setting", "好友上线提醒"))
self.radioButton.setText(_translate("Setting", "关闭好友上线提醒"))
self.radioButton_2.setText(_translate("Setting", "全部好友上线提醒"))
self.radioButton_3.setText(_translate("Setting", "以下好友上线提醒"))
self.pushButton.setText(_translate("Setting", "添加"))
self.titleLabel7.setText(_translate("Setting", "热键:"))
self.label_6.setText(_translate("Setting", "您可以通过点击选择要更改的热键"))
self.pushButton_2.setText(_translate("Setting", "设置热键"))
self.titleLabel8.setText(_translate("Setting", "显示:"))
self.checkBox_25.setText(_translate("Setting", "开启QQ适配屏幕DPI"))
self.right6.setText(_translate("Setting", "关闭选项后QQ将保持默认大小设置后需要重新登录才能生效"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Setting = QtWidgets.QWidget()
ui = Ui_Setting()
ui.setupUi(Setting)
Setting.show()
sys.exit(app.exec_())

View file

@ -0,0 +1,66 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PyQt5.QtWidgets import QWidget
from SettingUi import Ui_Setting # @UnresolvedImport
# Created on 2018年3月28日
# author: Irony
# site: https://github.com/892768447
# email: 892768447@qq.com
# file: 仿QQ设置面板.Window
# description:
__Author__ = """By: Irony
QQ: 892768447
Email: 892768447@qq.com"""
__Copyright__ = 'Copyright (c) 2018 Irony'
__Version__ = 1.0
class Window(QWidget, Ui_Setting):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(*args, **kwargs)
self.setupUi(self)
self.resize(700, 435)
self._blockSignals = False
# 绑定滚动条和左侧item事件
self.scrollArea.verticalScrollBar().valueChanged.connect(
self.onValueChanged)
self.listWidget.itemClicked.connect(self.onItemClicked)
def onValueChanged(self, value):
"""滚动条"""
if self._blockSignals:
# 防止item点击时改变滚动条会触发这里
return
for i in range(8): # 因为这里右侧有8个widget
widget = getattr(self, 'widget_%d' % i, None)
# widget不为空且在可视范围内
if widget and not widget.visibleRegion().isEmpty():
self.listWidget.setCurrentRow(i) # 设置item的选中
return
def onItemClicked(self, item):
"""左侧item"""
row = self.listWidget.row(item) # 获取点击的item的索引
# 由于右侧的widget是按照命名widget_0 widget_1这样比较规范的方法,可以通过getattr找到
widget = getattr(self, 'widget_%d' % row, None)
if not widget:
return
# 定位右侧位置并滚动
self._blockSignals = True
self.scrollArea.verticalScrollBar().setSliderPosition(widget.pos().y())
self._blockSignals = False
if __name__ == '__main__':
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
app.setStyleSheet(open("style.qss", "rb").read().decode("utf-8"))
w = Window()
w.show()
sys.exit(app.exec_())

View file

@ -0,0 +1,897 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Setting</class>
<widget class="QWidget" name="Setting">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>498</width>
<height>498</height>
</rect>
</property>
<property name="windowTitle">
<string>仿QQ设置面板</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="listWidget">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="currentRow">
<number>0</number>
</property>
<item>
<property name="text">
<string>登录</string>
</property>
</item>
<item>
<property name="text">
<string>主面板</string>
</property>
</item>
<item>
<property name="text">
<string>状态</string>
</property>
</item>
<item>
<property name="text">
<string>会话窗口</string>
</property>
</item>
<item>
<property name="text">
<string>信息展示</string>
</property>
</item>
<item>
<property name="text">
<string>提醒</string>
</property>
</item>
<item>
<property name="text">
<string>热键</string>
</property>
</item>
<item>
<property name="text">
<string>显示</string>
</property>
</item>
<item>
<property name="text">
<string>声音</string>
</property>
</item>
<item>
<property name="text">
<string>软件更新</string>
</property>
</item>
<item>
<property name="text">
<string>文件管理</string>
</property>
</item>
<item>
<property name="text">
<string>文件共享</string>
</property>
</item>
<item>
<property name="text">
<string>音视频通话</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>-810</y>
<width>460</width>
<height>1308</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>20</number>
</property>
<property name="leftMargin">
<number>35</number>
</property>
<property name="topMargin">
<number>20</number>
</property>
<property name="rightMargin">
<number>35</number>
</property>
<property name="bottomMargin">
<number>20</number>
</property>
<item>
<widget class="QWidget" name="widget_0" native="true">
<layout class="QFormLayout" name="formLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="titleLabel1">
<property name="text">
<string>登录:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="CheckBox">
<property name="text">
<string>开机时自动启动QQ</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>启动QQ时为我自动登录</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="checkBox_2">
<property name="text">
<string>总是打开登录提示</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="checkBox_3">
<property name="text">
<string>离线自动启动QQ手机版仅支持Android</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="checkBox_4">
<property name="text">
<string>登录后自动运行QQ宠物</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="checkBox_5">
<property name="text">
<string>订阅“腾讯视频”,获取量身定制视频资讯</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="checkBox_6">
<property name="text">
<string>订阅“每日精选”,了解最新商品资讯</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_1" native="true">
<layout class="QFormLayout" name="formLayout_8">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="titleLabel2">
<property name="text">
<string>主面板:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="checkBox_26">
<property name="text">
<string>始终保持在其他窗口前端</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkBox_27">
<property name="text">
<string>停靠在桌面边缘时自动隐藏</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="checkBox_28">
<property name="text">
<string>在任务栏通知区域显示QQ图标</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="checkBox_29">
<property name="text">
<string>显示天气</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_10">
<property name="text">
<string>关闭主面板时:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QRadioButton" name="right1">
<property name="text">
<string>隐藏到任务栏通知区域,不退出程序</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QRadioButton" name="right2">
<property name="text">
<string>退出程序</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLabel" name="label_11">
<property name="text">
<string>您可以自由定制适合您的面板和功能使用QQ更有效率</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QPushButton" name="right3">
<property name="text">
<string>界面管理器</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_2" native="true">
<layout class="QFormLayout" name="formLayout_9">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="titleLabel3">
<property name="text">
<string>状态:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_13">
<property name="text">
<string>登陆后状态为:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox">
<item>
<property name="text">
<string>我在线上</string>
</property>
</item>
<item>
<property name="text">
<string>Q我吧</string>
</property>
</item>
<item>
<property name="text">
<string>离开</string>
</property>
</item>
<item>
<property name="text">
<string>忙碌</string>
</property>
</item>
<item>
<property name="text">
<string>请勿打扰</string>
</property>
</item>
<item>
<property name="text">
<string>隐身</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkBox_30">
<property name="text">
<string>运行全屏程序时切换至“忙碌“状态””</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="right4">
<property name="text">
<string>仅在“Q我吧”和“我在线上”状态下生效</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="checkBox_31">
<property name="text">
<string>离开、忙碌、请勿打扰时自动回复100字以内</string>
</property>
</widget>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="pushButton_5">
<property name="text">
<string>自动回复设置</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_4">
<property name="text">
<string>快捷回复设置</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_3" native="true">
<layout class="QFormLayout" name="formLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="titleLabel4">
<property name="text">
<string>会话窗口:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="CheckBox_2">
<property name="text">
<string>使用多彩气泡聊天</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkBox_7">
<property name="text">
<string>不显示广告(会员设置项)</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="checkBox_8">
<property name="text">
<string>允许来消息时自动弹出窗口</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="checkBox_9">
<property name="text">
<string>默认使用腾讯视频播放视频文件</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="checkBox_10">
<property name="text">
<string>允许自动播放魔法表情和超级表情</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="checkBox_11">
<property name="text">
<string>允许使用QQ秀聊天随动表情</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="checkBox_12">
<property name="text">
<string>总是显示好友聊天窗口侧边栏</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="checkBox_13">
<property name="text">
<string>允许接收窗口抖动</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QCheckBox" name="checkBox_14">
<property name="text">
<string>显示热词搜索提示</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QCheckBox" name="checkBox_15">
<property name="text">
<string>显示历史消息记录</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_4" native="true">
<layout class="QFormLayout" name="formLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="titleLabel5">
<property name="text">
<string>信息展示:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="checkBox_16">
<property name="text">
<string>在资料卡和迷你信息卡上显示等级图标</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkBox_17">
<property name="text">
<string>在资料卡和迷你卡上显示更新搜索</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="checkBox_18">
<property name="text">
<string>在聊天窗口内展示好友的更新摘要</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="checkBox_19">
<property name="text">
<string>在聊天窗口内展示好友互动标识</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_5" native="true">
<layout class="QFormLayout" name="formLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="titleLabel6">
<property name="text">
<string>提醒:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="checkBox_20">
<property name="text">
<string>会话消息提醒</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkBox_21">
<property name="text">
<string>新邮件提醒</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="checkBox_22">
<property name="text">
<string>启用QQ看点消息</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="checkBox_23">
<property name="text">
<string>启用一声问候消息</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="checkBox_24">
<property name="text">
<string>启用设备连接提醒</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="right5">
<property name="text">
<string>当插入安卓设备时提示安装或者更新QQ手机版</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="label_3">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;您可以设置是否在屏幕右下角收到来自QQ空间的通知&lt;a href=&quot;#&quot;&gt;&lt;span style=&quot; text-decoration: none; color:#00aaff;&quot;&gt;进入设置&lt;/span&gt;&lt;/a&gt;。&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>好友上线提醒</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QRadioButton" name="radioButton">
<property name="text">
<string>关闭好友上线提醒</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QRadioButton" name="radioButton_2">
<property name="text">
<string>全部好友上线提醒</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QRadioButton" name="radioButton_3">
<property name="text">
<string>以下好友上线提醒</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="11" column="1">
<layout class="QFormLayout" name="formLayout_5">
<item row="0" column="0">
<widget class="QListWidget" name="listWidgetUser">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>添加</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_6" native="true">
<layout class="QFormLayout" name="formLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="titleLabel7">
<property name="text">
<string>热键:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_6">
<property name="text">
<string>您可以通过点击选择要更改的热键</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string>设置热键</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_7" native="true">
<layout class="QFormLayout" name="formLayout_7">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="titleLabel8">
<property name="text">
<string>显示:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="checkBox_25">
<property name="text">
<string>开启QQ适配屏幕DPI</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="right6">
<property name="text">
<string>关闭选项后QQ将保持默认大小设置后需要重新登录才能生效</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>listWidget</tabstop>
<tabstop>scrollArea</tabstop>
<tabstop>CheckBox</tabstop>
<tabstop>checkBox</tabstop>
<tabstop>checkBox_2</tabstop>
<tabstop>checkBox_3</tabstop>
<tabstop>checkBox_4</tabstop>
<tabstop>checkBox_5</tabstop>
<tabstop>checkBox_6</tabstop>
<tabstop>checkBox_26</tabstop>
<tabstop>checkBox_27</tabstop>
<tabstop>checkBox_28</tabstop>
<tabstop>checkBox_29</tabstop>
<tabstop>right1</tabstop>
<tabstop>right2</tabstop>
<tabstop>right3</tabstop>
<tabstop>comboBox</tabstop>
<tabstop>checkBox_30</tabstop>
<tabstop>checkBox_31</tabstop>
<tabstop>pushButton_5</tabstop>
<tabstop>pushButton_4</tabstop>
<tabstop>CheckBox_2</tabstop>
<tabstop>checkBox_7</tabstop>
<tabstop>checkBox_8</tabstop>
<tabstop>checkBox_9</tabstop>
<tabstop>checkBox_10</tabstop>
<tabstop>checkBox_11</tabstop>
<tabstop>checkBox_12</tabstop>
<tabstop>checkBox_13</tabstop>
<tabstop>checkBox_14</tabstop>
<tabstop>checkBox_15</tabstop>
<tabstop>checkBox_16</tabstop>
<tabstop>checkBox_17</tabstop>
<tabstop>checkBox_18</tabstop>
<tabstop>checkBox_19</tabstop>
<tabstop>checkBox_20</tabstop>
<tabstop>checkBox_21</tabstop>
<tabstop>checkBox_22</tabstop>
<tabstop>checkBox_23</tabstop>
<tabstop>checkBox_24</tabstop>
<tabstop>radioButton</tabstop>
<tabstop>radioButton_2</tabstop>
<tabstop>radioButton_3</tabstop>
<tabstop>listWidgetUser</tabstop>
<tabstop>pushButton</tabstop>
<tabstop>pushButton_2</tabstop>
<tabstop>checkBox_25</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View file

@ -0,0 +1,77 @@
/*左侧*/
#listWidget {
outline: 0px;
max-width: 165px;
background-color: rgb(240, 240, 240);
}
#listWidget::item {
min-height: 45px;
}
#listWidget::item:hover {
background-color: rgb(225, 230, 235);
}
#listWidget::item:selected {
color: black;
background-color: rgb(255, 255, 255);
}
/*右侧*/
#titleLabel1,#titleLabel2,#titleLabel3,#titleLabel4,#titleLabel5,#titleLabel6,#titleLabel7,#titleLabel8 {
min-width: 75px;
max-width: 75px;
}
#right1,#right2,#right3,#right4,#right5,#right6 {
margin-left: 25px;
color: rgb(128, 128, 128);
}
/*所有按钮*/
QPushButton {
max-width: 80px;
max-height: 24px;
min-height: 24px;
border-radius: 3px;
background-color: rgb(244, 244, 244);
border: 1px solid rgb(167, 167, 167);
}
QPushButton:hover {
background-color: rgb(190, 231, 253);
}
QPushButton:pressed {
background-color: rgb(244, 244, 244);
}
QComboBox {
max-width: 80px;
max-height: 20px;
min-height: 20px;
}
QComboBox {
border: 1px solid rgb(167, 167, 167);
border-radius: 3px;
}
#listWidgetUser {
min-width: 290px;
max-width: 290px;
max-height: 120px;
min-height: 120px;
border-radius: 2px;
border: 1px solid rgb(227, 236, 242);
background-color: rgb(244, 250, 253);
}
QScrollBar::vertical {
background: rgb(178, 178, 178);
border: -5px solid grey;
margin: 0px 0px 0px 0px;
width: 10px;
}
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
background: white;
}

View file

@ -17,4 +17,6 @@
### [6.QFileSystemModel图标](QFileSystemModel图标/)
### [6.QPushButton进度动画](QPushButton进度动画/)
### [7.QPushButton进度动画](QPushButton进度动画/)
### [7.水波纹进度条](水波纹进度条/)

View file

@ -0,0 +1,162 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Created on 2018年4月1日
# author: Irony
# site: https://github.com/892768447
# email: 892768447@qq.com
# file: ProgressBar
# description:
__Author__ = """By: Irony
QQ: 892768447
Email: 892768447@qq.com"""
__Copyright__ = 'Copyright (c) 2018 Irony'
__Version__ = 1.0
import math
from PyQt5.QtCore import QTimer, Qt, QRectF, QSize
from PyQt5.QtGui import QPainter, QPainterPath, QColor, QFont
from PyQt5.QtWidgets import QProgressBar
class ProgressBar(QProgressBar):
# 浪高百分比
waterHeight = 1
# 密度
waterDensity = 1
# 样式1为矩形, 0为圆形
styleType = 1
# 文字颜色
textColor = Qt.white
# 背景颜色
backgroundColor = Qt.gray
# 波浪颜色1
waterColor1 = QColor(33, 178, 148)
# 波浪颜色2
waterColor2 = QColor(33, 178, 148, 100)
def __init__(self, *args, **kwargs):
super(ProgressBar, self).__init__(*args, **kwargs)
self._offset = 0
# 每隔100ms刷新波浪模拟波浪动态
self._updateTimer = QTimer(self, timeout=self.update)
self._updateTimer.start(100)
def setRange(self, minValue, maxValue):
if minValue == maxValue == 0:
return # 不允许设置busy状态
super(ProgressBar, self).setRange(minValue, maxValue)
def setMinimum(self, value):
if value == self.maximum() == 0:
return # 不允许设置busy状态
super(ProgressBar, self).setMinimum(value)
def setMaximum(self, value):
if value == self.minimum() == 0:
return # 不允许设置busy状态
super(ProgressBar, self).setMaximum(value)
def setWaterHeight(self, height):
"""设置浪高"""
self.waterHeight = height
self.update()
def setWaterDensity(self, density):
"""设置密度"""
self.waterDensity = density
self.update()
def setStyleType(self, style):
"""设置类型"""
self.styleType = style
self.update()
def sizeHint(self):
return QSize(100, 100)
def paintEvent(self, event):
if self.minimum() == self.maximum() == 0:
return
# 正弦曲线公式 y = A * sin(ωx + φ) + k
# 当前值所占百分比
percent = 1 - (self.value() - self.minimum()) / \
(self.maximum() - self.minimum())
# w表示周期6为人为定义
w = 6 * self.waterDensity * math.pi / self.width()
# A振幅 高度百分比1/26为人为定义
A = self.height() * self.waterHeight * 1 / 26
# k 高度百分比
k = self.height() * percent
# 波浪1
waterPath1 = QPainterPath()
waterPath1.moveTo(0, self.height()) # 起点在左下角
# 波浪2
waterPath2 = QPainterPath()
waterPath2.moveTo(0, self.height()) # 起点在左下角
# 偏移
self._offset += 0.6
if self._offset > self.width() / 2:
self._offset = 0
for i in range(self.width() + 1):
# 从x轴开始计算y轴点
y = A * math.sin(w * i + self._offset) + k
waterPath1.lineTo(i, y)
# 相对第一条需要进行错位
y = A * math.sin(w * i + self._offset + self.width() / 2 * A) + k
waterPath2.lineTo(i, y)
# 封闭两条波浪,形成一个 U形 上面加波浪的封闭区间
waterPath1.lineTo(self.width(), self.height())
waterPath1.lineTo(0, self.height())
waterPath2.lineTo(self.width(), self.height())
waterPath2.lineTo(0, self.height())
# 整体形状(矩形或者圆形)
bgPath = QPainterPath()
if self.styleType:
bgPath.addRect(QRectF(self.rect()))
else:
radius = min(self.width(), self.height())
bgPath.addRoundedRect(QRectF(self.rect()), radius, radius)
# 开始画路径
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing, True)
# 设置没有画笔
painter.setPen(Qt.NoPen)
# 先整体绘制背景,然后再在背景上方绘制两条波浪
painter.save()
painter.setBrush(self.backgroundColor)
painter.drawPath(bgPath)
painter.restore()
# 波浪1
painter.save()
painter.setBrush(self.waterColor1)
painter.drawPath(waterPath1)
painter.restore()
# 波浪2
painter.save()
painter.setBrush(self.waterColor2)
painter.drawPath(waterPath2)
painter.restore()
# 绘制文字
if not self.isTextVisible():
return
painter.setPen(self.textColor)
font = self.font() or QFont()
font.setPixelSize(int(min(self.width(), self.height()) / 2))
painter.setFont(font)
painter.drawText(self.rect(), Qt.AlignCenter, '%d%%' %
(self.value() / self.maximum() * 100))

View file

@ -0,0 +1,11 @@
# 矩形/圆形 水波纹进度条
### 简单说明
- 利用正弦函数根据0-width的范围计算y坐标
- 利用QPainterPath矩形或者圆形作为背景
- 用QPainterPath把y坐标用lineTo连接起来形成一个U字形+上方波浪的闭合区间
截图
![1](ScreenShot/1.gif)

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

View file

@ -0,0 +1,125 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Created on 2018年4月1日
# author: Irony
# site: https://github.com/892768447
# email: 892768447@qq.com
# file: TestWidget
# description:
__Author__ = """By: Irony
QQ: 892768447
Email: 892768447@qq.com"""
__Copyright__ = 'Copyright (c) 2018 Irony'
__Version__ = 1.0
from random import randint
from PyQt5.Qt import QSpinBox
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QPixmap, QIcon
from PyQt5.QtWidgets import QWidget, QFormLayout, QRadioButton, QPushButton,\
QColorDialog
from ProgressBar import ProgressBar # @UnresolvedImport
class Window(QWidget):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(*args, **kwargs)
self.resize(800, 600)
self.bar = ProgressBar(self)
self.bar.setMinimumSize(400, 400)
self.bar.setMaximumSize(400, 400)
layout = QFormLayout(self)
layout.addWidget(QRadioButton(
'矩形', self, checked=True, clicked=lambda: self.bar.setStyleType(1)))
layout.addWidget(
QRadioButton('圆形', clicked=lambda: self.bar.setStyleType(0)))
layout.addWidget(
QPushButton('设置背景颜色', self, clicked=self.chooseBackgroundColor))
layout.addWidget(
QPushButton('设置文字颜色', self, clicked=self.chooseTextColor))
layout.addWidget(
QPushButton('设置波浪1颜色', self, clicked=self.chooseWaterColor1))
layout.addWidget(
QPushButton('设置波浪2颜色', self, clicked=self.chooseWaterColor2))
layout.addWidget(
QPushButton('设置随机0-100固定值', self, clicked=self.setRandomValue))
layout.addRow('振幅(浪高)',
QSpinBox(self, value=1, valueChanged=self.bar.setWaterHeight))
layout.addRow('周期(密度)',
QSpinBox(self, value=1, valueChanged=self.bar.setWaterDensity))
layout.addWidget(self.bar)
# 动态设置进度条的值
self._valueTimer = QTimer(self, timeout=self.updateValue)
self._valueTimer.start(100)
def chooseBackgroundColor(self):
"""设置背景颜色"""
col = QColorDialog.getColor(self.bar.backgroundColor, self)
if not col.isValid():
return
self.bar.backgroundColor = col
pix = QPixmap(16, 16)
pix.fill(col)
self.sender().setIcon(QIcon(pix))
def chooseTextColor(self):
"""设置文字颜色"""
col = QColorDialog.getColor(self.bar.textColor, self)
if not col.isValid():
return
self.bar.textColor = col
pix = QPixmap(16, 16)
pix.fill(col)
self.sender().setIcon(QIcon(pix))
def chooseWaterColor1(self):
"""设置波浪1颜色"""
col = QColorDialog.getColor(self.bar.waterColor1, self)
if not col.isValid():
return
self.bar.waterColor1 = col
pix = QPixmap(16, 16)
pix.fill(col)
self.sender().setIcon(QIcon(pix))
def chooseWaterColor2(self):
"""设置波浪2颜色"""
col = QColorDialog.getColor(self.bar.waterColor2, self)
if not col.isValid():
return
self.bar.waterColor2 = col
pix = QPixmap(16, 16)
pix.fill(col)
self.sender().setIcon(QIcon(pix))
def setRandomValue(self):
"""设置随机0-100值并停止自增"""
self._valueTimer.stop()
self.bar.setValue(randint(0, 100))
def updateValue(self):
value = self.bar.value() + 1
if value > self.bar.maximum():
value = 0
self.bar.setValue(value)
if __name__ == '__main__':
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())

View file

@ -20,4 +20,10 @@
![截图1](ScreenShot/1.gif)
使用自定义布局FlowLayout 自动列数效果图
![截图2](ScreenShot/2.gif)
![截图2](ScreenShot/2.gif)
使用QListWidget 配合setFlow(QListWidget.LeftToRight)和
setWrapping(True)和
setResizeMode(QListWidget.Adjust)达到类似FlowLayout的效果
![截图3](ScreenShot/3.gif)

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 MiB

View file

@ -0,0 +1,312 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2018年2月4日
@author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@email: 892768447@qq.com
@file: TencentMovieHotPlay_ListWidget
@description:
'''
import os
import sys
import webbrowser
from PyQt5.QtCore import QSize, Qt, QUrl, QTimer
from PyQt5.QtGui import QPainter, QFont, QLinearGradient, QGradient, QColor,\
QBrush, QPaintEvent, QPixmap
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest
from PyQt5.QtSvg import QSvgWidget
from PyQt5.QtWidgets import QWidget, QApplication, QVBoxLayout, QLabel,\
QHBoxLayout, QSpacerItem, QSizePolicy, QAbstractSlider,\
QListWidget, QListWidgetItem
from lxml.etree import HTML # @UnresolvedImport
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2018 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
# offset=0,30,60,90
Url = "http://v.qq.com/x/list/movie?pay=-1&offset={0}"
# 播放量图标
Svg_icon_play_sm = '''<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<path d="M10.83 8.31v.022l-4.08 2.539-.005.003-.048.03-.012-.005c-.073.051-.15.101-.246.101-.217 0-.376-.165-.413-.369l-.027-.011V5.461l.009-.005c0-.009-.009-.014-.009-.022 0-.24.197-.435.44-.435.096 0 .174.049.247.101l.031-.017 4.129 2.569v.016a.42.42 0 0 1 .153.317.418.418 0 0 1-.169.325zm3.493 2.604a.986.986 0 0 1-.948.742 1 1 0 0 1-1-1 .98.98 0 0 1 .094-.412l-.019-.01C12.79 9.559 13 8.807 13 8a5 5 0 1 0-5 5c.766 0 1.484-.186 2.133-.494l.013.03a.975.975 0 0 1 .417-.097 1 1 0 0 1 1 1 .987.987 0 0 1-.77.954A6.936 6.936 0 0 1 8 14.999a7 7 0 1 1 7-7c0 1.048-.261 2.024-.677 2.915z" fill="#999999"></path>
</svg>
'''.encode()
Svg_icon_loading = '''<svg width="100%" height="100%" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient x1="8.042%" y1="0%" x2="65.682%" y2="23.865%" id="a">
<stop stop-color="#03a9f4" stop-opacity="0" offset="0%"/>
<stop stop-color="#03a9f4" stop-opacity=".631" offset="63.146%"/>
<stop stop-color="#03a9f4" offset="100%"/>
</linearGradient>
</defs>
<g fill="none" fill-rule="evenodd">
<g transform="translate(1 1)">
<path d="M36 18c0-9.94-8.06-18-18-18" id="Oval-2" stroke="url(#a)" stroke-width="2">
<animateTransform
attributeName="transform"
type="rotate"
from="0 18 18"
to="360 18 18"
dur="0.5s"
repeatCount="indefinite" />
</path>
<circle fill="#03a9f4" cx="36" cy="18" r="4">
<animateTransform
attributeName="transform"
type="rotate"
from="0 18 18"
to="360 18 18"
dur="0.5s"
repeatCount="indefinite" />
</circle>
</g>
</g>
</svg>'''.encode()
# 主演
Actor = '''<a href="{href}" target="_blank" title="{title}" style="text-decoration: none;font-size: 12px;color: #999999;">{title}</a>&nbsp;'''
class CoverLabel(QLabel):
def __init__(self, cover_path, cover_title, video_url, *args, **kwargs):
super(CoverLabel, self).__init__(*args, **kwargs)
# super(CoverLabel, self).__init__(
# '<html><head/><body><img src="{0}"/></body></html>'.format(os.path.abspath(cover_path)), *args, **kwargs)
self.setCursor(Qt.PointingHandCursor)
self.setScaledContents(True)
self.setMinimumSize(220, 308)
self.setMaximumSize(220, 308)
self.cover_path = cover_path
self.cover_title = cover_title
self.video_url = video_url
self.setPixmap(QPixmap(cover_path))
def setCoverPath(self, path):
self.cover_path = path
def mouseReleaseEvent(self, event):
super(CoverLabel, self).mouseReleaseEvent(event)
webbrowser.open_new_tab(self.video_url)
def paintEvent(self, event):
super(CoverLabel, self).paintEvent(event)
if hasattr(self, "cover_title") and self.cover_title != "":
# 底部绘制文字
painter = QPainter(self)
rect = self.rect()
# 粗略字体高度
painter.save()
fheight = self.fontMetrics().height()
# 底部矩形框背景渐变颜色
bottomRectColor = QLinearGradient(
rect.width() / 2, rect.height() - 24 - fheight,
rect.width() / 2, rect.height())
bottomRectColor.setSpread(QGradient.PadSpread)
bottomRectColor.setColorAt(0, QColor(255, 255, 255, 70))
bottomRectColor.setColorAt(1, QColor(0, 0, 0, 50))
# 画半透明渐变矩形框
painter.setPen(Qt.NoPen)
painter.setBrush(QBrush(bottomRectColor))
painter.drawRect(rect.x(), rect.height() - 24 -
fheight, rect.width(), 24 + fheight)
painter.restore()
# 距离底部一定高度画文字
font = self.font() or QFont()
font.setPointSize(8)
painter.setFont(font)
painter.setPen(Qt.white)
rect.setHeight(rect.height() - 12) # 底部减去一定高度
painter.drawText(rect, Qt.AlignHCenter |
Qt.AlignBottom, self.cover_title)
class ItemWidget(QWidget):
def __init__(self, cover_path, figure_info, figure_title,
figure_score, figure_desc, figure_count, video_url, cover_url, img_path, manager, *args, **kwargs):
super(ItemWidget, self).__init__(*args, **kwargs)
self.setMaximumSize(220, 420)
self.setMaximumSize(220, 420)
self.img_path = img_path
self.cover_url = cover_url
self._manager = manager
layout = QVBoxLayout(self)
layout.setContentsMargins(10, 20, 10, 0)
# 图片label
self.clabel = CoverLabel(cover_path, figure_info, video_url, self)
layout.addWidget(self.clabel)
# 片名和分数
flayout = QHBoxLayout()
flayout.addWidget(QLabel(figure_title, self))
flayout.addItem(QSpacerItem(
20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum))
flayout.addWidget(QLabel(figure_score, self, styleSheet="color: red;"))
layout.addLayout(flayout)
# 主演
layout.addWidget(
QLabel(figure_desc, self, styleSheet="color: #999999;", openExternalLinks=True))
# 播放量
blayout = QHBoxLayout()
count_icon = QSvgWidget(self)
count_icon.setMaximumSize(16, 16)
count_icon.load(Svg_icon_play_sm)
blayout.addWidget(count_icon)
blayout.addWidget(
QLabel(figure_count, self, styleSheet="color: #999999;"))
layout.addLayout(blayout)
def setCover(self, path):
self.clabel.setCoverPath(path)
self.clabel.setPixmap(QPixmap(path))
# self.clabel.setText('<img src="{0}"/>'.format(os.path.abspath(path)))
def sizeHint(self):
# 每个item控件的大小
return QSize(220, 420)
def event(self, event):
if isinstance(event, QPaintEvent):
if event.rect().height() > 20 and hasattr(self, "clabel"):
if self.clabel.cover_path.find("pic_v.png") > -1: # 封面未加载
# print("start download img:", self.cover_url)
req = QNetworkRequest(QUrl(self.cover_url))
# 设置两个自定义属性方便后期reply中处理
req.setAttribute(QNetworkRequest.User + 1, self)
req.setAttribute(QNetworkRequest.User + 2, self.img_path)
self._manager.get(req) # 调用父窗口中的下载器下载
return super(ItemWidget, self).event(event)
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 = "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()
)
if __name__ == "__main__":
os.makedirs("cache", exist_ok=True)
app = QApplication(sys.argv)
w = Window()
w.show()
w.load()
sys.exit(app.exec_())