update
|
@ -1,3 +0,0 @@
|
||||||
微信 支付宝
|
|
||||||
<br/>
|
|
||||||
<a href="weixin.png" alt="微信"><img src="weixin.png" height="350" width="350"></a>or<a href="zhifubao.png" alt="支付宝"><img src="zhifubao.png" height="350" width="350"></a>
|
|
|
@ -6,7 +6,7 @@ Created on 2018年10月24日
|
||||||
@author: Irony
|
@author: Irony
|
||||||
@site: https://github.com/892768447
|
@site: https://github.com/892768447
|
||||||
@email: 892768447@qq.com
|
@email: 892768447@qq.com
|
||||||
@file: 菜单多选不关闭
|
@file: MultiSelect
|
||||||
@description:
|
@description:
|
||||||
"""
|
"""
|
||||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton, QMenu,\
|
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton, QMenu,\
|
|
@ -1,6 +1,7 @@
|
||||||
# 菜单 QMenu
|
# QMenu
|
||||||
|
|
||||||
## [1、菜单设置多选并且不关闭](菜单多选不关闭.py)
|
## 1、菜单设置多选并且不关闭
|
||||||
|
[运行 MultiSelect.py](MultiSelect.py)
|
||||||
|
|
||||||
有时候会遇到这种需求:在界面某个位置弹出一个菜单,其中里面的菜单项可以多选(类似配置选项),
|
有时候会遇到这种需求:在界面某个位置弹出一个菜单,其中里面的菜单项可以多选(类似配置选项),
|
||||||
此时用QMenu会遇到点击一个菜单项就会自动关闭,当然可以通过其他方式实现该功能,
|
此时用QMenu会遇到点击一个菜单项就会自动关闭,当然可以通过其他方式实现该功能,
|
||||||
|
@ -13,9 +14,9 @@
|
||||||
原理:
|
原理:
|
||||||
|
|
||||||
1. 设置菜单项可勾选:通过`QAction.setCheckable(True)`方法实现
|
1. 设置菜单项可勾选:通过`QAction.setCheckable(True)`方法实现
|
||||||
1. 设置菜单不可关闭:通过覆盖`QMenu`的鼠标释放`mouseReleaseEvent`方法(可直接替换或者通过`installEventFilter`安装事件过滤器实现)
|
2. 设置菜单不可关闭:通过覆盖`QMenu`的鼠标释放`mouseReleaseEvent`方法(可直接替换或者通过`installEventFilter`安装事件过滤器实现)
|
||||||
1. 在菜单的鼠标释放事件中,当点击菜单项后是通过点击点坐标来查找是否有`QAction`,然后触发对应的`QAction`
|
3. 在菜单的鼠标释放事件中,当点击菜单项后是通过点击点坐标来查找是否有`QAction`,然后触发对应的`QAction`
|
||||||
1. 故在没有`QAction`的地方则直接交还给`QMenu`自行处理逻辑,在有`QAction`的地方可以根据自己的需求进行处理(如上所提)
|
4. 故在没有`QAction`的地方则直接交还给`QMenu`自行处理逻辑,在有`QAction`的地方可以根据自己的需求进行处理(如上所提)
|
||||||
|
|
||||||
核心代码:
|
核心代码:
|
||||||
|
|
||||||
|
@ -31,6 +32,4 @@ def _menu_mouseReleaseEvent(self, event):
|
||||||
action.activate(action.Trigger)
|
action.activate(action.Trigger)
|
||||||
```
|
```
|
||||||
|
|
||||||
效果图:
|
![MultiSelect](ScreenShot/MultiSelect.gif)
|
||||||
|
|
||||||
![截图](ScreenShot/菜单多选不关闭.gif)
|
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 136 KiB |
|
@ -6,7 +6,7 @@ Created on 2018年11月5日
|
||||||
@author: Irony
|
@author: Irony
|
||||||
@site: https://pyqt5.com https://github.com/892768447
|
@site: https://pyqt5.com https://github.com/892768447
|
||||||
@email: 892768447@qq.com
|
@email: 892768447@qq.com
|
||||||
@file: Widgets.JumpSlider
|
@file: ClickJumpSlider
|
||||||
@description:
|
@description:
|
||||||
"""
|
"""
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt
|
||||||
|
@ -21,7 +21,7 @@ __Copyright__ = "Copyright (c) 2018 Irony"
|
||||||
__Version__ = "Version 1.0"
|
__Version__ = "Version 1.0"
|
||||||
|
|
||||||
|
|
||||||
class JumpSlider(QSlider):
|
class ClickJumpSlider(QSlider):
|
||||||
|
|
||||||
def mousePressEvent(self, event):
|
def mousePressEvent(self, event):
|
||||||
# 获取上面的拉动块位置
|
# 获取上面的拉动块位置
|
||||||
|
@ -31,7 +31,7 @@ class JumpSlider(QSlider):
|
||||||
QStyle.CC_Slider, option, QStyle.SC_SliderHandle, self)
|
QStyle.CC_Slider, option, QStyle.SC_SliderHandle, self)
|
||||||
if rect.contains(event.pos()):
|
if rect.contains(event.pos()):
|
||||||
# 如果鼠标点击的位置在滑块上则交给Qt自行处理
|
# 如果鼠标点击的位置在滑块上则交给Qt自行处理
|
||||||
super(JumpSlider, self).mousePressEvent(event)
|
super(ClickJumpSlider, self).mousePressEvent(event)
|
||||||
return
|
return
|
||||||
if self.orientation() == Qt.Horizontal:
|
if self.orientation() == Qt.Horizontal:
|
||||||
# 横向,要考虑invertedAppearance是否反向显示的问题
|
# 横向,要考虑invertedAppearance是否反向显示的问题
|
||||||
|
@ -47,29 +47,30 @@ class JumpSlider(QSlider):
|
||||||
) else event.y(), self.height()))
|
) else event.y(), self.height()))
|
||||||
|
|
||||||
|
|
||||||
class TestWindow(QWidget):
|
class DemoWindow(QWidget):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(TestWindow, self).__init__(*args, **kwargs)
|
super(DemoWindow, self).__init__(*args, **kwargs)
|
||||||
|
self.resize(600, 600)
|
||||||
layout = QFormLayout(self)
|
layout = QFormLayout(self)
|
||||||
|
|
||||||
self.label1 = QLabel('0', self)
|
self.label1 = QLabel('0', self)
|
||||||
layout.addRow(self.label1, JumpSlider(
|
layout.addRow(self.label1, ClickJumpSlider(
|
||||||
Qt.Horizontal, valueChanged=lambda v: self.label1.setText(str(v))))
|
Qt.Horizontal, valueChanged=lambda v: self.label1.setText(str(v))))
|
||||||
|
|
||||||
# 横向-反向显示
|
# 横向-反向显示
|
||||||
self.label2 = QLabel('0', self)
|
self.label2 = QLabel('0', self)
|
||||||
layout.addRow(self.label2, JumpSlider(
|
layout.addRow(self.label2, ClickJumpSlider(
|
||||||
Qt.Horizontal, invertedAppearance=True,
|
Qt.Horizontal, invertedAppearance=True,
|
||||||
valueChanged=lambda v: self.label2.setText(str(v))))
|
valueChanged=lambda v: self.label2.setText(str(v))))
|
||||||
|
|
||||||
self.label3 = QLabel('0', self)
|
self.label3 = QLabel('0', self)
|
||||||
layout.addRow(self.label3, JumpSlider(
|
layout.addRow(self.label3, ClickJumpSlider(
|
||||||
Qt.Vertical, minimumHeight=200, valueChanged=lambda v: self.label3.setText(str(v))))
|
Qt.Vertical, minimumHeight=200, valueChanged=lambda v: self.label3.setText(str(v))))
|
||||||
|
|
||||||
# 纵向反向显示
|
# 纵向反向显示
|
||||||
self.label4 = QLabel('0', self)
|
self.label4 = QLabel('0', self)
|
||||||
layout.addRow(self.label4, JumpSlider(
|
layout.addRow(self.label4, ClickJumpSlider(
|
||||||
Qt.Vertical, invertedAppearance=True,
|
Qt.Vertical, invertedAppearance=True,
|
||||||
minimumHeight=200, valueChanged=lambda v: self.label4.setText(str(v))))
|
minimumHeight=200, valueChanged=lambda v: self.label4.setText(str(v))))
|
||||||
|
|
||||||
|
@ -80,6 +81,6 @@ if __name__ == '__main__':
|
||||||
sys.excepthook = cgitb.enable(1, None, 5, '')
|
sys.excepthook = cgitb.enable(1, None, 5, '')
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
w = TestWindow()
|
w = DemoWindow()
|
||||||
w.show()
|
w.show()
|
||||||
sys.exit(app.exec_())
|
sys.exit(app.exec_())
|
|
@ -0,0 +1,36 @@
|
||||||
|
# QSlider
|
||||||
|
|
||||||
|
## 1、滑动条点击定位
|
||||||
|
[运行 ClickJumpSlider.py](ClickJumpSlider.py)
|
||||||
|
|
||||||
|
1. `QSlider`对鼠标点击然后跳转到该位置的支持不是很好,通过重写鼠标点击事件`mousePressEvent`来达到效果
|
||||||
|
2. 通过`style`的`subControlRect`方法计算得到滑块的区域,当鼠标点击区域在此次时则交给系统自己处理(比如按住不放拖动)
|
||||||
|
3. 通过`orientation`判断滑动条的方向(横竖)
|
||||||
|
4. 通过`invertedAppearance`判断滑动条是否反向(左右、上下)
|
||||||
|
|
||||||
|
```python
|
||||||
|
def mousePressEvent(self, event):
|
||||||
|
# 获取上面的拉动块位置
|
||||||
|
option = QStyleOptionSlider()
|
||||||
|
self.initStyleOption(option)
|
||||||
|
rect = self.style().subControlRect(
|
||||||
|
QStyle.CC_Slider, option, QStyle.SC_SliderHandle, self)
|
||||||
|
if rect.contains(event.pos()):
|
||||||
|
# 如果鼠标点击的位置在滑块上则交给Qt自行处理
|
||||||
|
super(JumpSlider, self).mousePressEvent(event)
|
||||||
|
return
|
||||||
|
if self.orientation() == Qt.Horizontal:
|
||||||
|
# 横向,要考虑invertedAppearance是否反向显示的问题
|
||||||
|
self.setValue(self.style().sliderValueFromPosition(
|
||||||
|
self.minimum(), self.maximum(),
|
||||||
|
event.x() if not self.invertedAppearance() else (self.width(
|
||||||
|
) - event.x()), self.width()))
|
||||||
|
else:
|
||||||
|
# 纵向
|
||||||
|
self.setValue(self.style().sliderValueFromPosition(
|
||||||
|
self.minimum(), self.maximum(),
|
||||||
|
(self.height() - event.y()) if not self.invertedAppearance(
|
||||||
|
) else event.y(), self.height()))
|
||||||
|
```
|
||||||
|
|
||||||
|
![ClickJumpSlider](ScreenShot/ClickJumpSlider.gif)
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
|
@ -1,30 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
Created on 2018年12月6日
|
|
||||||
@author: Irony
|
|
||||||
@site: https://pyqt5.com, https://github.com/892768447
|
|
||||||
@email: 892768447@qq.com
|
|
||||||
@file:
|
|
||||||
@description:
|
|
||||||
"""
|
|
||||||
|
|
||||||
__Author__ = """By: Irony
|
|
||||||
QQ: 892768447
|
|
||||||
Email: 892768447@qq.com"""
|
|
||||||
__Copyright__ = 'Copyright (c) 2018 Irony'
|
|
||||||
__Version__ = 1.0
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QApplication
|
|
||||||
|
|
||||||
from CopyContent import TableView
|
|
||||||
|
|
||||||
|
|
||||||
app = QApplication(sys.argv)
|
|
||||||
app.setApplicationName("TableView")
|
|
||||||
w = TableView()
|
|
||||||
w.show()
|
|
||||||
sys.exit(app.exec_())
|
|
|
@ -1,10 +1,11 @@
|
||||||
# QTableView
|
# QTableView
|
||||||
|
|
||||||
## [1、表格内容复制](CopyContent)
|
## 1、表格内容复制
|
||||||
|
[运行 CopyContent.py](CopyContent.py)
|
||||||
|
|
||||||
1. 通过构造一个和选中区域一样的空数组,然后对数组进行填充形成表格
|
1. 通过构造一个和选中区域一样的空数组,然后对数组进行填充形成表格
|
||||||
1. 最后循环数组用`\t`进行拼接`join`,换行用`\r\n`
|
1. 最后循环数组用`\t`进行拼接`join`,换行用`\r\n`
|
||||||
1. 把字符串复制到剪切板中
|
1. 把字符串复制到剪切板中
|
||||||
|
|
||||||
![截图](ScreenShot/CopyContent1.png)![截图](ScreenShot/CopyContent2.png)
|
![CopyContent1](ScreenShot/CopyContent1.png) ![CopyContent2](ScreenShot/CopyContent2.png)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
# QTableWidget
|
# QTableWidget
|
||||||
|
|
||||||
## [1、Sqlalchemy动态拼接字段查询显示表格](SqlQuery)
|
## 1、Sqlalchemy动态拼接字段查询显示表格
|
||||||
|
[运行 SqlQuery.py](SqlQuery.py)
|
||||||
|
|
||||||
通过判断界面中选择的条件对`Sqlalchemy`的`model`进行字段拼接从而实现按条件查询
|
通过判断界面中选择的条件对`Sqlalchemy`的`model`进行字段拼接从而实现按条件查询
|
||||||
|
|
||||||
![截图](ScreenShot/SqlQuery.png)
|
![SqlQuery](ScreenShot/SqlQuery.png)
|
|
@ -17,7 +17,7 @@ from sqlalchemy.orm.session import sessionmaker
|
||||||
from sqlalchemy.sql.expression import and_
|
from sqlalchemy.sql.expression import and_
|
||||||
from sqlalchemy.sql.schema import Column
|
from sqlalchemy.sql.schema import Column
|
||||||
from sqlalchemy.sql.sqltypes import Integer, Text
|
from sqlalchemy.sql.sqltypes import Integer, Text
|
||||||
from mainui import Ui_Form
|
from Lib.mainui import Ui_Form
|
||||||
|
|
||||||
__Author__ = """By: Irony
|
__Author__ = """By: Irony
|
||||||
QQ: 892768447
|
QQ: 892768447
|
||||||
|
@ -26,7 +26,7 @@ __Copyright__ = "Copyright (c) 2018 Irony"
|
||||||
__Version__ = "Version 1.0"
|
__Version__ = "Version 1.0"
|
||||||
|
|
||||||
# engine = create_engine('mysql+mysqldb://root@localhost:3306/tourist?charset=utf8')
|
# engine = create_engine('mysql+mysqldb://root@localhost:3306/tourist?charset=utf8')
|
||||||
engine = create_engine('sqlite:///data.sqlite3', echo=True) # echo 表示开启命令显示
|
engine = create_engine('sqlite:///Data/data.sqlite3', echo=True) # echo 表示开启命令显示
|
||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
Created on 2018年12月6日
|
|
||||||
@author: Irony
|
|
||||||
@site: https://pyqt5.com, https://github.com/892768447
|
|
||||||
@email: 892768447@qq.com
|
|
||||||
@file:
|
|
||||||
@description:
|
|
||||||
"""
|
|
||||||
|
|
||||||
__Author__ = """By: Irony
|
|
||||||
QQ: 892768447
|
|
||||||
Email: 892768447@qq.com"""
|
|
||||||
__Copyright__ = 'Copyright (c) 2018 Irony'
|
|
||||||
__Version__ = 1.0
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QApplication
|
|
||||||
|
|
||||||
from SqlQuery import Window
|
|
||||||
|
|
||||||
|
|
||||||
app = QApplication(sys.argv)
|
|
||||||
w = Window()
|
|
||||||
w.show()
|
|
||||||
sys.exit(app.exec_())
|
|
|
@ -1,111 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'mainui.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_Form(object):
|
|
||||||
def setupUi(self, Form):
|
|
||||||
Form.setObjectName("Form")
|
|
||||||
Form.resize(400, 362)
|
|
||||||
self.gridLayout = QtWidgets.QGridLayout(Form)
|
|
||||||
self.gridLayout.setObjectName("gridLayout")
|
|
||||||
self.checkBoxName = QtWidgets.QCheckBox(Form)
|
|
||||||
self.checkBoxName.setObjectName("checkBoxName")
|
|
||||||
self.gridLayout.addWidget(self.checkBoxName, 0, 0, 1, 1)
|
|
||||||
self.checkBoxSeat = QtWidgets.QCheckBox(Form)
|
|
||||||
self.checkBoxSeat.setObjectName("checkBoxSeat")
|
|
||||||
self.gridLayout.addWidget(self.checkBoxSeat, 0, 2, 1, 1)
|
|
||||||
self.lineEditName = QtWidgets.QLineEdit(Form)
|
|
||||||
self.lineEditName.setObjectName("lineEditName")
|
|
||||||
self.gridLayout.addWidget(self.lineEditName, 0, 1, 1, 1)
|
|
||||||
self.tableWidget = QtWidgets.QTableWidget(Form)
|
|
||||||
self.tableWidget.setObjectName("tableWidget")
|
|
||||||
self.tableWidget.setColumnCount(10)
|
|
||||||
self.tableWidget.setRowCount(0)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(0, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(1, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(2, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(3, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(4, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(5, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(6, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(7, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(8, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(9, item)
|
|
||||||
self.gridLayout.addWidget(self.tableWidget, 3, 0, 1, 4)
|
|
||||||
self.lineEditSeat = QtWidgets.QLineEdit(Form)
|
|
||||||
self.lineEditSeat.setObjectName("lineEditSeat")
|
|
||||||
self.gridLayout.addWidget(self.lineEditSeat, 0, 3, 1, 1)
|
|
||||||
self.lineEditPort = QtWidgets.QLineEdit(Form)
|
|
||||||
self.lineEditPort.setObjectName("lineEditPort")
|
|
||||||
self.gridLayout.addWidget(self.lineEditPort, 1, 3, 1, 1)
|
|
||||||
self.checkBoxPort = QtWidgets.QCheckBox(Form)
|
|
||||||
self.checkBoxPort.setObjectName("checkBoxPort")
|
|
||||||
self.gridLayout.addWidget(self.checkBoxPort, 1, 2, 1, 1)
|
|
||||||
self.checkBoxLicense = QtWidgets.QCheckBox(Form)
|
|
||||||
self.checkBoxLicense.setObjectName("checkBoxLicense")
|
|
||||||
self.gridLayout.addWidget(self.checkBoxLicense, 1, 0, 1, 1)
|
|
||||||
self.lineEditLicense = QtWidgets.QLineEdit(Form)
|
|
||||||
self.lineEditLicense.setObjectName("lineEditLicense")
|
|
||||||
self.gridLayout.addWidget(self.lineEditLicense, 1, 1, 1, 1)
|
|
||||||
self.pushButtonQuery = QtWidgets.QPushButton(Form)
|
|
||||||
self.pushButtonQuery.setObjectName("pushButtonQuery")
|
|
||||||
self.gridLayout.addWidget(self.pushButtonQuery, 2, 0, 1, 4)
|
|
||||||
|
|
||||||
self.retranslateUi(Form)
|
|
||||||
QtCore.QMetaObject.connectSlotsByName(Form)
|
|
||||||
|
|
||||||
def retranslateUi(self, Form):
|
|
||||||
_translate = QtCore.QCoreApplication.translate
|
|
||||||
Form.setWindowTitle(_translate("Form", "Form"))
|
|
||||||
self.checkBoxName.setText(_translate("Form", "姓名"))
|
|
||||||
self.checkBoxSeat.setText(_translate("Form", "座位号"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(0)
|
|
||||||
item.setText(_translate("Form", "编号"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(1)
|
|
||||||
item.setText(_translate("Form", "姓名"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(2)
|
|
||||||
item.setText(_translate("Form", "证件号"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(3)
|
|
||||||
item.setText(_translate("Form", "航班号"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(4)
|
|
||||||
item.setText(_translate("Form", "航班日期"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(5)
|
|
||||||
item.setText(_translate("Form", "座位号"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(6)
|
|
||||||
item.setText(_translate("Form", "登机口"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(7)
|
|
||||||
item.setText(_translate("Form", "序号"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(8)
|
|
||||||
item.setText(_translate("Form", "出发地"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(9)
|
|
||||||
item.setText(_translate("Form", "目的地"))
|
|
||||||
self.checkBoxPort.setText(_translate("Form", "登机口"))
|
|
||||||
self.checkBoxLicense.setText(_translate("Form", "证件号"))
|
|
||||||
self.pushButtonQuery.setText(_translate("Form", "查询"))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import sys
|
|
||||||
app = QtWidgets.QApplication(sys.argv)
|
|
||||||
Form = QtWidgets.QWidget()
|
|
||||||
ui = Ui_Form()
|
|
||||||
ui.setupUi(Form)
|
|
||||||
Form.show()
|
|
||||||
sys.exit(app.exec_())
|
|
||||||
|
|
|
@ -1,39 +1,40 @@
|
||||||
import sys
|
import sys
|
||||||
from PyQt5.QtGui import QTextCharFormat,QTextDocument, QTextCursor
|
from PyQt5.QtGui import QTextCharFormat, QTextDocument, QTextCursor
|
||||||
from PyQt5.QtWidgets import (QApplication, QMainWindow, QTextEdit,
|
from PyQt5.QtWidgets import (QApplication, QMainWindow, QTextEdit,
|
||||||
QToolBar, QLineEdit, QPushButton, QColorDialog, QHBoxLayout, QWidget)
|
QToolBar, QLineEdit, QPushButton, QColorDialog, QHBoxLayout, QWidget)
|
||||||
|
|
||||||
|
|
||||||
class TextEdit(QMainWindow):
|
class TextEdit(QMainWindow):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super(TextEdit, self).__init__(parent)
|
super(TextEdit, self).__init__(parent)
|
||||||
self.textEdit = QTextEdit(self)
|
self.textEdit = QTextEdit(self)
|
||||||
self.setCentralWidget(self.textEdit)
|
self.setCentralWidget(self.textEdit)
|
||||||
|
|
||||||
widget = QWidget(self)
|
widget = QWidget(self)
|
||||||
vb = QHBoxLayout(widget)
|
vb = QHBoxLayout(widget)
|
||||||
vb.setContentsMargins(0, 0, 0, 0)
|
vb.setContentsMargins(0, 0, 0, 0)
|
||||||
self.findText = QLineEdit(self)
|
self.findText = QLineEdit(self)
|
||||||
self.findText.setText('self')
|
self.findText.setText('self')
|
||||||
findBtn = QPushButton('高亮',self)
|
findBtn = QPushButton('高亮', self)
|
||||||
findBtn.clicked.connect(self.highlight)
|
findBtn.clicked.connect(self.highlight)
|
||||||
vb.addWidget(self.findText)
|
vb.addWidget(self.findText)
|
||||||
vb.addWidget(findBtn)
|
vb.addWidget(findBtn)
|
||||||
|
|
||||||
tb = QToolBar(self)
|
tb = QToolBar(self)
|
||||||
tb.addWidget(widget)
|
tb.addWidget(widget)
|
||||||
|
|
||||||
def setText(self,text):
|
def setText(self, text):
|
||||||
self.textEdit.setPlainText(text)
|
self.textEdit.setPlainText(text)
|
||||||
|
|
||||||
def mergeFormatOnWordOrSelection(self, format):
|
def mergeFormatOnWordOrSelection(self, format):
|
||||||
cursor = self.textEdit.textCursor()
|
cursor = self.textEdit.textCursor()
|
||||||
if not cursor.hasSelection():
|
if not cursor.hasSelection():
|
||||||
cursor.select(QTextCursor.WordUnderCursor)
|
cursor.select(QTextCursor.WordUnderCursor)
|
||||||
cursor.mergeCharFormat(format)
|
cursor.mergeCharFormat(format)
|
||||||
self.textEdit.mergeCurrentCharFormat(format)
|
self.textEdit.mergeCurrentCharFormat(format)
|
||||||
|
|
||||||
def highlight(self):
|
def highlight(self):
|
||||||
text = self.findText.text()#输入框中的文字
|
text = self.findText.text() # 输入框中的文字
|
||||||
if not text:
|
if not text:
|
||||||
return
|
return
|
||||||
col = QColorDialog.getColor(self.textEdit.textColor(), self)
|
col = QColorDialog.getColor(self.textEdit.textColor(), self)
|
||||||
|
@ -41,17 +42,18 @@ class TextEdit(QMainWindow):
|
||||||
return
|
return
|
||||||
fmt = QTextCharFormat()
|
fmt = QTextCharFormat()
|
||||||
fmt.setForeground(col)
|
fmt.setForeground(col)
|
||||||
#先把光标移动到开头
|
# 先把光标移动到开头
|
||||||
self.textEdit.moveCursor(QTextCursor.Start)
|
self.textEdit.moveCursor(QTextCursor.Start)
|
||||||
while self.textEdit.find(text,QTextDocument.FindWholeWords):#查找所有文字
|
while self.textEdit.find(text, QTextDocument.FindWholeWords): # 查找所有文字
|
||||||
self.mergeFormatOnWordOrSelection(fmt)
|
self.mergeFormatOnWordOrSelection(fmt)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
|
|
||||||
textEdit = TextEdit()
|
textEdit = TextEdit()
|
||||||
textEdit.resize(800, 600)
|
textEdit.resize(800, 600)
|
||||||
textEdit.show()
|
textEdit.show()
|
||||||
textEdit.setText(open(sys.argv[0],'rb').read().decode())
|
textEdit.setText(open(sys.argv[0], 'rb').read().decode())
|
||||||
|
|
||||||
sys.exit(app.exec_())
|
sys.exit(app.exec_())
|
|
@ -0,0 +1,8 @@
|
||||||
|
# QTextEdit
|
||||||
|
|
||||||
|
## 1、文本查找高亮
|
||||||
|
[运行 HighlightText.py](HighlightText.py)
|
||||||
|
|
||||||
|
主要用到`mergeCurrentCharFormat`函数
|
||||||
|
|
||||||
|
![HighlightText](ScreenShot/HighlightText.gif)
|
Before Width: | Height: | Size: 471 KiB After Width: | Height: | Size: 471 KiB |
|
@ -6,7 +6,7 @@ Created on 2017年12月10日
|
||||||
@author: Irony."[讽刺]
|
@author: Irony."[讽刺]
|
||||||
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
|
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
|
||||||
@email: 892768447@qq.com
|
@email: 892768447@qq.com
|
||||||
@file: WebEngineView
|
@file: GetCookie
|
||||||
@description:
|
@description:
|
||||||
'''
|
'''
|
||||||
import sys
|
import sys
|
||||||
|
@ -36,9 +36,9 @@ class WebEngineView(QWebEngineView):
|
||||||
def onLoadFinished(self):
|
def onLoadFinished(self):
|
||||||
print("*****AllDomainCookies:", self.getAllDomainCookies())
|
print("*****AllDomainCookies:", self.getAllDomainCookies())
|
||||||
print("*****AllPathCookies:", self.getAllPathCookies())
|
print("*****AllPathCookies:", self.getAllPathCookies())
|
||||||
print("*****alyl.vip cookie:", self.getDomainCookies(".alyl.vip"))
|
print("*****pyqt5.com cookie:", self.getDomainCookies(".pyqt5.com"))
|
||||||
print("*****alyl.vip / path cookie:",
|
print("*****pyqt5.com / path cookie:",
|
||||||
self.getPathCookies(".alyl.vip/"))
|
self.getPathCookies(".pyqt5.com/"))
|
||||||
|
|
||||||
def getAllDomainCookies(self):
|
def getAllDomainCookies(self):
|
||||||
return self.DomainCookies
|
return self.DomainCookies
|
||||||
|
@ -79,5 +79,5 @@ if __name__ == "__main__":
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
w = WebEngineView()
|
w = WebEngineView()
|
||||||
w.show()
|
w.show()
|
||||||
w.load(QUrl("http://alyl.vip"))
|
w.load(QUrl("https://pyqt5.com"))
|
||||||
sys.exit(app.exec_())
|
sys.exit(app.exec_())
|
0
QWebEngineView/README.en.md
Normal file
8
QWebEngineView/README.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# QWebEngineView
|
||||||
|
|
||||||
|
## 1、QWebEngineView
|
||||||
|
[运行 GetCookie.py](GetCookie.py)
|
||||||
|
|
||||||
|
通过`QWebEngineProfile`中得到的`cookieStore`并绑定它的`cookieAdded`信号来得到Cookie
|
||||||
|
|
||||||
|
![GetCookie](ScreenShot/GetCookie.png)
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
@ -17,14 +17,14 @@ from PyQt5.QtGui import QPalette
|
||||||
from PyQt5.QtWebKitWidgets import QWebView
|
from PyQt5.QtWebKitWidgets import QWebView
|
||||||
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout
|
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout
|
||||||
|
|
||||||
import data_rc # @UnusedImport @UnresolvedImport
|
from Lib import data_rc # @UnusedImport @UnresolvedImport
|
||||||
|
|
||||||
|
|
||||||
# from PyQt5.QtWebKit import QWebSettings
|
# from PyQt5.QtWebKit import QWebSettings
|
||||||
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
|
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
|
||||||
__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]"
|
__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]"
|
||||||
__Version__ = "Version 1.0"
|
__Version__ = "Version 1.0"
|
||||||
|
|
||||||
|
|
||||||
# 要实现透明的webview,需要先用一个QWidget作为父控件
|
# 要实现透明的webview,需要先用一个QWidget作为父控件
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,8 +42,8 @@ class Window(QWidget):
|
||||||
layout = QVBoxLayout(self)
|
layout = QVBoxLayout(self)
|
||||||
layout.setContentsMargins(0, 0, 0, 0)
|
layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
# QWebSettings.globalSettings().setAttribute(
|
# QWebSettings.globalSettings().setAttribute(
|
||||||
# QWebSettings.DeveloperExtrasEnabled, True)# web开发者工具
|
# QWebSettings.DeveloperExtrasEnabled, True)# web开发者工具
|
||||||
|
|
||||||
self.webView = QWebView(self) # 网页控件
|
self.webView = QWebView(self) # 网页控件
|
||||||
layout.addWidget(self.webView)
|
layout.addWidget(self.webView)
|
||||||
|
@ -62,6 +62,7 @@ class Window(QWidget):
|
||||||
def load(self):
|
def load(self):
|
||||||
self.webView.load(QUrl('qrc:/tree.html')) # 加载网页
|
self.webView.load(QUrl('qrc:/tree.html')) # 加载网页
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
w = Window()
|
w = Window()
|
|
@ -6,7 +6,7 @@ Created on 2017年12月10日
|
||||||
@author: Irony."[讽刺]
|
@author: Irony."[讽刺]
|
||||||
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
|
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
|
||||||
@email: 892768447@qq.com
|
@email: 892768447@qq.com
|
||||||
@file: WebView
|
@file: GetCookie
|
||||||
@description:
|
@description:
|
||||||
'''
|
'''
|
||||||
import sys
|
import sys
|
||||||
|
@ -31,17 +31,17 @@ class WebView(QWebView):
|
||||||
allCookies = self.page().networkAccessManager().cookieJar().allCookies()
|
allCookies = self.page().networkAccessManager().cookieJar().allCookies()
|
||||||
print("allCookies:", allCookies)
|
print("allCookies:", allCookies)
|
||||||
for cookie in allCookies:
|
for cookie in allCookies:
|
||||||
if cookie.domain() == ".alyl.vip":
|
# if cookie.domain() == ".pyqt5.com":
|
||||||
print("domain:", cookie.domain())
|
print("domain:", cookie.domain())
|
||||||
print("path:", cookie.path())
|
print("path:", cookie.path())
|
||||||
print("name:", cookie.name())
|
print("name:", cookie.name())
|
||||||
print("value:", cookie.value())
|
print("value:", cookie.value())
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
w = WebView()
|
w = WebView()
|
||||||
w.show()
|
w.show()
|
||||||
w.load(QUrl("http://alyl.vip"))
|
w.load(QUrl("https://pyqt5.com"))
|
||||||
sys.exit(app.exec_())
|
sys.exit(app.exec_())
|
|
@ -0,0 +1,15 @@
|
||||||
|
# QWebView
|
||||||
|
|
||||||
|
## 1、梦幻树
|
||||||
|
[运行 DreamTree.py](DreamTree.py)
|
||||||
|
在桌面上显示透明html效果,使用`QWebkit`加载html实现,采用窗口背景透明和穿透方式
|
||||||
|
|
||||||
|
![DreamTree](ScreenShot/DreamTree.png)
|
||||||
|
|
||||||
|
## 2、获取Cookie
|
||||||
|
[运行 GetCookie.py](GetCookie.py)
|
||||||
|
|
||||||
|
从`page()`中得到`QNetworkAccessManager`,在从中得到`QNetworkCookieJar`,
|
||||||
|
最后得到cookie,当然也可以设置自己的`QNetworkCookieJar`
|
||||||
|
|
||||||
|
![GetCookie](ScreenShot/GetCookie.png)
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
241
README.md
|
@ -1,197 +1,66 @@
|
||||||
# 各种各样的PyQt测试和例子
|
# 各种各样的PyQt测试和例子
|
||||||
|
|
||||||
[![Blog](https://img.shields.io/badge/blog-pyqt5-green.svg)](https://pyqt5.com)
|
[![Blog](https://img.shields.io/badge/blog-pyqt5-green.svg)](https://pyqt5.com)
|
||||||
[![Gitter version](https://img.shields.io/gitter/room/gitterHQ/gitter.svg)](https://gitter.im/PyQt-5/Lobby)
|
|
||||||
|
|
||||||
https://pyqt5.com 社区是专门针对PyQt5学习和提升开设的博客网站,分享大家平时学习中记录的笔记和例子,以及对遇到的问题进行收集整理。
|
https://pyqt5.com 社区是专门针对PyQt5学习和提升开设的博客网站,分享大家平时学习中记录的笔记和例子,以及对遇到的问题进行收集整理。
|
||||||
|
|
||||||
## [ActiveX](ActiveX)
|
## 目录
|
||||||
|
|
||||||
1. [显示Word、Excel、Pdf文件](ActiveX/显示word_excel_pdf.py)
|
| | |
|
||||||
|
|:-------|:-------|
|
||||||
|
| ActiveX | [QAxWidget](QAxWidget)
|
||||||
|
| 日历 | [QCalendarWidget](QCalendarWidget)
|
||||||
|
| 复选框 | [QCheckBox](QCheckBox)
|
||||||
|
| 列视图 | [QColumnView](QColumnView)
|
||||||
|
| 组合框 | [QComboBox](QComboBox)
|
||||||
|
| 日期时间 | [QDateTime](QDateTime)
|
||||||
|
| 日期时间编辑 | [QDateTimeEdit](QDateTimeEdit)
|
||||||
|
| 刻度盘 | [QDial](QDial)
|
||||||
|
| 停靠窗口 | [QDockWidget](QDockWidget)
|
||||||
|
| 双精度编辑 | [QDoubleSpinBox](QDoubleSpinBox)
|
||||||
|
| 流布局 | [QFlowLayout](QFlowLayout)
|
||||||
|
| 字体选择 | [QFontComboBox](QFontComboBox)
|
||||||
|
| 表单布局 | [QFormLayout](QFormLayout)
|
||||||
|
| 边框容器 | [QFrame](QFrame)
|
||||||
|
| 图形视图 | [QGraphicsView](QGraphicsView)
|
||||||
|
| 网格布局 | [QGridLayout](QGridLayout)
|
||||||
|
| 分组容器 | [QGroupBox](QGroupBox)
|
||||||
|
| 横向布局 | [QHBoxLayout](QHBoxLayout)
|
||||||
|
| 文本图片 | [QLabel](QLabel)
|
||||||
|
| 类液晶屏显示 | [QLCDNumber](QLCDNumber)
|
||||||
|
| 行输入框 | [QLineEdit](QLineEdit)
|
||||||
|
| 列表视图 | [QListView](QListView)
|
||||||
|
| 列表控件 | [QListWidget](QListWidget)
|
||||||
|
| 子区域 | [QMdiArea](QMdiArea)
|
||||||
|
| 菜单 | [QMenu](QMenu)
|
||||||
|
| OpenGL | [QOpenGLWidget](QOpenGLWidget)
|
||||||
|
| 纯文本 | [QPlainTextEdit](QPlainTextEdit)
|
||||||
|
| 进度条 | [QProgressBar](QProgressBar)
|
||||||
|
| 按钮 | [QPushButton](QPushButton)
|
||||||
|
| 单选框 | [QRadioButton](QRadioButton)
|
||||||
|
| 滚动区 | [QScrollArea](QScrollArea)
|
||||||
|
| 滑动条 | [QScrollBar](QScrollBar)
|
||||||
|
| 拉动条 | [QSlider](QSlider)
|
||||||
|
| 拉伸条 | [QSpacerItem](QSpacerItem)
|
||||||
|
| 单精度编辑 | [QSpinBox](QSpinBox)
|
||||||
|
| 堆叠布局 | [QStackedLayout](QStackedLayout)
|
||||||
|
| 堆叠控件 | [QStackedWidget](QStackedWidget)
|
||||||
|
| 表格视图 | [QTableView](QTableView)
|
||||||
|
| 表格控件 | [QTableWidget](QTableWidget)
|
||||||
|
| 多标签 | [QTabWidget](QTabWidget)
|
||||||
|
| 富文本 | [QTextBrowser](QTextBrowser)
|
||||||
|
| 多行富文本 | [QTextEdit](QTextEdit)
|
||||||
|
| 时间编辑 | [QTimeEdit](QTimeEdit)
|
||||||
|
| 工具箱 | [QToolBox](QToolBox)
|
||||||
|
| 工具按钮 | [QToolButton](QToolButton)
|
||||||
|
| 树形视图 | [QTreeView](QTreeView)
|
||||||
|
| 树形控件 | [QTreeWidget](QTreeWidget)
|
||||||
|
| 纵向布局 | [QVBoxLayout](QVBoxLayout)
|
||||||
|
| WebEngine | [QWebEngineView](QWebEngineView)
|
||||||
|
| WebView | [QWebView](QWebView)
|
||||||
|
| QWidget | [QWidget](QWidget)
|
||||||
|
| 美化样式 | [StyleSheets](StyleSheets)
|
||||||
|
|
||||||
## [按钮](按钮)
|
|
||||||
|
|
||||||
## [输入框](输入框)
|
|
||||||
|
|
||||||
1. [QTextEdit](输入框/QTextEdit)
|
|
||||||
1. [文本高亮](输入框/QTextEdit/简单查找文字并高亮.py)
|
|
||||||
|
|
||||||
## [菜单](菜单)
|
|
||||||
|
|
||||||
1. [菜单多选不关闭](菜单/菜单多选不关闭.py)
|
|
||||||
|
|
||||||
## [列表](列表)
|
|
||||||
|
|
||||||
1. [QListWidget](列表/QListWidget)
|
|
||||||
1. [自定义可拖拽Item](列表/QListWidget/自定义可拖拽Item.py)
|
|
||||||
1. [腾讯视频热播列表](列表/QListWidget/腾讯视频热播列表)
|
|
||||||
1. [删除自定义Item](列表/QListWidget/删除自定义Item.py)
|
|
||||||
|
|
||||||
1. [QListView](列表/QListView)
|
|
||||||
1. [自定义Widget](列表/QListView/显示自定义Widget.py)
|
|
||||||
1. [自定义Widget并排序](列表/QListView/显示自定义Widget并排序.py)
|
|
||||||
|
|
||||||
## [树结构](树结构)
|
|
||||||
|
|
||||||
1. [QTreeWidget](树结构/QTreeWidget)
|
|
||||||
1. [Json生成QTreeWidget](树结构/QTreeWidget/Json生成QTreeWidget)
|
|
||||||
|
|
||||||
1. [QTreeView](树结构/QTreeView)
|
|
||||||
|
|
||||||
## [表格](表格)
|
|
||||||
|
|
||||||
1. [QTableWidget](表格/QTableWidget)
|
|
||||||
1. [数据库查询显示表格](表格/QTableWidget/数据库查询显示表格)
|
|
||||||
|
|
||||||
1. [QTreeView](表格/QTableView)
|
|
||||||
1. [表格内容复制](表格/QTableView/表格内容复制.py)
|
|
||||||
|
|
||||||
## [级联](级联)
|
|
||||||
|
|
||||||
## [日期](日期)
|
|
||||||
|
|
||||||
## [图片](图片)
|
|
||||||
|
|
||||||
1. [图片加载、动态图](图片/图片加载)
|
|
||||||
1. [显示.9.png格式图片](图片/显示.9格式图片)
|
|
||||||
1. [仿网页图片错位特效](图片/仿网页图片错位特效.py)
|
|
||||||
1. [图片旋转](图片/图片旋转.py)
|
|
||||||
|
|
||||||
## [下拉框](下拉框)
|
|
||||||
|
|
||||||
1. [下拉选择联动](下拉框/下拉选择联动)
|
|
||||||
|
|
||||||
## [滚动条](滚动条)
|
|
||||||
|
|
||||||
## [滑动条](滑动条)
|
|
||||||
|
|
||||||
1. [滑动条点击定位](滑动条/滑动条点击定位.py)
|
|
||||||
|
|
||||||
## [进度条](进度条)
|
|
||||||
|
|
||||||
## [窗口](窗口)
|
|
||||||
|
|
||||||
1. [窗口重启](窗口/窗口重启.py)
|
|
||||||
1. [分割窗口的分割条重写](窗口/分割窗口的分割条重写.py)
|
|
||||||
1. [简单的窗口贴边隐藏](窗口/简单的窗口贴边隐藏.py)
|
|
||||||
1. [简单探测窗口和放大截图](窗口/简单探测窗口和放大截图.py)
|
|
||||||
1. [嵌入外部窗口](窗口/嵌入外部窗口.py)
|
|
||||||
1. [外部窗口跟随](窗口/外部窗口跟随.py)
|
|
||||||
1. [无边框自定义标题栏窗口](窗口/无边框自定义标题栏窗口)
|
|
||||||
1. [消息对话框倒计时关闭](窗口/消息对话框倒计时关闭.py)
|
|
||||||
|
|
||||||
## [多页面](多页面)
|
|
||||||
|
|
||||||
1. [QScrollArea](QScrollArea/)
|
|
||||||
1. [仿QQ设置面板](多页面/QScrollArea/仿QQ设置面板)
|
|
||||||
|
|
||||||
1. [QStackedWidget](QStackedWidget/)
|
|
||||||
1. [左侧选项卡](多页面/QStackedWidget/左侧选项卡)
|
|
||||||
2. [多页面切换动画](动画/多页面切换动画)
|
|
||||||
|
|
||||||
## [多线程](多线程)
|
|
||||||
|
|
||||||
1. [线程挂起恢复](多线程/线程挂起恢复.py)
|
|
||||||
1. [线程休眠唤醒](多线程/线程休眠唤醒.py)
|
|
||||||
1. [继承QThread](多线程/继承QThread.py)
|
|
||||||
1. [moveToThread](多线程/moveToThread.py)
|
|
||||||
|
|
||||||
## [美化](美化)
|
|
||||||
|
|
||||||
1. [Effect-特效](美化/Effect)
|
|
||||||
1. [图片按钮输入框阴影](美化/Effect/图片按钮输入框阴影.py)
|
|
||||||
|
|
||||||
1. [QCalendarWidget-日历](美化/QCalendarWidget)
|
|
||||||
|
|
||||||
1. [QFileSystemModel-模型](美化/QFileSystemModel)
|
|
||||||
|
|
||||||
1. [QLabel-文字图片](美化/QLabel)
|
|
||||||
1. [圆形图片](美化/QLabel/圆形图片.py)
|
|
||||||
|
|
||||||
1. [QMessageBox-消息对话框](美化/QMessageBox)
|
|
||||||
1. [方案一](美化/QMessageBox/方案一)
|
|
||||||
1. [方案二](美化/QMessageBox/方案二)
|
|
||||||
|
|
||||||
1. [QProgressBar-进度条](美化/QProgressBar)
|
|
||||||
1. [水波纹进度条](美化/QProgressBar/水波纹进度条)
|
|
||||||
1. [Metro进度条](美化/QProgressBar/Metro进度条.py)
|
|
||||||
1. [百分比进度条](美化/QProgressBar/百分比进度条.py)
|
|
||||||
1. [简单样式表美化](美化/QProgressBar/简单样式表美化.py)
|
|
||||||
1. [圆圈进度条](美化/QProgressBar/圆圈进度条.py)
|
|
||||||
|
|
||||||
1. [QPushButton-按钮](美化/QPushButton)
|
|
||||||
1. [按钮进度动画](美化/QPushButton/按钮进度动画)
|
|
||||||
1. [按钮常见样式](美化/QPushButton/按钮常见样式.py)
|
|
||||||
|
|
||||||
1. [QScrollBar-滚动条](美化/QScrollBar)
|
|
||||||
|
|
||||||
1. [QSlider-拉动条](美化/QSlider)
|
|
||||||
1. [自绘拉动条PaintQSlider](美化/QSlider/PaintQSlider.py)
|
|
||||||
1. [QSS拉动条QssQSlider](美化/QSlider/QssQSlider.py)
|
|
||||||
|
|
||||||
1. [QWidget-窗口](美化/QWidget)
|
|
||||||
1. [自定义QWidget样式测试](美化/QWidget/QWidget样式测试.py)
|
|
||||||
|
|
||||||
## [动画](动画)
|
|
||||||
|
|
||||||
1. [淡入淡出](动画/淡入淡出.py)
|
|
||||||
1. [右键菜单动画](动画/右键菜单动画.py)
|
|
||||||
1. [按钮放大缩小动画](动画/按钮放大缩小动画.py)
|
|
||||||
1. [仿网页点阵特效](动画/点阵特效)
|
|
||||||
1. [图片轮播动画](动画/多页面切换动画/图片轮播动画.py)
|
|
||||||
|
|
||||||
## [图表](图表)
|
|
||||||
|
|
||||||
1. [仿echarts折线图](图表/PyQtChart/charts/line/LineStack.py)
|
|
||||||
1. [仿echarts柱状图](图表/PyQtChart/charts/line/BarStack.py)
|
|
||||||
1. [折线图](图表/PyQtChart/demo/LineChart.py)
|
|
||||||
1. [折线图自定义xy轴](图表/PyQtChart/demo/LineChart自定义xy轴.py)
|
|
||||||
1. [ToolTip提示](图表/PyQtChart/demo/ToolTip.py)
|
|
||||||
|
|
||||||
## [网络](网络)
|
|
||||||
|
|
||||||
1. [窗口配合异步Http](网络/窗口配合异步Http)
|
|
||||||
1. [控制小车](网络/控制小车)
|
|
||||||
|
|
||||||
## [浏览器](浏览器)
|
|
||||||
|
|
||||||
1. [QWebView](浏览器/QWebView)
|
|
||||||
1. [梦幻树](浏览器/QWebView/梦幻树)
|
|
||||||
1. [获取Cookie](浏览器/QWebView/获取Cookie)
|
|
||||||
|
|
||||||
1. [QWebEngineView](浏览器/QWebEngineView)
|
|
||||||
1. [获取Cookie](浏览器/QWebEngineView/获取Cookie)
|
|
||||||
1. [下载文件](partner_625781186/6.QWebEngineView下载文件)
|
|
||||||
|
|
||||||
## [QML](QML)
|
|
||||||
|
|
||||||
## [图形视图](图形视图)
|
|
||||||
|
|
||||||
1. [世界地图](图形视图/世界地图)
|
|
||||||
1. [添加QWidget](图形视图/添加QWidget.py)
|
|
||||||
1. [显示图片及缩放](图形视图/显示图片及缩放.py)
|
|
||||||
|
|
||||||
## [其它](其它)
|
|
||||||
|
|
||||||
1. [C和C++扩展](其它/C和C++扩展)
|
|
||||||
1. [直接生成pyd](其它/C和C++扩展/pydext)
|
|
||||||
2. [使用pyx和c++](其它/C和C++扩展/pyx和c++)
|
|
||||||
3. [python转pyd](其它/C和C++扩展/py转pyd)
|
|
||||||
|
|
||||||
1. [QRC资源文件使用](其它/QRC资源文件使用)
|
|
||||||
1. [程序重启](其它/程序重启)
|
|
||||||
1. [单实例应用](其它/单实例应用)
|
|
||||||
1. [调用截图dll(只能用32位)](其它/调用截图dll(只能用32位))
|
|
||||||
1. [全局热键](其它/全局热键)
|
|
||||||
1. [人脸描点检测](其它/人脸描点检测)
|
|
||||||
1. [自定义import](其它/自定义import)
|
|
||||||
1. [自动更新](其它/自动更新)
|
|
||||||
1. [自定义属性测试](其它/自定义属性测试)
|
|
||||||
1. [验证码控件](其它/验证码控件)
|
|
||||||
1. [右下角弹出框](其它/右下角弹出框)
|
|
||||||
1. [消息提示](其它/消息提示)
|
|
||||||
1. [字体测试](其它/字体测试)
|
|
||||||
1. [串口调试小助手](其它/串口调试小助手)
|
|
||||||
|
|
||||||
# QQ群
|
# QQ群
|
||||||
|
|
||||||
|
|
149
README.old.md
|
@ -1,149 +0,0 @@
|
||||||
# 各种各样的PyQt测试和例子
|
|
||||||
|
|
||||||
## [PyQt5 社区](https://pyqt5.com)
|
|
||||||
本社区是专门针对PyQt5学习和提升开设的博客网站,分析大家平时学习中记录的笔记和例子,以及对遇到的问题进行收集整理。
|
|
||||||
|
|
||||||
### I、 项目型
|
|
||||||
[Qt皮肤生成器 - 持续更新中](https://github.com/892768447/QtSkin)
|
|
||||||
|
|
||||||
[客户端动画界面](https://github.com/892768447/PyQtClient)
|
|
||||||
|
|
||||||
[桌面悬浮异形窗体](https://github.com/892768447/Lolita)
|
|
||||||
|
|
||||||
[必应壁纸](https://github.com/892768447/BingWallpaper)
|
|
||||||
|
|
||||||
[腾讯视频热播列表](腾讯视频热播列表/)
|
|
||||||
|
|
||||||
[ QWebView 与 python 通过js交互 特效 - QWebEngine需要改代码](https://github.com/892768447/PhotoEffects)
|
|
||||||
|
|
||||||
### II、功能型
|
|
||||||
|
|
||||||
#### 2.1 常用例子
|
|
||||||
|
|
||||||
1. - [ 自定义属性测试](自定义属性测试/)
|
|
||||||
1. - [ 自动更新](自动更新/)
|
|
||||||
1. - [ 自定义import](自定义import/)
|
|
||||||
1. - [ 全局热键](全局热键/)
|
|
||||||
1. - [ 单实例应用 - 只允许运行一个程序](单实例应用/)
|
|
||||||
1. - [ 程序重启](程序重启/)
|
|
||||||
1. - [ 窗口重启](窗口重启/)
|
|
||||||
1. - [ 菜单](菜单/)
|
|
||||||
- [1. 菜单多选](菜单/菜单多选不关闭.py)
|
|
||||||
1. - [ 外部窗口跟随](外部窗口跟随/)
|
|
||||||
1. - python 的exec( ) 动态生成控件
|
|
||||||
- [1. 动态控件基础例子 - 动态生成按钮](partner_625781186/1.exec动态生成控件/dynamic_button)
|
|
||||||
- [2. 动态控件基础例子 - 动态生成菜单](partner_625781186/1.exec动态生成控件/dynamic_Menu)
|
|
||||||
- [3. 配合setting记录模型类型](partner_625781186/13.combo_listwidget)
|
|
||||||
|
|
||||||
- 小部件
|
|
||||||
|
|
||||||
1. - [ ☆! QSplitter 分割条重写 来添加按钮](分割窗口的分割条重写/)
|
|
||||||
1. - [ QLabel 图片加载 gif动画](图片加载/)
|
|
||||||
1. - [ 一个图片显示小特效](图片加载/)
|
|
||||||
1. - [ ComboBox 下拉选择级联--省、市、县 json 数据 ](下拉选择联动/)
|
|
||||||
1. - [ ComboBox 自定义下拉 listitem ](partner_625781186/13.combo_listwidget/)
|
|
||||||
1. - [ 仿QQ设置面板](仿QQ设置面板/)
|
|
||||||
1. - [ 右下角弹出框](右下角弹出框/)
|
|
||||||
1. - [ 消息对话框倒计时关闭](消息对话框倒计时关闭/)
|
|
||||||
1. - [ QTextEdit 文本高亮](文本高亮/)
|
|
||||||
1. - [ QActiveX窗口 加载本地word/pdf](ActiveX窗口/)
|
|
||||||
|
|
||||||
- win 32
|
|
||||||
|
|
||||||
1. - [ 线程的挂起与恢复](多线程使用/)
|
|
||||||
1. - [ 嵌入外部窗口](嵌入外部窗口/)
|
|
||||||
1. - [ 截图dll (只能用32位python)](调用截图dll(只能用32位)/)
|
|
||||||
1. - [ 探测窗口 和 放大镜](探测窗口和放大截图/)
|
|
||||||
|
|
||||||
- Model & View
|
|
||||||
|
|
||||||
1. - [ QListView 加按钮和 排序](QListView/)
|
|
||||||
1. - [ QListWidget 自定义Item并拖拽](QListWidget自定义Item并拖拽/)
|
|
||||||
|
|
||||||
1. - [ Json生成QTreeWidget](Json生成QTreeWidget/)
|
|
||||||
1. - [ treeWidget 节点可拖拽](https://github.com/AshotS/glowing-disco)
|
|
||||||
1. - [ treeWidget 支持拖拽 并改变图标样式](partner_625781186/12.1拖拽显示为图片/)
|
|
||||||
|
|
||||||
1. - [ QTabWidget 左侧标签 正字方法](左侧选项卡/)
|
|
||||||
1. - [ QTabWidget 表格复制 与 黏贴](表格复制/)
|
|
||||||
1. - [ QSqlTableModel + QTableView 数据库查询显示表格](数据库查询显示表格/)
|
|
||||||
|
|
||||||
- 浏览器QWebEngine模块例子
|
|
||||||
|
|
||||||
1. - [ 浏览器获取Cookie](浏览器获取Cookie/)
|
|
||||||
1. - [ 浏览器下载功能](partner_625781186/6.QWebEngineView下载文件)
|
|
||||||
1. - [ 浏览器开启调试工具](partner_625781186/14.多进程爬虫)
|
|
||||||
|
|
||||||
1. - [ 梦幻树 QWebView - QWebEngine需要改代码](梦幻树/)
|
|
||||||
1. - [ QWebView 与 python 通过js交互 特效 - QWebEngine需要改代码](https://github.com/892768447/PhotoEffects)
|
|
||||||
|
|
||||||
|
|
||||||
#### 2.2 框架
|
|
||||||
1. - [ 无边框自定义标题栏窗口](无边框自定义标题栏窗口/)
|
|
||||||
1. - [ 简单的窗口贴边隐藏](简单的窗口贴边隐藏/)
|
|
||||||
1. - [ 验证码控件](验证码控件/)
|
|
||||||
1. - [ 消息提示](消息提示/)
|
|
||||||
1. - 悬浮下拉菜单
|
|
||||||
- [ tableWidget形式](partner_625781186/5.hoverMenu)
|
|
||||||
|
|
||||||
#### 2.3 其他案例
|
|
||||||
- [ 人脸描点检测](人脸描点检测/)
|
|
||||||
- [ 网络操作](网络操作/)
|
|
||||||
- [ 窗口和异步asyncio http](窗口配合异步Http/)
|
|
||||||
- [ QRC资源文件使用](QRC资源文件使用/)
|
|
||||||
- [ C和C++扩展](C和C++扩展/)
|
|
||||||
- [.1 pyx和c++](C和C++扩展/pyx和c++/)
|
|
||||||
- [.2 py转pyd](C和C++扩展/py转pyd/)
|
|
||||||
- [.3 pydext](C和C++扩展/pydext/)
|
|
||||||
|
|
||||||
### III、 界面型
|
|
||||||
|
|
||||||
#### 3.1 [美化类](界面美化/)
|
|
||||||
1. - [ 字体测试](字体测试/)
|
|
||||||
1. - [ 自定义QWidget的QSS样式](自定义QWidget的QSS样式/)
|
|
||||||
1. - [ QSS美化例子](界面美化/QSS美化例子)
|
|
||||||
1. - [ Flat Style](https://github.com/892768447/QFlat)
|
|
||||||
1. - [ QMessageBox样式](界面美化/QMessageBox样式)
|
|
||||||
1. - [ QScrollBar滚动条样式](界面美化/QScrollBar滚动条样式)
|
|
||||||
1. - [ QLabel圆形头像](界面美化/QLabel圆形头像)
|
|
||||||
1. - [ QFileSystemModel图标](界面美化/QFileSystemModel图标)
|
|
||||||
1. - [ QPushButton进度动画](界面美化/QPushButton进度动画)
|
|
||||||
1. - [ QSlider美化](界面美化/QSlider美化)
|
|
||||||
1. - [ 各类进度条](界面美化/各类进度条)
|
|
||||||
1. - [ 动态边框阴影动画](界面美化/边框动画阴影)
|
|
||||||
|
|
||||||
#### 3.2 [动画类](动画特效/)
|
|
||||||
1. - [ 气泡提示 上升渐隐](消息提示/)
|
|
||||||
1. - [ 折叠动画效果](partner_625781186/2.折叠控件/)
|
|
||||||
1. - [ 淡入淡出](动画特效/)
|
|
||||||
1. - [ 右键菜单动画](动画特效/)
|
|
||||||
1. - [ 水波纹进度条](界面美化/水波纹进度条)
|
|
||||||
|
|
||||||
### IV、图表型
|
|
||||||
#### 4.1 [ QGraphicsView练习](QGraphicsView练习/)
|
|
||||||
- [ 世界地图](QGraphicsView练习/世界地图)
|
|
||||||
- [ 添加QWidget](QGraphicsView练习/添加QWidget.py)
|
|
||||||
- [ QChartToolTipTest](QGraphicsView练习/QChartToolTipTest.py)
|
|
||||||
|
|
||||||
#### 4.2 [ PyQtChart练习](PyQtChart练习/)
|
|
||||||
- [ charts](PyQtChart练习/charts)
|
|
||||||
- [ test](PyQtChart练习/test)
|
|
||||||
|
|
||||||
|
|
||||||
### V、[QML](partner_625781186/QML_QtQuick_PY)
|
|
||||||
- [python_QML调用基础](partner_625781186/QML_QtQuick_PY/python_QML调用基础)
|
|
||||||
- QWidget窗体中嵌入qml界面
|
|
||||||
- [QDialog中嵌入qml窗体并缩放](partner_625781186/QML_QtQuick_PY/QDialog中嵌入qml窗体并缩放)
|
|
||||||
- [QQmlApplicationEngine之qml嵌入qtwidget_qt以上](partner_625781186/QML_QtQuick_PY/QQmlApplicationEngine之qml嵌入qtwidget_qt以上)
|
|
||||||
|
|
||||||
|
|
||||||
# QQ群
|
|
||||||
- [PyQt & PySide](https://jq.qq.com/?_wv=1027&k=50LWvn9)
|
|
||||||
- [PyQt学习互助](https://jq.qq.com/?_wv=1027&k=5QVVEdF)
|
|
||||||
- [PyQt5小组](https://jq.qq.com/?_wv=1027&k=5cI3oRz)
|
|
||||||
|
|
||||||
|
|
||||||
# [Donate-打赏](Donate/)
|
|
||||||
|
|
||||||
# Wiki
|
|
||||||
- [一些Qt写的三方APP](https://github.com/892768447/PyQt/wiki/3rd-party-applications)
|
|
|
@ -1,21 +0,0 @@
|
||||||
# 浏览器
|
|
||||||
|
|
||||||
## [1、QWebView](QWebView)
|
|
||||||
|
|
||||||
### 1. [梦幻树](QWebView/梦幻树)
|
|
||||||
在桌面上显示透明html效果,使用`QWebkit`加载html实现,采用窗口背景透明和穿透方式
|
|
||||||
|
|
||||||
![截图](QWebView/梦幻树/ScreenShot/梦幻树.png)
|
|
||||||
|
|
||||||
### 2. [获取Cookie](QWebView/获取Cookie)
|
|
||||||
`QWebView`很简单,从`page()`中得到`QNetworkAccessManager`,在从中得到`QNetworkCookieJar`,
|
|
||||||
最后得到cookie,当然也可以设置自己的`QNetworkCookieJar`
|
|
||||||
|
|
||||||
![截图](QWebView/获取Cookie/ScreenShot/获取Cookie.png)
|
|
||||||
|
|
||||||
## [2、QWebEngineView](QWebEngineView)
|
|
||||||
|
|
||||||
### 1. [获取Cookie](QWebEngineView/获取Cookie)
|
|
||||||
`QWebEngineView`的话目前是通过`QWebEngineProfile`中得到的`cookieStore`并绑定它的`cookieAdded`信号来得到Cookie
|
|
||||||
|
|
||||||
![截图](QWebEngineView/获取Cookie/ScreenShot/获取Cookie.png)
|
|
|
@ -1,37 +0,0 @@
|
||||||
# 滑动条
|
|
||||||
|
|
||||||
## [1、滑动条点击定位](滑动条点击定位.py)
|
|
||||||
|
|
||||||
1. `QSlider`对鼠标点击然后跳转到该位置的支持不是很好,通过重写鼠标点击事件`mousePressEvent`来达到效果
|
|
||||||
1. 通过`style`的`subControlRect`方法计算得到滑块的区域,当鼠标点击区域在此次时则交给系统自己处理(比如按住不放拖动)
|
|
||||||
1. 通过`orientation`判断滑动条的方向(横竖)
|
|
||||||
1. 通过`invertedAppearance`判断滑动条是否反向(左右、上下)
|
|
||||||
|
|
||||||
核心代码:
|
|
||||||
|
|
||||||
```python
|
|
||||||
def mousePressEvent(self, event):
|
|
||||||
# 获取上面的拉动块位置
|
|
||||||
option = QStyleOptionSlider()
|
|
||||||
self.initStyleOption(option)
|
|
||||||
rect = self.style().subControlRect(
|
|
||||||
QStyle.CC_Slider, option, QStyle.SC_SliderHandle, self)
|
|
||||||
if rect.contains(event.pos()):
|
|
||||||
# 如果鼠标点击的位置在滑块上则交给Qt自行处理
|
|
||||||
super(JumpSlider, self).mousePressEvent(event)
|
|
||||||
return
|
|
||||||
if self.orientation() == Qt.Horizontal:
|
|
||||||
# 横向,要考虑invertedAppearance是否反向显示的问题
|
|
||||||
self.setValue(self.style().sliderValueFromPosition(
|
|
||||||
self.minimum(), self.maximum(),
|
|
||||||
event.x() if not self.invertedAppearance() else (self.width(
|
|
||||||
) - event.x()), self.width()))
|
|
||||||
else:
|
|
||||||
# 纵向
|
|
||||||
self.setValue(self.style().sliderValueFromPosition(
|
|
||||||
self.minimum(), self.maximum(),
|
|
||||||
(self.height() - event.y()) if not self.invertedAppearance(
|
|
||||||
) else event.y(), self.height()))
|
|
||||||
```
|
|
||||||
|
|
||||||
![截图](ScreenShot/滑动条点击定位.gif)
|
|
|
@ -1 +0,0 @@
|
||||||
# 按钮
|
|
|
@ -1 +0,0 @@
|
||||||
# 按钮
|
|
|
@ -1,10 +0,0 @@
|
||||||
# 表格控件 QTableView
|
|
||||||
|
|
||||||
## [1、表格内容复制](表格内容复制.py)
|
|
||||||
|
|
||||||
1. 通过构造一个和选中区域一样的空数组,然后对数组进行填充形成表格
|
|
||||||
1. 最后循环数组用`\t`进行拼接`join`,换行用`\r\n`
|
|
||||||
1. 把字符串复制到剪切板中
|
|
||||||
|
|
||||||
![截图](ScreenShot/表格内容复制1.png)![截图](ScreenShot/表格内容复制2.png)
|
|
||||||
|
|
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 14 KiB |
|
@ -1,107 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
'''
|
|
||||||
Created on 2017年4月6日
|
|
||||||
@author: Irony."[讽刺]
|
|
||||||
@site: https://pyqt5.com, https://github.com/892768447
|
|
||||||
@email: 892768447@qq.com
|
|
||||||
@file: TableView
|
|
||||||
@description:
|
|
||||||
'''
|
|
||||||
from PyQt5.QtCore import Qt
|
|
||||||
from PyQt5.QtGui import QStandardItemModel, QStandardItem
|
|
||||||
from PyQt5.QtWidgets import QTableView, QApplication, QAction, QMessageBox
|
|
||||||
|
|
||||||
|
|
||||||
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
|
|
||||||
__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]"
|
|
||||||
__Version__ = "Version 1.0"
|
|
||||||
|
|
||||||
|
|
||||||
class TableView(QTableView):
|
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
|
||||||
super(TableView, self).__init__(parent)
|
|
||||||
self.resize(800, 600)
|
|
||||||
self.setContextMenuPolicy(Qt.ActionsContextMenu) # 右键菜单
|
|
||||||
self.setEditTriggers(self.NoEditTriggers) # 禁止编辑
|
|
||||||
self.doubleClicked.connect(self.onDoubleClick)
|
|
||||||
self.addAction(QAction("复制", self, triggered=self.copyData))
|
|
||||||
self.myModel = QStandardItemModel() # model
|
|
||||||
self.initHeader() # 初始化表头
|
|
||||||
self.setModel(self.myModel)
|
|
||||||
self.initData() # 初始化模拟数据
|
|
||||||
|
|
||||||
def onDoubleClick(self, index):
|
|
||||||
print(index.row(), index.column(), index.data())
|
|
||||||
|
|
||||||
def keyPressEvent(self, event):
|
|
||||||
super(TableView, self).keyPressEvent(event)
|
|
||||||
# Ctrl + C
|
|
||||||
if event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_C:
|
|
||||||
self.copyData()
|
|
||||||
|
|
||||||
def copyData(self):
|
|
||||||
count = len(self.selectedIndexes())
|
|
||||||
if count == 0:
|
|
||||||
return
|
|
||||||
if count == 1: # 只复制了一个
|
|
||||||
QApplication.clipboard().setText(
|
|
||||||
self.selectedIndexes()[0].data()) # 复制到剪贴板中
|
|
||||||
QMessageBox.information(self, "提示", "已复制一个数据")
|
|
||||||
return
|
|
||||||
rows = set()
|
|
||||||
cols = set()
|
|
||||||
for index in self.selectedIndexes(): # 得到所有选择的
|
|
||||||
rows.add(index.row())
|
|
||||||
cols.add(index.column())
|
|
||||||
# print(index.row(),index.column(),index.data())
|
|
||||||
if len(rows) == 1: # 一行
|
|
||||||
QApplication.clipboard().setText("\t".join(
|
|
||||||
[index.data() for index in self.selectedIndexes()])) # 复制
|
|
||||||
QMessageBox.information(self, "提示", "已复制一行数据")
|
|
||||||
return
|
|
||||||
if len(cols) == 1: # 一列
|
|
||||||
QApplication.clipboard().setText("\r\n".join(
|
|
||||||
[index.data() for index in self.selectedIndexes()])) # 复制
|
|
||||||
QMessageBox.information(self, "提示", "已复制一列数据")
|
|
||||||
return
|
|
||||||
mirow, marow = min(rows), max(rows) # 最(少/多)行
|
|
||||||
micol, macol = min(cols), max(cols) # 最(少/多)列
|
|
||||||
print(mirow, marow, micol, macol)
|
|
||||||
arrays = [
|
|
||||||
[
|
|
||||||
"" for _ in range(macol - micol + 1)
|
|
||||||
] for _ in range(marow - mirow + 1)
|
|
||||||
] # 创建二维数组(并排除前面的空行和空列)
|
|
||||||
print(arrays)
|
|
||||||
# 填充数据
|
|
||||||
for index in self.selectedIndexes(): # 遍历所有选择的
|
|
||||||
arrays[index.row() - mirow][index.column() - micol] = index.data()
|
|
||||||
print(arrays)
|
|
||||||
data = "" # 最后的结果
|
|
||||||
for row in arrays:
|
|
||||||
data += "\t".join(row) + "\r\n"
|
|
||||||
print(data)
|
|
||||||
QApplication.clipboard().setText(data) # 复制到剪贴板中
|
|
||||||
QMessageBox.information(self, "提示", "已复制")
|
|
||||||
|
|
||||||
def initHeader(self):
|
|
||||||
for i in range(5):
|
|
||||||
self.myModel.setHorizontalHeaderItem(
|
|
||||||
i, QStandardItem("表头" + str(i + 1)))
|
|
||||||
|
|
||||||
def initData(self):
|
|
||||||
for row in range(100):
|
|
||||||
for col in range(5):
|
|
||||||
self.myModel.setItem(
|
|
||||||
row, col, QStandardItem("row: {row},col: {col}".format(row=row + 1, col=col + 1)))
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import sys
|
|
||||||
app = QApplication(sys.argv)
|
|
||||||
app.setApplicationName("TableView")
|
|
||||||
w = TableView()
|
|
||||||
w.show()
|
|
||||||
sys.exit(app.exec_())
|
|
|
@ -1,7 +0,0 @@
|
||||||
# 表格控件 QTableWidget
|
|
||||||
|
|
||||||
[1、Sqlalchemy动态拼接字段查询显示表格](数据库查询显示表格)
|
|
||||||
|
|
||||||
通过判断界面中选择的条件对`Sqlalchemy`的`model`进行字段拼接从而实现按条件查询
|
|
||||||
|
|
||||||
![截图](数据库查询显示表格/ScreenShot/数据库查询显示表格.png)
|
|
Before Width: | Height: | Size: 31 KiB |
|
@ -1,149 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
Created on 2018年5月15日
|
|
||||||
@author: Irony
|
|
||||||
@site: https://pyqt5.com, https://github.com/892768447
|
|
||||||
@email: 892768447@qq.com
|
|
||||||
@file: 数据库查询显示表格.main
|
|
||||||
@description:
|
|
||||||
"""
|
|
||||||
from PyQt5.QtCore import pyqtSlot
|
|
||||||
from PyQt5.QtWidgets import QWidget, QMessageBox, QTableWidgetItem
|
|
||||||
from sqlalchemy.engine import create_engine
|
|
||||||
from sqlalchemy.ext.declarative.api import declarative_base
|
|
||||||
from sqlalchemy.orm.session import sessionmaker
|
|
||||||
from sqlalchemy.sql.expression import and_
|
|
||||||
from sqlalchemy.sql.schema import Column
|
|
||||||
from sqlalchemy.sql.sqltypes import Integer, Text
|
|
||||||
from mainui import Ui_Form
|
|
||||||
|
|
||||||
__Author__ = """By: Irony
|
|
||||||
QQ: 892768447
|
|
||||||
Email: 892768447@qq.com"""
|
|
||||||
__Copyright__ = "Copyright (c) 2018 Irony"
|
|
||||||
__Version__ = "Version 1.0"
|
|
||||||
|
|
||||||
# engine = create_engine('mysql+mysqldb://root@localhost:3306/tourist?charset=utf8')
|
|
||||||
engine = create_engine('sqlite:///data.sqlite3', echo=True) # echo 表示开启命令显示
|
|
||||||
Base = declarative_base()
|
|
||||||
|
|
||||||
|
|
||||||
class Tourist(Base):
|
|
||||||
|
|
||||||
__tablename__ = 'tourist'
|
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True)
|
|
||||||
name = Column(Text)
|
|
||||||
license = Column(Text)
|
|
||||||
flightnumber = Column(Text)
|
|
||||||
flightdate = Column(Text)
|
|
||||||
seatnumber = Column(Text)
|
|
||||||
boardingport = Column(Text)
|
|
||||||
no = Column(Text)
|
|
||||||
departurestation = Column(Text)
|
|
||||||
destinationstation = Column(Text)
|
|
||||||
|
|
||||||
|
|
||||||
class Window(QWidget, Ui_Form):
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(Window, self).__init__(*args, **kwargs)
|
|
||||||
self.setupUi(self)
|
|
||||||
# sql的拼接字段
|
|
||||||
self.sql = {}
|
|
||||||
# 数据库连接
|
|
||||||
self.session = sessionmaker(bind=engine)()
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def on_pushButtonQuery_clicked(self):
|
|
||||||
"""查询按钮"""
|
|
||||||
self.applyName()
|
|
||||||
self.applySeat()
|
|
||||||
self.applyLicense()
|
|
||||||
self.applyPort()
|
|
||||||
if not self.sql:
|
|
||||||
return QMessageBox.warning(self, '提示', '没有进行任何输入')
|
|
||||||
# 清空数据
|
|
||||||
self.tableWidget.clear()
|
|
||||||
# 重新设置表头
|
|
||||||
self.tableWidget.setHorizontalHeaderLabels(
|
|
||||||
['编号', '姓名', '证件号', '航班号', '航班日期', '座位号', '登机口', '序号', '出发地', '目的地'])
|
|
||||||
# 根据选择的字段进行并列查询
|
|
||||||
rets = self.session.query(Tourist).filter(
|
|
||||||
and_(*(key == value for key, value in self.sql.items()))).all()
|
|
||||||
if not rets:
|
|
||||||
return QMessageBox.information(self, '提示', '未查询到结果')
|
|
||||||
self.tableWidget.setRowCount(len(rets))
|
|
||||||
# 根据查询结果添加到表格中
|
|
||||||
for row, tourist in enumerate(rets):
|
|
||||||
self.tableWidget.setItem(row, 0, QTableWidgetItem(str(tourist.id)))
|
|
||||||
self.tableWidget.setItem(
|
|
||||||
row, 1, QTableWidgetItem(str(tourist.name)))
|
|
||||||
self.tableWidget.setItem(
|
|
||||||
row, 2, QTableWidgetItem(str(tourist.license)))
|
|
||||||
self.tableWidget.setItem(
|
|
||||||
row, 3, QTableWidgetItem(str(tourist.flightnumber)))
|
|
||||||
self.tableWidget.setItem(
|
|
||||||
row, 4, QTableWidgetItem(str(tourist.flightdate)))
|
|
||||||
self.tableWidget.setItem(
|
|
||||||
row, 5, QTableWidgetItem(str(tourist.seatnumber)))
|
|
||||||
self.tableWidget.setItem(
|
|
||||||
row, 6, QTableWidgetItem(str(tourist.boardingport)))
|
|
||||||
self.tableWidget.setItem(row, 7, QTableWidgetItem(str(tourist.no)))
|
|
||||||
self.tableWidget.setItem(
|
|
||||||
row, 8, QTableWidgetItem(str(tourist.departurestation)))
|
|
||||||
self.tableWidget.setItem(
|
|
||||||
row, 9, QTableWidgetItem(str(tourist.destinationstation)))
|
|
||||||
|
|
||||||
def applyName(self):
|
|
||||||
"""姓名"""
|
|
||||||
if not self.checkBoxName.isChecked():
|
|
||||||
if Tourist.name in self.sql:
|
|
||||||
# 移除
|
|
||||||
self.sql.pop(Tourist.name)
|
|
||||||
# 更新或添加到字典里
|
|
||||||
else:
|
|
||||||
self.sql[Tourist.name] = self.lineEditName.text().strip()
|
|
||||||
|
|
||||||
def applySeat(self):
|
|
||||||
"""座位号"""
|
|
||||||
if not self.checkBoxSeat.isChecked():
|
|
||||||
if Tourist.seatnumber in self.sql:
|
|
||||||
# 移除
|
|
||||||
self.sql.pop(Tourist.seatnumber)
|
|
||||||
# 更新或添加到字典里
|
|
||||||
else:
|
|
||||||
self.sql[Tourist.seatnumber] = self.lineEditSeat.text().strip()
|
|
||||||
|
|
||||||
def applyLicense(self):
|
|
||||||
"""证件号"""
|
|
||||||
if not self.checkBoxLicense.isChecked():
|
|
||||||
if Tourist.license in self.sql:
|
|
||||||
# 移除
|
|
||||||
self.sql.pop(Tourist.license)
|
|
||||||
# 更新或添加到字典里
|
|
||||||
else:
|
|
||||||
self.sql[Tourist.license] = self.lineEditLicense.text().strip()
|
|
||||||
|
|
||||||
def applyPort(self):
|
|
||||||
"""登机口"""
|
|
||||||
if not self.checkBoxPort.isChecked():
|
|
||||||
if Tourist.boardingport in self.sql:
|
|
||||||
# 移除
|
|
||||||
self.sql.pop(Tourist.boardingport)
|
|
||||||
# 更新或添加到字典里
|
|
||||||
else:
|
|
||||||
self.sql[Tourist.boardingport] = self.lineEditPort.text().strip()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
import sys
|
|
||||||
import cgitb
|
|
||||||
sys.excepthook = cgitb.Hook(1, None, 5, sys.stderr, 'text')
|
|
||||||
from PyQt5.QtWidgets import QApplication
|
|
||||||
app = QApplication(sys.argv)
|
|
||||||
w = Window()
|
|
||||||
w.show()
|
|
||||||
sys.exit(app.exec_())
|
|
|
@ -1,111 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'mainui.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_Form(object):
|
|
||||||
def setupUi(self, Form):
|
|
||||||
Form.setObjectName("Form")
|
|
||||||
Form.resize(400, 362)
|
|
||||||
self.gridLayout = QtWidgets.QGridLayout(Form)
|
|
||||||
self.gridLayout.setObjectName("gridLayout")
|
|
||||||
self.checkBoxName = QtWidgets.QCheckBox(Form)
|
|
||||||
self.checkBoxName.setObjectName("checkBoxName")
|
|
||||||
self.gridLayout.addWidget(self.checkBoxName, 0, 0, 1, 1)
|
|
||||||
self.checkBoxSeat = QtWidgets.QCheckBox(Form)
|
|
||||||
self.checkBoxSeat.setObjectName("checkBoxSeat")
|
|
||||||
self.gridLayout.addWidget(self.checkBoxSeat, 0, 2, 1, 1)
|
|
||||||
self.lineEditName = QtWidgets.QLineEdit(Form)
|
|
||||||
self.lineEditName.setObjectName("lineEditName")
|
|
||||||
self.gridLayout.addWidget(self.lineEditName, 0, 1, 1, 1)
|
|
||||||
self.tableWidget = QtWidgets.QTableWidget(Form)
|
|
||||||
self.tableWidget.setObjectName("tableWidget")
|
|
||||||
self.tableWidget.setColumnCount(10)
|
|
||||||
self.tableWidget.setRowCount(0)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(0, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(1, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(2, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(3, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(4, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(5, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(6, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(7, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(8, item)
|
|
||||||
item = QtWidgets.QTableWidgetItem()
|
|
||||||
self.tableWidget.setHorizontalHeaderItem(9, item)
|
|
||||||
self.gridLayout.addWidget(self.tableWidget, 3, 0, 1, 4)
|
|
||||||
self.lineEditSeat = QtWidgets.QLineEdit(Form)
|
|
||||||
self.lineEditSeat.setObjectName("lineEditSeat")
|
|
||||||
self.gridLayout.addWidget(self.lineEditSeat, 0, 3, 1, 1)
|
|
||||||
self.lineEditPort = QtWidgets.QLineEdit(Form)
|
|
||||||
self.lineEditPort.setObjectName("lineEditPort")
|
|
||||||
self.gridLayout.addWidget(self.lineEditPort, 1, 3, 1, 1)
|
|
||||||
self.checkBoxPort = QtWidgets.QCheckBox(Form)
|
|
||||||
self.checkBoxPort.setObjectName("checkBoxPort")
|
|
||||||
self.gridLayout.addWidget(self.checkBoxPort, 1, 2, 1, 1)
|
|
||||||
self.checkBoxLicense = QtWidgets.QCheckBox(Form)
|
|
||||||
self.checkBoxLicense.setObjectName("checkBoxLicense")
|
|
||||||
self.gridLayout.addWidget(self.checkBoxLicense, 1, 0, 1, 1)
|
|
||||||
self.lineEditLicense = QtWidgets.QLineEdit(Form)
|
|
||||||
self.lineEditLicense.setObjectName("lineEditLicense")
|
|
||||||
self.gridLayout.addWidget(self.lineEditLicense, 1, 1, 1, 1)
|
|
||||||
self.pushButtonQuery = QtWidgets.QPushButton(Form)
|
|
||||||
self.pushButtonQuery.setObjectName("pushButtonQuery")
|
|
||||||
self.gridLayout.addWidget(self.pushButtonQuery, 2, 0, 1, 4)
|
|
||||||
|
|
||||||
self.retranslateUi(Form)
|
|
||||||
QtCore.QMetaObject.connectSlotsByName(Form)
|
|
||||||
|
|
||||||
def retranslateUi(self, Form):
|
|
||||||
_translate = QtCore.QCoreApplication.translate
|
|
||||||
Form.setWindowTitle(_translate("Form", "Form"))
|
|
||||||
self.checkBoxName.setText(_translate("Form", "姓名"))
|
|
||||||
self.checkBoxSeat.setText(_translate("Form", "座位号"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(0)
|
|
||||||
item.setText(_translate("Form", "编号"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(1)
|
|
||||||
item.setText(_translate("Form", "姓名"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(2)
|
|
||||||
item.setText(_translate("Form", "证件号"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(3)
|
|
||||||
item.setText(_translate("Form", "航班号"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(4)
|
|
||||||
item.setText(_translate("Form", "航班日期"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(5)
|
|
||||||
item.setText(_translate("Form", "座位号"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(6)
|
|
||||||
item.setText(_translate("Form", "登机口"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(7)
|
|
||||||
item.setText(_translate("Form", "序号"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(8)
|
|
||||||
item.setText(_translate("Form", "出发地"))
|
|
||||||
item = self.tableWidget.horizontalHeaderItem(9)
|
|
||||||
item.setText(_translate("Form", "目的地"))
|
|
||||||
self.checkBoxPort.setText(_translate("Form", "登机口"))
|
|
||||||
self.checkBoxLicense.setText(_translate("Form", "证件号"))
|
|
||||||
self.pushButtonQuery.setText(_translate("Form", "查询"))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import sys
|
|
||||||
app = QtWidgets.QApplication(sys.argv)
|
|
||||||
Form = QtWidgets.QWidget()
|
|
||||||
ui = Ui_Form()
|
|
||||||
ui.setupUi(Form)
|
|
||||||
Form.show()
|
|
||||||
sys.exit(app.exec_())
|
|
||||||
|
|
|
@ -1,122 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>Form</class>
|
|
||||||
<widget class="QWidget" name="Form">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>400</width>
|
|
||||||
<height>362</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Form</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QCheckBox" name="checkBoxName">
|
|
||||||
<property name="text">
|
|
||||||
<string>姓名</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2">
|
|
||||||
<widget class="QCheckBox" name="checkBoxSeat">
|
|
||||||
<property name="text">
|
|
||||||
<string>座位号</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLineEdit" name="lineEditName"/>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0" colspan="4">
|
|
||||||
<widget class="QTableWidget" name="tableWidget">
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>编号</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>姓名</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>证件号</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>航班号</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>航班日期</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>座位号</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>登机口</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>序号</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>出发地</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>目的地</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="3">
|
|
||||||
<widget class="QLineEdit" name="lineEditSeat"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="3">
|
|
||||||
<widget class="QLineEdit" name="lineEditPort"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="2">
|
|
||||||
<widget class="QCheckBox" name="checkBoxPort">
|
|
||||||
<property name="text">
|
|
||||||
<string>登机口</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QCheckBox" name="checkBoxLicense">
|
|
||||||
<property name="text">
|
|
||||||
<string>证件号</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLineEdit" name="lineEditLicense"/>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0" colspan="4">
|
|
||||||
<widget class="QPushButton" name="pushButtonQuery">
|
|
||||||
<property name="text">
|
|
||||||
<string>查询</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
|
@ -1 +0,0 @@
|
||||||
# 按钮
|
|
|
@ -1,8 +0,0 @@
|
||||||
# 输入框
|
|
||||||
|
|
||||||
## [1、QTextEdit](QTextEdit/)
|
|
||||||
|
|
||||||
### 1. [文本查找高亮](QTextEdit/简单查找文字并高亮.py)
|
|
||||||
主要用到`mergeCurrentCharFormat`函数
|
|
||||||
|
|
||||||
![截图](QTextEdit/ScreenShot/简单查找文字并高亮.gif)
|
|
|
@ -1 +0,0 @@
|
||||||
# 按钮
|
|