更新完善Readme
|
@ -30,7 +30,7 @@ encoding//\u5217\u8868/QListWidget/\u817E\u8BAF\u89C6\u9891\u70ED\u64AD\u5217\u8
|
|||
encoding//\u5217\u8868/QListWidget/\u81EA\u5B9A\u4E49\u53EF\u62D6\u62FDItem.py=utf-8
|
||||
encoding//\u52A8\u753B/\u53F3\u952E\u83DC\u5355\u52A8\u753B.py=utf-8
|
||||
encoding//\u52A8\u753B/\u6309\u94AE\u653E\u5927\u7F29\u5C0F\u52A8\u753B.py=utf-8
|
||||
encoding//\u52A8\u753B/\u6DE1\u5165\u6DE1\u51FA.py=utf-8
|
||||
encoding//\u52A8\u753B/\u7A97\u53E3\u6DE1\u5165\u6DE1\u51FA.py=utf-8
|
||||
encoding//\u56FE\u5F62\u89C6\u56FE/ImageView.py=utf-8
|
||||
encoding//\u56FE\u5F62\u89C6\u56FE/QGraphicsItem/Item\u62D6\u62FD\u6539\u53D8\u5927\u5C0F.py=utf-8
|
||||
encoding//\u56FE\u5F62\u89C6\u56FE/QGraphicsItem/Item\u79FB\u52A8.py=utf-8
|
||||
|
@ -58,6 +58,8 @@ encoding//\u56FE\u8868/PyQtChart\u7EC3\u4E60/test/LineChart.py=utf-8
|
|||
encoding//\u56FE\u8868/PyQtChart\u7EC3\u4E60/test/LineChart\u81EA\u5B9A\u4E49xy\u8F74.py=utf-8
|
||||
encoding//\u56FE\u8868/PyQtChart\u7EC3\u4E60/test/ToolTip.py=utf-8
|
||||
encoding//\u56FE\u8868/PyQtChart\u7EC3\u4E60/test/ToolTip2.py=utf-8
|
||||
encoding//\u591A\u7EBF\u7A0B/moveToThread.py=utf-8
|
||||
encoding//\u591A\u7EBF\u7A0B/\u7EE7\u627FQThread.py=utf-8
|
||||
encoding//\u591A\u9875\u9762/QScrollArea/\u4EFFQQ\u8BBE\u7F6E\u9762\u677F/SettingUi.py=utf-8
|
||||
encoding//\u591A\u9875\u9762/QScrollArea/\u4EFFQQ\u8BBE\u7F6E\u9762\u677F/Window.py=utf-8
|
||||
encoding//\u591A\u9875\u9762/QStackedWidget/\u5DE6\u4FA7\u9009\u9879\u5361/LeftTabWidget.py=utf-8
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
## [1、显示Word、Excel、PDF文件](显示word_excel_pdf.py)
|
||||
|
||||
1. 利用 Word.Application 打开Word文件
|
||||
1. 利用 Excel.Application 打开Excel文件
|
||||
1. 利用 Adobe PDF Reader 打开PDF文件(前提先装PDF软件)
|
||||
1. 利用 `Word.Application` 打开Word文件
|
||||
1. 利用 `Excel.Application` 打开Excel文件
|
||||
1. 利用 `Adobe PDF Reader` 打开PDF文件(前提先装PDF软件)
|
||||
|
||||
![截图](ScreenShot/显示word_excel_pdf.png)
|
54
动画/README.md
|
@ -1,10 +1,52 @@
|
|||
# 简单的动画特效
|
||||
# 动画特效
|
||||
|
||||
使用QPropertyAnimation属性类动画(支持的属性有限)
|
||||
|
||||
### 常见例子
|
||||
- [1.1 淡入淡出](淡入淡出.py)<br/>
|
||||
![截图](ScreenShot/1.gif)
|
||||
## [1、窗口淡入淡出](窗口淡入淡出.py)
|
||||
|
||||
- [1.2 右键菜单动画](右键菜单动画.py)<br/>
|
||||
![截图](ScreenShot/2.gif)
|
||||
1. 使用`QPropertyAnimation`对窗口的`windowOpacity`透明度属性进行修改
|
||||
1. 窗口启动时开启透明度0-->1的动画
|
||||
1. 尝试先取消动画完成后关闭窗口的信号(使用同一个动画对象,在关闭窗口动画的时候连接了动画结束后关闭窗口的信号)
|
||||
1. 停止旧动画开启新动画
|
||||
1. 窗口关闭时开启透明度1-->0的动画
|
||||
1. 停止就动画
|
||||
1. 绑定动画完成后`finished`信号连接到`close`关闭窗口函数
|
||||
|
||||
![截图](ScreenShot/窗口淡入淡出.gif)
|
||||
|
||||
## [2、右键菜单动画](右键菜单动画.py)
|
||||
|
||||
1. 使用`QPropertyAnimation`对菜单控件的`geometry`属性进行修改
|
||||
1. 当菜单事件`contextMenuEvent`触发时调用动画启动,同时显示菜单
|
||||
|
||||
![截图](ScreenShot/右键菜单动画.gif)
|
||||
|
||||
## [3、按钮放大缩小动画](按钮放大缩小动画.py)
|
||||
|
||||
1. 使用`QPropertyAnimation`对按钮的`geometry`属性进行修改
|
||||
1. 针对按钮在布局中或者没有在布局中两种情况,需要对主窗口的`showEvent`和`resizeEvent`两个事件进行重写,从而达到更新按钮的最新`geometry`值
|
||||
1. 主动调用按钮的`updatePos`函数来更新`geometry`值
|
||||
|
||||
比如:
|
||||
|
||||
```python
|
||||
def showEvent(self, event):
|
||||
super(TestWindow, self).showEvent(event)
|
||||
# 更新按钮的位置
|
||||
self.button1.updatePos()
|
||||
# 针对不在控件中的按钮
|
||||
self.button2.move(self.width() - self.button2.width() - 15,
|
||||
self.height() - self.button2.height() - 10)
|
||||
self.button2.updatePos()
|
||||
|
||||
def resizeEvent(self, event):
|
||||
super(TestWindow, self).resizeEvent(event)
|
||||
# 更新按钮的位置
|
||||
self.button1.updatePos()
|
||||
# 针对不在控件中的按钮
|
||||
self.button2.move(self.width() - self.button2.width() - 15,
|
||||
self.height() - self.button2.height() - 10)
|
||||
self.button2.updatePos()
|
||||
```
|
||||
|
||||
![截图](ScreenShot/按钮放大缩小动画.gif)
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
BIN
动画/ScreenShot/按钮放大缩小动画.gif
Normal file
After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 630 KiB After Width: | Height: | Size: 630 KiB |
|
@ -92,7 +92,7 @@ class TestWindow(QWidget):
|
|||
super(TestWindow, self).showEvent(event)
|
||||
# 更新按钮的位置
|
||||
self.button1.updatePos()
|
||||
|
||||
# 针对不在控件中的按钮
|
||||
self.button2.move(self.width() - self.button2.width() - 15,
|
||||
self.height() - self.button2.height() - 10)
|
||||
self.button2.updatePos()
|
||||
|
@ -101,7 +101,7 @@ class TestWindow(QWidget):
|
|||
super(TestWindow, self).resizeEvent(event)
|
||||
# 更新按钮的位置
|
||||
self.button1.updatePos()
|
||||
|
||||
# 针对不在控件中的按钮
|
||||
self.button2.move(self.width() - self.button2.width() - 15,
|
||||
self.height() - self.button2.height() - 10)
|
||||
self.button2.updatePos()
|
||||
|
|
|
@ -34,6 +34,7 @@ class Window(QWidget):
|
|||
|
||||
def doShow(self):
|
||||
try:
|
||||
# 尝试先取消动画完成后关闭窗口的信号
|
||||
self.animation.finished.disconnect(self.close)
|
||||
except:
|
||||
pass
|
19
多线程/README.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
# 多线程
|
||||
|
||||
PyQt多线程的简单使用例子
|
||||
|
||||
## [1、继承QThread](继承QThread.py)
|
||||
|
||||
## [2、moveToThread](moveToThread.py)
|
||||
|
||||
## [3、线程挂起恢复](线程挂起恢复.py)
|
||||
|
||||
注意,这里只是简单演示,在应用这些代码时要小心
|
||||
|
||||
1. 这里使用windows的api实现,主要用到`SuspendThread`和`ResumeThread`函数
|
||||
1. 利用`ctypes.windll.kernel32.OpenThread(win32con.PROCESS_ALL_ACCESS, False, int(QThread.currentThreadId()))`
|
||||
1. 得到线程的句柄,然后就可以通过上面的两个函数对其进行挂起与恢复
|
||||
|
||||
`ctypes.windll.kernel32.TerminateThread`终止线程,不推荐
|
||||
|
||||
![截图](ScreenShot/线程挂起恢复.gif)
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
|
@ -1,16 +0,0 @@
|
|||
# 简单的子线程例子
|
||||
|
||||
使用继承QThread和moveToThread两种方式
|
||||
|
||||
# 注意,这里只是简单演示,在应用这些代码时要小心
|
||||
## 线程的挂起与恢复
|
||||
这里使用windows的api实现,主要用到SuspendThread和ResumeThread函数
|
||||
|
||||
利用ctypes.windll.kernel32.OpenThread(win32con.PROCESS_ALL_ACCESS, False, int(QThread.currentThreadId()))
|
||||
|
||||
得到线程的句柄,然后就可以通过上面的两个函数对其进行挂起与恢复
|
||||
|
||||
ctypes.windll.kernel32.TerminateThread终止线程,不推荐
|
||||
|
||||
## 截图
|
||||
![截图](ScreenShot/1.gif)
|
42
窗口/README.md
|
@ -8,10 +8,10 @@
|
|||
|
||||
## [2、分割窗口的分割条重绘](分割窗口的分割条重写.py)
|
||||
|
||||
1. 原理在于QSplitter在创建分割条的时候会调用createHandle函数
|
||||
1. 通过重新写createHandle返回自己的QSplitterHandle类
|
||||
1. 通过QSplitterHandle的paintEvent实现绘制其它形状,
|
||||
1. 重写mousePressEvent和mouseMoveEvent来实现鼠标的其它事件
|
||||
1. 原理在于`QSplitter`在创建分割条的时候会调用`createHandle`函数
|
||||
1. 通过重新写`createHandle`返回自己的`QSplitterHandle`类
|
||||
1. 通过`QSplitterHandle`的`paintEvent`实现绘制其它形状,
|
||||
1. 重写`mousePressEvent`和`mouseMoveEvent`来实现鼠标的其它事件
|
||||
|
||||
![截图](ScreenShot/分割窗口的分割条重写.gif)
|
||||
|
||||
|
@ -24,17 +24,17 @@
|
|||
1. 如果窗口的x坐标大于屏幕宽度-窗口宽度/2 则需要隐藏到右边
|
||||
|
||||
2. 事件说明
|
||||
1. mousePressEvent,鼠标按下事件,主要记录按下的坐标
|
||||
1. mouseMoveEvent,鼠标移动事件,用于移动窗口
|
||||
1. mouseReleaseEvent,鼠标弹起事件,用于判断是否需要隐藏窗口
|
||||
1. enterEvent,鼠标进入事件,用于窗口隐藏后,是否需要暂时显示预览
|
||||
1. leaveEvent,鼠标离开事件,用于窗口暂时显示后自动隐藏效果
|
||||
1. `mousePressEvent`,鼠标按下事件,主要记录按下的坐标
|
||||
1. `mouseMoveEvent`,鼠标移动事件,用于移动窗口
|
||||
1. `mouseReleaseEvent`,鼠标弹起事件,用于判断是否需要隐藏窗口
|
||||
1. `enterEvent`,鼠标进入事件,用于窗口隐藏后,是否需要暂时显示预览
|
||||
1. `leaveEvent`,鼠标离开事件,用于窗口暂时显示后自动隐藏效果
|
||||
|
||||
## [4、嵌入外部窗口](嵌入外部窗口.py)
|
||||
|
||||
1. 使用SetParent函数设置外部窗口的parent为Qt的窗口
|
||||
1. Qt使用QWidget.createWindowContainer(QWindow.fromWinId(窗口ID))生成QWidget
|
||||
1. 使用GetWindowLong得到原来窗口的样式属性(style = win32gui.GetWindowLong(hwnd, win32con.GWL_STYLE)和exstyle = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE))
|
||||
1. 使用`SetParent`函数设置外部窗口的`parent`为Qt的窗口
|
||||
1. Qt使用`QWidget.createWindowContainer(QWindow.fromWinId(窗口ID))`生成QWidget
|
||||
1. 使用`GetWindowLong`得到原来窗口的样式属性`style = win32gui.GetWindowLong(hwnd, win32con.GWL_STYLE)`和`exstyle = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)`
|
||||
1. 这里还原窗口后不会显示,用spy++发现没有了WS_VISIBLE样式(未解决)
|
||||
|
||||
![截图](ScreenShot/嵌入外部窗口.gif)
|
||||
|
@ -52,7 +52,7 @@
|
|||
|
||||
## [6、简单探测窗口和放大截图](简单探测窗口和放大截图.py)
|
||||
|
||||
1. 利用win32gui模块获取鼠标所在位置的窗口大小(未去掉边框)和rgb颜色
|
||||
1. 利用`win32gui`模块获取鼠标所在位置的窗口大小(未去掉边框)和rgb颜色
|
||||
1. 利用一个全屏的全透明鼠标穿透的窗口(目的在于绘制矩形框和截图)
|
||||
|
||||
![截图](ScreenShot/简单探测窗口和放大截图.gif)
|
||||
|
@ -60,8 +60,8 @@
|
|||
|
||||
## [7、消息对话框倒计时关闭](消息对话框倒计时关闭.py)
|
||||
|
||||
1. 通过继承QMessageBox实现倒计时关闭的对话框
|
||||
1. QTimer定时器关闭窗口
|
||||
1. 通过继承`QMessageBox`实现倒计时关闭的对话框
|
||||
1. `QTimer`定时器关闭窗口
|
||||
|
||||
![截图](ScreenShot/消息对话框倒计时关闭.gif)
|
||||
|
||||
|
@ -69,17 +69,17 @@
|
|||
|
||||
1. 方式一(QWidget)
|
||||
|
||||
1. 使用一个QWidget(FramelessWindow)作为父窗口, 一个TitleBar作为标题栏, 一个QWidget作为底部容器
|
||||
1. 父窗口FramelessWindow设置为背景透明,但是需要绘制一定宽度的透明度很高的矩形边框用来接受鼠标事件(变形鼠标样式进行调整窗口大小)
|
||||
1. TitleBar的最小化最大化关闭等按钮事件关联到父窗口里
|
||||
1. TitleBar中的鼠标按下移动事件得到坐标也传递到父窗口调用move方法进行窗口移动
|
||||
1. 使用一个`QWidget`(`FramelessWindow`)作为父窗口, 一个`TitleBar`作为标题栏, 一个`QWidget`作为底部容器
|
||||
1. 父窗口`FramelessWindow`设置为背景透明,但是需要绘制一定宽度的透明度很高的矩形边框用来接受鼠标事件(变形鼠标样式进行调整窗口大小)
|
||||
1. `TitleBar`的最小化最大化关闭等按钮事件关联到父窗口里
|
||||
1. `TitleBar`中的鼠标按下移动事件得到坐标也传递到父窗口调用move方法进行窗口移动
|
||||
|
||||
![截图](ScreenShot/无边框自定义标题栏窗口/无边框自定义标题栏窗口.gif)
|
||||
|
||||
1. 方式二(windows api)
|
||||
|
||||
1. 使用win32gui设置薄边框
|
||||
1. 重写nativeEvent事件拦截边框的系统边框的显示,并返回各个方向
|
||||
1. 使用`win32gui`设置薄边框
|
||||
1. 重写`nativeEvent`事件拦截边框的系统边框的显示,并返回各个方向
|
||||
|
||||
## 截图
|
||||
![截图](ScreenShot/无边框自定义标题栏窗口/win无边框调整大小1.jpg)
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
|
||||
原理:
|
||||
|
||||
1. 设置菜单项可勾选:通过QAction.setCheckable(True)方法实现
|
||||
1. 设置菜单不可关闭:通过覆盖QMenu的鼠标释放mouseReleaseEvent方法(可直接替换或者通过installEventFilter安装事件过滤器实现)
|
||||
1. 在菜单的鼠标释放事件中,当点击菜单项后是通过点击点坐标来查找是否有QAction,然后触发对应的QAction。<br/>
|
||||
1. 故在没有QAction的地方则直接交还给QMenu自行处理逻辑,在有QAction的地方可以根据自己的需求进行处理(如上所提)
|
||||
1. 设置菜单项可勾选:通过`QAction.setCheckable(True)`方法实现
|
||||
1. 设置菜单不可关闭:通过覆盖`QMenu`的鼠标释放`mouseReleaseEvent`方法(可直接替换或者通过`installEventFilter`安装事件过滤器实现)
|
||||
1. 在菜单的鼠标释放事件中,当点击菜单项后是通过点击点坐标来查找是否有`QAction`,然后触发对应的`QAction`
|
||||
1. 故在没有`QAction`的地方则直接交还给`QMenu`自行处理逻辑,在有`QAction`的地方可以根据自己的需求进行处理(如上所提)
|
||||
|
||||
核心代码:
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
## [1、表格内容复制](表格内容复制.py)
|
||||
|
||||
1. 通过构造一个和选中区域一样的空数组,然后对数组进行填充形成表格
|
||||
1. 最后循环数组用\t进行拼接join,换行用\r\n
|
||||
1. 最后循环数组用`\t`进行拼接`join`,换行用`\r\n`
|
||||
1. 把字符串复制到剪切板中
|
||||
|
||||
![截图](ScreenShot/表格内容复制1.png)![截图](ScreenShot/表格内容复制2.png)
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
[1、Sqlalchemy动态拼接字段查询显示表格](数据库查询显示表格)
|
||||
|
||||
通过判断界面中选择的条件对Sqlalchemy的model进行字段拼接从而实现按条件查询
|
||||
通过判断界面中选择的条件对`Sqlalchemy`的`model`进行字段拼接从而实现按条件查询
|
||||
|
||||
![截图](数据库查询显示表格/ScreenShot/数据库查询显示表格.png)
|