更新子目录Readme
|
@ -1,5 +1,5 @@
|
||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
encoding//ActiveX/QAxWidget/\u663E\u793Aword_excel_pdf.py=utf-8
|
encoding//ActiveX/\u663E\u793Aword_excel_pdf.py=utf-8
|
||||||
encoding//\u4E0B\u62C9\u6846/\u4E0B\u62C9\u9009\u62E9\u8054\u52A8/ComboBox.py=utf-8
|
encoding//\u4E0B\u62C9\u6846/\u4E0B\u62C9\u9009\u62E9\u8054\u52A8/ComboBox.py=utf-8
|
||||||
encoding//\u5176\u5B83/C\u548CC++\u6269\u5C55/py\u8F6Cpyd/pydmod.py=utf-8
|
encoding//\u5176\u5B83/C\u548CC++\u6269\u5C55/py\u8F6Cpyd/pydmod.py=utf-8
|
||||||
encoding//\u5176\u5B83/QRC\u8D44\u6E90\u6587\u4EF6\u4F7F\u7528/qrctest1.py=utf-8
|
encoding//\u5176\u5B83/QRC\u8D44\u6E90\u6587\u4EF6\u4F7F\u7528/qrctest1.py=utf-8
|
||||||
|
@ -88,13 +88,16 @@ encoding//\u754C\u9762\u7F8E\u5316/\u6C34\u6CE2\u7EB9\u8FDB\u5EA6\u6761/Progress
|
||||||
encoding//\u754C\u9762\u7F8E\u5316/\u6C34\u6CE2\u7EB9\u8FDB\u5EA6\u6761/TestWidget.py=utf-8
|
encoding//\u754C\u9762\u7F8E\u5316/\u6C34\u6CE2\u7EB9\u8FDB\u5EA6\u6761/TestWidget.py=utf-8
|
||||||
encoding//\u754C\u9762\u7F8E\u5316/\u8FB9\u6846\u52A8\u753B\u9634\u5F71/AnimationShadowEffect.py=utf-8
|
encoding//\u754C\u9762\u7F8E\u5316/\u8FB9\u6846\u52A8\u753B\u9634\u5F71/AnimationShadowEffect.py=utf-8
|
||||||
encoding//\u754C\u9762\u7F8E\u5316/\u8FB9\u6846\u52A8\u753B\u9634\u5F71/Test.py=utf-8
|
encoding//\u754C\u9762\u7F8E\u5316/\u8FB9\u6846\u52A8\u753B\u9634\u5F71/Test.py=utf-8
|
||||||
|
encoding//\u7A97\u53E3/\u5206\u5272\u7A97\u53E3\u7684\u5206\u5272\u6761\u91CD\u5199.py=utf-8
|
||||||
encoding//\u7A97\u53E3/\u65E0\u8FB9\u6846\u81EA\u5B9A\u4E49\u6807\u9898\u680F\u7A97\u53E3/FramelessWindow.py=utf-8
|
encoding//\u7A97\u53E3/\u65E0\u8FB9\u6846\u81EA\u5B9A\u4E49\u6807\u9898\u680F\u7A97\u53E3/FramelessWindow.py=utf-8
|
||||||
encoding//\u7A97\u53E3/\u65E0\u8FB9\u6846\u81EA\u5B9A\u4E49\u6807\u9898\u680F\u7A97\u53E3/Test.py=utf-8
|
|
||||||
encoding//\u7A97\u53E3/\u65E0\u8FB9\u6846\u81EA\u5B9A\u4E49\u6807\u9898\u680F\u7A97\u53E3/win\u65E0\u8FB9\u6846\u8C03\u6574\u5927\u5C0F.py=utf-8
|
encoding//\u7A97\u53E3/\u65E0\u8FB9\u6846\u81EA\u5B9A\u4E49\u6807\u9898\u680F\u7A97\u53E3/win\u65E0\u8FB9\u6846\u8C03\u6574\u5927\u5C0F.py=utf-8
|
||||||
|
encoding//\u7A97\u53E3/\u65E0\u8FB9\u6846\u81EA\u5B9A\u4E49\u6807\u9898\u680F\u7A97\u53E3/\u65E0\u8FB9\u6846\u81EA\u5B9A\u4E49\u6807\u9898\u680F\u7A97\u53E3.py=utf-8
|
||||||
encoding//\u7A97\u53E3/\u6D88\u606F\u5BF9\u8BDD\u6846\u5012\u8BA1\u65F6\u5173\u95ED.py=utf-8
|
encoding//\u7A97\u53E3/\u6D88\u606F\u5BF9\u8BDD\u6846\u5012\u8BA1\u65F6\u5173\u95ED.py=utf-8
|
||||||
|
encoding//\u7A97\u53E3/\u7A97\u53E3\u91CD\u542F.py=utf-8
|
||||||
encoding//\u7F8E\u5316/\u81EA\u5B9A\u4E49QWidget\u7684QSS\u6837\u5F0F/CustomPaintWidget.py=utf-8
|
encoding//\u7F8E\u5316/\u81EA\u5B9A\u4E49QWidget\u7684QSS\u6837\u5F0F/CustomPaintWidget.py=utf-8
|
||||||
encoding//\u7F8E\u5316/\u81EA\u5B9A\u4E49QWidget\u7684QSS\u6837\u5F0F/CustomWidget.py=utf-8
|
encoding//\u7F8E\u5316/\u81EA\u5B9A\u4E49QWidget\u7684QSS\u6837\u5F0F/CustomWidget.py=utf-8
|
||||||
encoding//\u7F8E\u5316/\u81EA\u5B9A\u4E49QWidget\u7684QSS\u6837\u5F0F/test.py=utf-8
|
encoding//\u7F8E\u5316/\u81EA\u5B9A\u4E49QWidget\u7684QSS\u6837\u5F0F/test.py=utf-8
|
||||||
encoding//\u83DC\u5355/\u83DC\u5355\u591A\u9009\u4E0D\u5173\u95ED.py=utf-8
|
encoding//\u83DC\u5355/\u83DC\u5355\u591A\u9009\u4E0D\u5173\u95ED.py=utf-8
|
||||||
|
encoding//\u8868\u683C/QTableView/\u8868\u683C\u5185\u5BB9\u590D\u5236.py=utf-8
|
||||||
encoding//\u8868\u683C/QTableWidget/\u6570\u636E\u5E93\u67E5\u8BE2\u663E\u793A\u8868\u683C/main.py=utf-8
|
encoding//\u8868\u683C/QTableWidget/\u6570\u636E\u5E93\u67E5\u8BE2\u663E\u793A\u8868\u683C/main.py=utf-8
|
||||||
encoding//\u8868\u683C/QTableWidget/\u6570\u636E\u5E93\u67E5\u8BE2\u663E\u793A\u8868\u683C/mainui.py=utf-8
|
encoding//\u8868\u683C/QTableWidget/\u6570\u636E\u5E93\u67E5\u8BE2\u663E\u793A\u8868\u683C/mainui.py=utf-8
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
# 嗯嗯,就是简单的测试ActiveX控件
|
|
||||||
|
|
||||||
### [Python3.4.4 or Python3.5][PyQt5]
|
|
||||||
|
|
||||||
显示Word、Excel、PDF文件(前提先装PDF软件)
|
|
||||||
|
|
||||||
# 截图
|
|
||||||
![截图1](ScreenShot/excel.png)
|
|
9
ActiveX/README.md
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# ActiveX控件
|
||||||
|
|
||||||
|
## [1、显示Word、Excel、PDF文件](显示word_excel_pdf.py)
|
||||||
|
|
||||||
|
1. 利用 Word.Application 打开Word文件
|
||||||
|
1. 利用 Excel.Application 打开Excel文件
|
||||||
|
1. 利用 Adobe PDF Reader 打开PDF文件(前提先装PDF软件)
|
||||||
|
|
||||||
|
![截图](ScreenShot/显示word_excel_pdf.png)
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
115
窗口/README.md
|
@ -1,80 +1,89 @@
|
||||||
# 重启窗口Widget
|
# 窗口案例
|
||||||
|
|
||||||
|
## [1、重启窗口Widget](窗口重启.py)
|
||||||
|
|
||||||
|
利用类变量对窗口的变量进行引用,防止被回收(导致窗口一闪而过),重启时先显示新窗口后关闭自己
|
||||||
|
|
||||||
# 截图
|
|
||||||
![截图](ScreenShot/窗口重启.gif)
|
![截图](ScreenShot/窗口重启.gif)
|
||||||
|
|
||||||
|
## [2、分割窗口的分割条重绘](分割窗口的分割条重写.py)
|
||||||
|
|
||||||
|
1. 原理在于QSplitter在创建分割条的时候会调用createHandle函数
|
||||||
|
1. 通过重新写createHandle返回自己的QSplitterHandle类
|
||||||
|
1. 通过QSplitterHandle的paintEvent实现绘制其它形状,
|
||||||
|
1. 重写mousePressEvent和mouseMoveEvent来实现鼠标的其它事件
|
||||||
|
|
||||||
# 分割窗口的分割条重绘
|
|
||||||
|
|
||||||
原理在于QSplitter在创建分割条的时候会调用createHandle函数
|
|
||||||
|
|
||||||
于是通过重新写createHandle返回自己的QSplitterHandle类
|
|
||||||
|
|
||||||
并通过QSplitterHandle的paintEvent实现绘制其它形状,
|
|
||||||
重写mousePressEvent和mouseMoveEvent来实现鼠标的其它事件
|
|
||||||
|
|
||||||
## 截图
|
|
||||||
![截图](ScreenShot/分割窗口的分割条重写.gif)
|
![截图](ScreenShot/分割窗口的分割条重写.gif)
|
||||||
|
|
||||||
|
## [3、简单的窗口贴边隐藏](简单的窗口贴边隐藏.py)
|
||||||
|
|
||||||
# 简单的窗口贴边隐藏
|
1. 大概思路
|
||||||
|
1. 思路是当窗口进入左边,顶部,右边一半时,此时判断窗口的坐标
|
||||||
|
1. 如果窗口的x坐标小于0 则需要隐藏到左边
|
||||||
|
1. 如果窗口的y坐标小于0 则需要隐藏到顶部
|
||||||
|
1. 如果窗口的x坐标大于屏幕宽度-窗口宽度/2 则需要隐藏到右边
|
||||||
|
|
||||||
## 大概思路
|
2. 事件说明
|
||||||
- 1.思路是当窗口进入左边,顶部,右边一半时,此时判断窗口的坐标
|
1. mousePressEvent,鼠标按下事件,主要记录按下的坐标
|
||||||
- 2.如果窗口的x坐标小于0 则需要隐藏到左边
|
1. mouseMoveEvent,鼠标移动事件,用于移动窗口
|
||||||
- 3.如果窗口的y坐标小于0 则需要隐藏到顶部
|
1. mouseReleaseEvent,鼠标弹起事件,用于判断是否需要隐藏窗口
|
||||||
- 4.如果窗口的x坐标大于屏幕宽度-窗口宽度/2 则需要隐藏到右边
|
1. enterEvent,鼠标进入事件,用于窗口隐藏后,是否需要暂时显示预览
|
||||||
|
1. leaveEvent,鼠标离开事件,用于窗口暂时显示后自动隐藏效果
|
||||||
|
|
||||||
## 事件
|
## [4、嵌入外部窗口](嵌入外部窗口.py)
|
||||||
- 1.mousePressEvent,鼠标按下事件,主要记录按下的坐标
|
|
||||||
- 1.mouseMoveEvent,鼠标移动事件,用于移动窗口
|
1. 使用SetParent函数设置外部窗口的parent为Qt的窗口
|
||||||
- 1.mouseReleaseEvent,鼠标弹起事件,用于判断是否需要隐藏窗口
|
1. Qt使用QWidget.createWindowContainer(QWindow.fromWinId(窗口ID))生成QWidget
|
||||||
- 1.enterEvent,鼠标进入事件,用于窗口隐藏后,是否需要暂时显示预览
|
1. 使用GetWindowLong得到原来窗口的样式属性(style = win32gui.GetWindowLong(hwnd, win32con.GWL_STYLE)和exstyle = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE))
|
||||||
- 1.leaveEvent,鼠标离开事件,用于窗口暂时显示后自动隐藏效果
|
1. 这里还原窗口后不会显示,用spy++发现没有了WS_VISIBLE样式(未解决)
|
||||||
|
|
||||||
|
![截图](ScreenShot/嵌入外部窗口.gif)
|
||||||
|
|
||||||
|
|
||||||
|
## [5、简单跟随其它窗口](外部窗口跟随.py)
|
||||||
|
|
||||||
# 内嵌外部窗口
|
1. 利用win32gui模块获取目标窗口的句柄
|
||||||
|
1. 通过句柄获取目标窗口的大小位置,并设置自己的位置
|
||||||
|
1. 当句柄失效时关闭自己
|
||||||
|
1. 主要是检测时间,在10毫秒以下很流畅
|
||||||
|
|
||||||
### 原理思路:
|
![截图](ScreenShot/外部窗口跟随.gif)
|
||||||
- 1.使用SetParent函数设置外部窗口的parent为Qt的窗口
|
|
||||||
- 2.Qt使用QWidget.createWindowContainer(QWindow.fromWinId(窗口ID))生成QWidget
|
|
||||||
- 3.使用GetWindowLong得到原来窗口的样式属性(style = win32gui.GetWindowLong(hwnd, win32con.GWL_STYLE)和exstyle = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE))
|
|
||||||
- 4.这里还原窗口后不会显示,用spy++发现没有了WS_VISIBLE样式(未解决)
|
|
||||||
|
|
||||||
截图
|
|
||||||
|
|
||||||
![1](ScreenShot/嵌入外部窗口.gif)
|
|
||||||
|
|
||||||
|
|
||||||
# 简单跟随其它窗口
|
## [6、简单探测窗口和放大截图](简单探测窗口和放大截图.py)
|
||||||
|
|
||||||
1、利用win32gui模块获取目标窗口的句柄
|
1. 利用win32gui模块获取鼠标所在位置的窗口大小(未去掉边框)和rgb颜色
|
||||||
|
1. 利用一个全屏的全透明鼠标穿透的窗口(目的在于绘制矩形框和截图)
|
||||||
|
|
||||||
2、通过句柄获取目标窗口的大小位置,并设置自己的位置
|
![截图](ScreenShot/简单探测窗口和放大截图.gif)
|
||||||
|
|
||||||
3、当句柄失效时关闭自己
|
|
||||||
|
|
||||||
4、主要是检测时间,在10毫秒以下很流畅
|
|
||||||
|
|
||||||
截图
|
|
||||||
|
|
||||||
![1](ScreenShot/外部窗口跟随.gif)
|
|
||||||
|
|
||||||
|
|
||||||
# 简单探测窗口和放大截图
|
## [7、消息对话框倒计时关闭](消息对话框倒计时关闭.py)
|
||||||
|
|
||||||
利用win32gui模块获取鼠标所在位置的窗口大小(未去掉边框)和rgb颜色, 主要思路是利用一个全屏的全透明鼠标穿透的窗口(目的在于绘制矩形框和截图)
|
1. 通过继承QMessageBox实现倒计时关闭的对话框
|
||||||
|
1. QTimer定时器关闭窗口
|
||||||
|
|
||||||
截图
|
![截图](ScreenShot/消息对话框倒计时关闭.gif)
|
||||||
|
|
||||||
![1](ScreenShot/1.gif)
|
## [8、无边框自定义标题栏窗口](无边框自定义标题栏窗口/)
|
||||||
|
|
||||||
|
1. 方式一(QWidget)
|
||||||
|
|
||||||
# 消息对话框倒计时关闭
|
1. 使用一个QWidget(FramelessWindow)作为父窗口, 一个TitleBar作为标题栏, 一个QWidget作为底部容器
|
||||||
|
1. 父窗口FramelessWindow设置为背景透明,但是需要绘制一定宽度的透明度很高的矩形边框用来接受鼠标事件(变形鼠标样式进行调整窗口大小)
|
||||||
|
1. TitleBar的最小化最大化关闭等按钮事件关联到父窗口里
|
||||||
|
1. TitleBar中的鼠标按下移动事件得到坐标也传递到父窗口调用move方法进行窗口移动
|
||||||
|
|
||||||
通过继承QMessageBox实现倒计时关闭的对话框
|
![截图](ScreenShot/无边框自定义标题栏窗口/无边框自定义标题栏窗口.gif)
|
||||||
|
|
||||||
# 截图
|
1. 方式二(windows api)
|
||||||
![截图1](ScreenShot/1.gif)
|
|
||||||
|
1. 使用win32gui设置薄边框
|
||||||
|
1. 重写nativeEvent事件拦截边框的系统边框的显示,并返回各个方向
|
||||||
|
|
||||||
|
## 截图
|
||||||
|
![截图](ScreenShot/无边框自定义标题栏窗口/win无边框调整大小1.jpg)
|
||||||
|
|
||||||
|
![截图](ScreenShot/无边框自定义标题栏窗口/win无边框调整大小2.jpg)
|
||||||
|
|
||||||
|
![截图](ScreenShot/无边框自定义标题栏窗口/win无边框调整大小3.gif)
|
|
@ -149,7 +149,7 @@ class FramelessWindow(QWidget):
|
||||||
# 背景透明
|
# 背景透明
|
||||||
self.setAttribute(Qt.WA_TranslucentBackground, True)
|
self.setAttribute(Qt.WA_TranslucentBackground, True)
|
||||||
# 无边框
|
# 无边框
|
||||||
self.setWindowFlag(Qt.FramelessWindowHint)
|
self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint)
|
||||||
# 鼠标跟踪
|
# 鼠标跟踪
|
||||||
self.setMouseTracking(True)
|
self.setMouseTracking(True)
|
||||||
# 布局
|
# 布局
|
||||||
|
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 101 KiB |
Before Width: | Height: | Size: 235 KiB After Width: | Height: | Size: 235 KiB |
Before Width: | Height: | Size: 3.2 MiB After Width: | Height: | Size: 3.2 MiB |
32
菜单/README.md
|
@ -1,27 +1,24 @@
|
||||||
# 菜单设置多选并且不关闭
|
# 菜单 QMenu
|
||||||
|
|
||||||
### [Python3.4.4 or Python3.5][PyQt5]
|
## [1、菜单设置多选并且不关闭](菜单多选不关闭.py)
|
||||||
|
|
||||||
有时候会遇到这种需求:在界面某个位置弹出一个菜单,其中里面的菜单项可以多选(类似配置选项),
|
有时候会遇到这种需求:在界面某个位置弹出一个菜单,其中里面的菜单项可以多选(类似配置选项),
|
||||||
此时用QMenu会遇到点击一个菜单项就会自动关闭,当然可以通过其他方式实现该功能,
|
此时用QMenu会遇到点击一个菜单项就会自动关闭,当然可以通过其他方式实现该功能,
|
||||||
不过这里就采用QMenu通过特殊的方式来实现该需求。
|
不过这里就采用QMenu通过特殊的方式来实现该需求。
|
||||||
|
|
||||||
需求:<br/>
|
需求:显示4个菜单(菜单1、菜单2、菜单3、菜单4),
|
||||||
菜单1<br/>
|
其中点击菜单1、2、3可以多选不关闭菜单,
|
||||||
菜单2<br/>
|
|
||||||
菜单3<br/>
|
|
||||||
菜单4<br/>
|
|
||||||
|
|
||||||
点击菜单1、2、3可以多选不关闭菜单<br/>
|
|
||||||
点击菜单4可以勾选,并且关闭菜单
|
点击菜单4可以勾选,并且关闭菜单
|
||||||
|
|
||||||
知识点:<br/>
|
原理:
|
||||||
1、设置菜单项可勾选:通过QAction.setCheckable(True)方法实现<br/>
|
|
||||||
2、设置菜单不可关闭:通过覆盖QMenu的鼠标释放mouseReleaseEvent方法(可直接替换或者通过installEventFilter安装事件过滤器实现)<br/>
|
1. 设置菜单项可勾选:通过QAction.setCheckable(True)方法实现
|
||||||
3、在菜单的鼠标释放事件中,当点击菜单项后是通过点击点坐标来查找是否有QAction,然后触发对应的QAction。<br/>
|
1. 设置菜单不可关闭:通过覆盖QMenu的鼠标释放mouseReleaseEvent方法(可直接替换或者通过installEventFilter安装事件过滤器实现)
|
||||||
4、故在没有QAction的地方则直接交还给QMenu自行处理逻辑,在有QAction的地方可以根据自己的需求进行处理(如上所提)
|
1. 在菜单的鼠标释放事件中,当点击菜单项后是通过点击点坐标来查找是否有QAction,然后触发对应的QAction。<br/>
|
||||||
|
1. 故在没有QAction的地方则直接交还给QMenu自行处理逻辑,在有QAction的地方可以根据自己的需求进行处理(如上所提)
|
||||||
|
|
||||||
|
核心代码:
|
||||||
|
|
||||||
核心代码:<br/>
|
|
||||||
```python
|
```python
|
||||||
def _menu_mouseReleaseEvent(self, event):
|
def _menu_mouseReleaseEvent(self, event):
|
||||||
action = self._menu.actionAt(event.pos())
|
action = self._menu.actionAt(event.pos())
|
||||||
|
@ -34,5 +31,6 @@ def _menu_mouseReleaseEvent(self, event):
|
||||||
action.activate(action.Trigger)
|
action.activate(action.Trigger)
|
||||||
```
|
```
|
||||||
|
|
||||||
# 截图
|
效果图:
|
||||||
![截图1](ScreenShot/1.gif)
|
|
||||||
|
![截图](ScreenShot/菜单多选不关闭.gif)
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 136 KiB |
|
@ -1,6 +1,10 @@
|
||||||
# 表格控件案例
|
# 表格控件 QTableView
|
||||||
|
|
||||||
1. [表格内容复制](表格内容复制.py)
|
## [1、表格内容复制](表格内容复制.py)
|
||||||
|
|
||||||
![截图1](ScreenShot/1.png)![截图2](ScreenShot/2.png)
|
1. 通过构造一个和选中区域一样的空数组,然后对数组进行填充形成表格
|
||||||
|
1. 最后循环数组用\t进行拼接join,换行用\r\n
|
||||||
|
1. 把字符串复制到剪切板中
|
||||||
|
|
||||||
|
![截图](ScreenShot/表格内容复制1.png)![截图](ScreenShot/表格内容复制2.png)
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
7
表格/QTableWidget/README.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# 表格控件 QTableWidget
|
||||||
|
|
||||||
|
[1、Sqlalchemy动态拼接字段查询显示表格](数据库查询显示表格)
|
||||||
|
|
||||||
|
通过判断界面中选择的条件对Sqlalchemy的model进行字段拼接从而实现按条件查询
|
||||||
|
|
||||||
|
![截图](数据库查询显示表格/ScreenShot/数据库查询显示表格.png)
|
|
@ -1,5 +0,0 @@
|
||||||
# sqlalchemy动态拼接字段查询结果
|
|
||||||
|
|
||||||
截图
|
|
||||||
|
|
||||||
![1](ScreenShot/1.png)
|
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |