Pyqt5之代码碎片
- 1) 创建主窗口
- 2)让主窗口居中显示
- 3)退出应用程序
- 4)屏幕坐标系
- 5) 设置窗口和应用程序图标
- 6) 为控件添加提示信息
- 7) QLabel控件的基本用法
- 8) QLabel与伙伴关系
- 9)QLine控件与回显模式
- 10)限制QlineEdit控件的输入(校验器)
- 11)使用掩码限制QlineEdit控件输入
- 12)QLineEdit控件综合案例
- 13)使用QTextEdit控件输入多行文本
- 14) 按钮控件(QPushButton)
- 15)单选按钮控件(QRadioButton)
- 16) 复选框控件(QCheckBox)
- 17)下拉列表控件(QComboBox)
- 18) 滑块控件(QSlider)
- 19)计数器控件(QSpinBox)
- 对话框
- 绘图API
- 菜单栏,工具栏,状态栏
- 使用打印机
- 二维表
- 容器控件
- 多线程
- web交互技术
- 布局
1) 创建主窗口
import sys
from PyQt5.QtWidgets import QMainWindow,QApplication
from PyQt5.QtGui import QIcon
class FirstMainWin(QMainWindow):
def __init__(self):
super(FirstMainWin,self).__init__()
# 设置主窗口的标题
self.setWindowTitle('第一个主窗口应用')
# 设置窗口的尺寸
self.resize(400,300)
self.status = self.statusBar()
self.status.showMessage('只存在5秒的消息',5000)
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setWindowIcon(QIcon('./images/Dragon.ico'))
main = FirstMainWin()
main.show()
sys.exit(app.exec_())
2)让主窗口居中显示
# QDesktopWidget
import sys
from PyQt5.QtWidgets import QDesktopWidget,QMainWindow,QApplication
from PyQt5.QtGui import QIcon
class CenterForm(QMainWindow):
def __init__(self):
super(CenterForm,self).__init__()
# 设置主窗口的标题
self.setWindowTitle('让窗口居中')
# 设置窗口的尺寸
self.resize(400,300)
def center(self):
# 获取屏幕坐标系
screen = QDesktopWidget().screenGeometry()
# 获取窗口坐标系
size = self.geometry()
newLeft = (screen.width() - size.width()) / 2
newTop = (screen.height() - size.height()) / 2
self.move(newLeft,newTop)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = CenterForm()
main.show()
sys.exit(app.exec_())
3)退出应用程序
import sys
from PyQt5.QtWidgets import QHBoxLayout,QMainWindow,QApplication,QPushButton,QWidget
class QuitApplication(QMainWindow):
def __init__(self):
super(QuitApplication,self).__init__()
self.resize(300,120)
self.setWindowTitle('退出应用程序')
# 添加Button
self.button1 = QPushButton('退出应用程序')
# 将信号与槽关联
self.button1.clicked.connect(self.onClick_Button)
layout = QHBoxLayout()
layout.addWidget(self.button1)
mainFrame = QWidget()
mainFrame.setLayout(layout)
self.setCentralWidget(mainFrame)
# 按钮单击事件的方法(自定义的槽)
def onClick_Button(self):
sender = self.sender() # 发送者,这里指按钮
print(sender.text() + ' 按钮被按下')
app = QApplication.instance()
# 退出应用程序
app.quit()
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QuitApplication()
main.show()
sys.exit(app.exec_())
4)屏幕坐标系
import sys
from PyQt5.QtWidgets import QHBoxLayout,QMainWindow,QApplication,QPushButton,QWidget
def onClick_Button():
print("1")
print("widget.x() = %d" % widget.x()) # 250 (窗口横坐标)
print("widget.y() = %d" % widget.y()) # 200 (窗口纵坐标)
print("widget.width() = %d" % widget.width()) # 300(工作区宽度)
print("widget.height() = %d" % widget.height()) # 240 (工作区高度)
print("2")
print("widget.geometry().x() = %d" % widget.geometry().x()) # 250 (工作区横坐标)
print("widget.geometry().y() = %d" % widget.geometry().y()) # 222 (工作区纵坐标)
print("widget.geometry().width() = %d" % widget.geometry().width() ) # 300(工作区宽度)
print("widget.geometry().height() = %d" % widget.geometry().height()) # 240 (工作区高度)
print("3")
print("widget.frameGeometry().x() = %d" % widget.frameGeometry().x()) # 250 (窗口横坐标)
print("widget.frameGeometry().y() = %d" % widget.frameGeometry().y()) # 200 (窗口纵坐标)
print("widget.frameGeometry().width() = %d" % widget.frameGeometry().width() ) # 300(窗口宽度)
print("widget.frameGeometry().height() = %d" % widget.frameGeometry().height()) # 262(窗口高度)
app = QApplication(sys.argv)
widget = QWidget()
btn = QPushButton(widget)
btn.setText("按钮")
btn.clicked.connect(onClick_Button)
btn.move(24,52)
widget.resize(300,240) # 设置工作区的尺寸
widget.move(250,200)
widget.setWindowTitle('屏幕坐标系')
widget.show()
sys.exit(app.exec_())
5) 设置窗口和应用程序图标
import sys
from PyQt5.QtWidgets import QMainWindow,QApplication
from PyQt5.QtGui import QIcon
'''
窗口的setWindowIcon方法用于设置窗口的图标,只在Windows中可用
QAplication中的setWindowIcon方法用于设置主窗口的图标和应用程序图标,但调用了窗口的setWindowIcon方法
QAplication中的setWindowIcon方法就只能用于设置应用程序图标了
'''
class IconForm(QMainWindow):
def __init__(self):
super(IconForm,self).__init__()
self.initUI()
def initUI(self):
self.setGeometry(300,300,250,250)
# 设置主窗口的标题
self.setWindowTitle('设置窗口图标')
# 设置窗口图标
self.setWindowIcon(QIcon('./images/Basilisk.ico'))
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setWindowIcon(QIcon('./images/Dragon.ico'))
main = IconForm()
main.show()
sys.exit(app.exec_())
6) 为控件添加提示信息
# 显示控件提示消息
import sys
from PyQt5.QtWidgets import QHBoxLayout,QMainWindow,QApplication,QToolTip,QPushButton,QWidget
from PyQt5.QtGui import QFont
class TooltipForm(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
QToolTip.setFont(QFont('SansSerif',12))
self.setToolTip('今天是<b>星期五</b>')
self.setGeometry(300,30,200,300)
self.setWindowTitle('设置控件提示消息')
self.button1 = QPushButton('我的按钮')
self.button1.setToolTip('这是一个按钮,Are you ok?')
layout = QHBoxLayout()
layout.addWidget(self.button1)
mainFrame = QWidget()
mainFrame.setLayout(layout)
self.setCentralWidget(mainFrame)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = TooltipForm()
main.show()
sys.exit(app.exec_())
7) QLabel控件的基本用法
'''
QLabel控件
setAlignment():设置文本的对齐方式
setIndent():设置文本缩进
text():获取文本内容
setBuddy():设置伙伴关系
setText():设置文本内容
selectedText():返回所选择的字符
setWordWrap():设置是否允许换行
QLabel常用的信号(事件):
1. 当鼠标滑过QLabel控件时触发:linkHovered
2. 当鼠标单击QLabel控件时触发:linkActivated
'''
import sys
from PyQt5.QtWidgets import QVBoxLayout,QMainWindow,QApplication,QLabel,QWidget
from PyQt5.QtGui import QPixmap, QPalette
from PyQt5.QtCore import Qt
class QLabelDemo(QWidget) :
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
label1 = QLabel(self)
label2 = QLabel(self)
label3 = QLabel(self)
label4 = QLabel(self)
label1.setText("<font color=yellow>这是一个文本标签.</font>")
label1.setAutoFillBackground(True)
palette = QPalette()
palette.setColor(QPalette.Window,Qt.blue) # 设置背景色
label1.setPalette(palette)
label1.setAlignment(Qt.AlignCenter)
label2.setText("<a href='#'>欢迎使用Python GUI程序</a>")
label3.setAlignment(Qt.AlignCenter)
label3.setToolTip('这是一个图片标签')
label3.setPixmap(QPixmap("./images/python.jpg"))
# 如果设为True,用浏览器打开网页,如果设为False,调用槽函数
label4.setOpenExternalLinks(True)
label4.setText("<a href='https://blog.csdn.net/weixin_45651336?spm=1001.2014.3001.5343'>感谢关注《Python从菜鸟到高手》</a>")
label4.setAlignment(Qt.AlignRight)
label4.setToolTip('这是一个超级链接')
vbox = QVBoxLayout()
vbox.addWidget(label1)
vbox.addWidget(label2)
vbox.addWidget(label3)
vbox.addWidget(label4)
label2.linkHovered.connect(self.linkHovered)
label4.linkActivated.connect(self.linkClicked)
self.setLayout(vbox)
self.setWindowTitle('QLabel控件演示')
def linkHovered(self):
print('当鼠标滑过label2标签时,触发事件')
def linkClicked(self):
print('当鼠标单击label4标签时,触发事件')
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QLabelDemo()
main.show()
sys.exit(app.exec_())
8) QLabel与伙伴关系
'''
QLabel与伙伴控件
mainLayout.addWidget(控件对象,rowIndex,columnIndex,row,column)
'''
from PyQt5.QtWidgets import *
import sys
class QLabelBuddy(QDialog) :
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('QLabel与伙伴控件')
nameLabel = QLabel('&Name',self)
nameLineEdit = QLineEdit(self)
# 设置伙伴控件
nameLabel.setBuddy(nameLineEdit)
passwordLabel = QLabel('&Password',self)
passwordLineEdit = QLineEdit(self)
# 设置伙伴控件
passwordLabel.setBuddy(passwordLineEdit)
btnOK = QPushButton('&OK')
btnCancel = QPushButton('&Cancel')
mainLayout = QGridLayout(self)
mainLayout.addWidget(nameLabel,0,0)
mainLayout.addWidget(nameLineEdit,0,1,1,2)
mainLayout.addWidget(passwordLabel,1,0)
mainLayout.addWidget(passwordLineEdit,1,1,1,2)
mainLayout.addWidget(btnOK,2,1)
mainLayout.addWidget(btnCancel,2,2)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QLabelBuddy()
main.show()
sys.exit(app.exec_())
9)QLine控件与回显模式
'''
QLineEdit控件与回显模式
基本功能:输入单行的文本
EchoMode(回显模式)
4种回显模式
1. Normal 常规模式
2. NoEcho 不回显,输入不显示
3. Password 加密,一般是*
4. PasswordEchoOnEdit 先显示,后加密
Mac : Command Windows:Control
'''
from PyQt5.QtWidgets import *
import sys
class QLineEditEchoMode(QWidget) :
def __init__(self):
super(QLineEditEchoMode,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('文本输入框的回显模式')
formLayout = QFormLayout()
normalLineEdit = QLineEdit()
noEchoLineEdit = QLineEdit()
passwordLineEdit = QLineEdit()
passwordEchoOnEditLineEdit = QLineEdit()
formLayout.addRow("Normal",normalLineEdit)
formLayout.addRow("NoEcho", noEchoLineEdit)
formLayout.addRow("Password",passwordLineEdit)
formLayout.addRow("PasswordEchoOnEdit",passwordEchoOnEditLineEdit)
# placeholdertext
normalLineEdit.setPlaceholderText("Normal")
noEchoLineEdit.setPlaceholderText("NoEcho")
passwordLineEdit.setPlaceholderText("Password")
passwordEchoOnEditLineEdit.setPlaceholderText("PasswordEchoOnEdit")
normalLineEdit.setEchoMode(QLineEdit.Normal)
noEchoLineEdit.setEchoMode(QLineEdit.NoEcho)
passwordLineEdit.setEchoMode(QLineEdit.Password)
passwordEchoOnEditLineEdit.setEchoMode(QLineEdit.PasswordEchoOnEdit)
self.setLayout(formLayout)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QLineEditEchoMode()
main.show()
sys.exit(app.exec_())
10)限制QlineEdit控件的输入(校验器)
'''
现在QLineEdit控件的输入(校验器)
如限制只能输入整数、浮点数或满足一定条件的字符串
'''
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIntValidator,QDoubleValidator, QRegExpValidator
from PyQt5.QtCore import QRegExp
import sys
class QLineEditValidator(QWidget):
def __init__(self):
super(QLineEditValidator,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('校验器')
# 创建表单布局
formLayout = QFormLayout()
intLineEdit = QLineEdit()
doubleLineEdit = QLineEdit()
validatorLineEdit = QLineEdit()
formLayout.addRow('整数类型', intLineEdit)
formLayout.addRow('浮点类型', doubleLineEdit)
formLayout.addRow('数字和字母',validatorLineEdit)
intLineEdit.setPlaceholderText('整型')
doubleLineEdit.setPlaceholderText('浮点型')
validatorLineEdit.setPlaceholderText('字母和数字')
# 整数校验器 [1,99]
intValidator = QIntValidator(self)
intValidator.setRange(1,99)
# 浮点校验器 [-360,360],精度:小数点后2位
doubleValidator = QDoubleValidator(self)
doubleValidator.setRange(-360,360)
doubleValidator.setNotation(QDoubleValidator.StandardNotation)
# 设置精度,小数点2位
doubleValidator.setDecimals(2)
# 字符和数字
reg = QRegExp('[a-zA-z0-9]+$')
validator = QRegExpValidator(self)
validator.setRegExp(reg)
# 设置校验器
intLineEdit.setValidator(intValidator)
doubleLineEdit.setValidator(doubleValidator)
validatorLineEdit.setValidator(validator)
self.setLayout(formLayout)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QLineEditValidator()
main.show()
sys.exit(app.exec_())
11)使用掩码限制QlineEdit控件输入
'''
用掩码限制QLineEdit控件的输入
A ASCII字母字符是必须输入的(A-Z、a-z)
a ASCII字母字符是允许输入的,但不是必需的(A-Z、a-z)
N ASCII字母字符是必须输入的(A-Z、a-z、0-9)
n ASII字母字符是允许输入的,但不是必需的(A-Z、a-z、0-9)
X 任何字符都是必须输入的
x 任何字符都是允许输入的,但不是必需的
9 ASCII数字字符是必须输入的(0-9)
0 ASCII数字字符是允许输入的,但不是必需的(0-9)
D ASCII数字字符是必须输入的(1-9)
d ASCII数字字符是允许输入的,但不是必需的(1-9)
# ASCI数字字符或加减符号是允许输入的,但不是必需的
H 十六进制格式字符是必须输入的(A-F、a-f、0-9)
h 十六进制格式字符是允许输入的,但不是必需的(A-F、a-f、0-9)
B 二进制格式字符是必须输入的(0,1)
b 二进制格式字符是允许输入的,但不是必需的(0,1)
> 所有的字母字符都大写
< 所有的字母字符都小写
! 关闭大小写转换
\ 使用"\"转义上面列出的字符
'''
from PyQt5.QtWidgets import *
import sys
class QLineEditMask(QWidget) :
def __init__(self):
super(QLineEditMask,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('用掩码限制QLineEdit控件的输入')
formLayout = QFormLayout()
ipLineEdit = QLineEdit()
macLineEdit = QLineEdit()
dateLineEdit = QLineEdit()
licenseLineEdit = QLineEdit()
# 192.168.21.45
ipLineEdit.setInputMask('000.000.000.000;_')
macLineEdit.setInputMask('HH:HH:HH:HH:HH:HH;_')
dateLineEdit.setInputMask('0000-00-00')
licenseLineEdit.setInputMask('>AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;#')
formLayout.addRow('数字掩码',ipLineEdit)
formLayout.addRow('Mac掩码', macLineEdit)
formLayout.addRow('日期掩码',dateLineEdit)
formLayout.addRow('许可证掩码',licenseLineEdit)
self.setLayout(formLayout)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QLineEditMask()
main.show()
sys.exit(app.exec_())
12)QLineEdit控件综合案例
'''
QLineEdit综合案例
'''
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import Qt
import sys
class QLineEditDemo(QWidget):
def __init__(self):
super(QLineEditDemo,self).__init__()
self.initUI()
def initUI(self):
edit1 = QLineEdit()
# 使用int校验器
edit1.setValidator(QIntValidator())
edit1.setMaxLength(4) # 不超过9999
edit1.setAlignment(Qt.AlignRight)
edit1.setFont(QFont('Arial',20))
edit2 = QLineEdit()
edit2.setValidator(QDoubleValidator(0.99,99.99,2))
edit3 = QLineEdit()
edit3.setInputMask('99_9999_999999;#')
edit4 = QLineEdit()
edit4.textChanged.connect(self.textChanged)
edit5 = QLineEdit()
edit5.setEchoMode(QLineEdit.Password)
edit5.editingFinished.connect(self.enterPress)
edit6 = QLineEdit('Hello PyQt5')
edit6.setReadOnly(True)
formLayout = QFormLayout()
formLayout.addRow('整数校验',edit1)
formLayout.addRow('浮点数校验',edit2)
formLayout.addRow('Input Mask',edit3)
formLayout.addRow('文本变化', edit4)
formLayout.addRow('密码',edit5)
formLayout.addRow('只读',edit6)
self.setLayout(formLayout)
self.setWindowTitle('QLineEdit综合案例')
def textChanged(self,text):
print('输入的内容:' + text)
def enterPress(self):
print('已输入值')
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QLineEditDemo()
main.show()
sys.exit(app.exec_())
13)使用QTextEdit控件输入多行文本
'''
QTextEdit控件
'''
from PyQt5.QtWidgets import *
import sys
class QTextEditDemo(QWidget) :
def __init__(self):
super(QTextEditDemo,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('QTextEdit控件演示')
self.resize(300,320)
self.textEdit = QTextEdit()
self.buttonText = QPushButton('显示文本')
self.buttonHTML = QPushButton('显示HTML')
self.buttonToText = QPushButton('获取文本')
self.buttonToHTML = QPushButton('获取HTML')
layout = QVBoxLayout()
layout.addWidget(self.textEdit)
layout.addWidget(self.buttonText)
layout.addWidget(self.buttonToText)
layout.addWidget(self.buttonHTML)
layout.addWidget(self.buttonToHTML)
self.setLayout(layout)
self.buttonText.clicked.connect(self.onClick_ButtonText)
self.buttonHTML.clicked.connect(self.onClick_ButtonHTML)
self.buttonToText.clicked.connect(self.onClick_ButtonToText)
self.buttonToHTML.clicked.connect(self.onClick_ButtonToHTML)
def onClick_ButtonText(self):
self.textEdit.setPlainText('Hello World,世界你好吗?')
def onClick_ButtonToText(self):
print(self.textEdit.toPlainText())
def onClick_ButtonHTML(self):
self.textEdit.setHtml('<font color="blue" size="5">Hello World</font>')
def onClick_ButtonToHTML(self):
print(self.textEdit.toHtml())
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QTextEditDemo()
main.show()
sys.exit(app.exec_())
14) 按钮控件(QPushButton)
'''
按钮控件(QPushButton)
QAbstractButton
QPushButton
AToolButton
QRadioButton
QCheckBox
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class QPushButtonDemo(QDialog) :
def __init__(self):
super(QPushButtonDemo,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('QPushButton Demo')
layout = QVBoxLayout()
self.button1 = QPushButton('第1个按钮')
self.button1.setText('First Button1')
self.button1.setCheckable(True)
self.button1.toggle()
self.button1.clicked.connect(self.buttonState)
self.button1.clicked.connect(lambda :self.whichButton(self.button1))
layout.addWidget(self.button1)
# 在文本前面显示图像
self.button2 = QPushButton('图像按钮')
self.button2.setIcon(QIcon(QPixmap('./images/python.png')))
self.button2.clicked.connect(lambda:self.whichButton(self.button2))
layout.addWidget(self.button2)
self.button3 = QPushButton('不可用的按钮')
self.button3.setEnabled(False)
layout.addWidget(self.button3)
self.button4 = QPushButton('&MyButton')
self.button4.setDefault(True)
self.button4.clicked.connect(lambda:self.whichButton(self.button4))
layout.addWidget(self.button4)
self.setLayout(layout)
self.resize(400,300)
def buttonState(self):
if self.button1.isChecked():
print('按钮1已经被选中')
else:
print('按钮1未被选中')
def whichButton(self,btn):
print('被单击的按钮是<' + btn.text() + '>')
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QPushButtonDemo()
main.show()
sys.exit(app.exec_())
15)单选按钮控件(QRadioButton)
'''
单选按钮控件(QRadioButton)
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class QRadioButtonDemo(QWidget):
def __init__(self):
super(QRadioButtonDemo,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('QRadioButton')
layout = QHBoxLayout()
self.button1 = QRadioButton('单选按钮1')
self.button1.setChecked(True)
self.button1.toggled.connect(self.buttonState)
layout.addWidget(self.button1)
self.button2 = QRadioButton('单选按钮2')
self.button2.toggled.connect(self.buttonState)
layout.addWidget(self.button2)
self.setLayout(layout)
def buttonState(self):
radioButton = self.sender()
if radioButton.isChecked() == True:
print('<' + radioButton.text() + '> 被选中')
else:
print('<' + radioButton.text() + '> 被取消选中状态')
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QRadioButtonDemo()
main.show()
sys.exit(app.exec_())
16) 复选框控件(QCheckBox)
'''
复选框控件(QCheckBox)
3种状态
未选中:0
半选中:1
选中:2
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
class QCheckBoxDemo(QWidget):
def __init__(self):
super(QCheckBoxDemo,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('复选框控件演示')
layout = QHBoxLayout()
self.checkBox1 = QCheckBox('复选框控件1')
self.checkBox1.setChecked(True)
self.checkBox1.stateChanged.connect(lambda:self.checkboxState(self.checkBox1))
layout.addWidget(self.checkBox1)
self.checkBox2 = QCheckBox('复选框控件2')
self.checkBox2.stateChanged.connect(lambda:self.checkboxState(self.checkBox2))
layout.addWidget(self.checkBox2)
self.checkBox3 = QCheckBox('半选中')
self.checkBox3.stateChanged.connect(lambda:self.checkboxState(self.checkBox3))
self.checkBox3.setTristate(True)
self.checkBox3.setCheckState(Qt.PartiallyChecked)
layout.addWidget(self.checkBox3)
self.setLayout(layout)
def checkboxState(self,cb):
check1Status = self.checkBox1.text() + ', isChecked=' + str(self.checkBox1.isChecked()) + ',checkState=' + str(self.checkBox1.checkState()) + '\n'
check2Status = self.checkBox2.text() + ', isChecked=' + str(self.checkBox2.isChecked()) + ',checkState=' + str(self.checkBox2.checkState()) + '\n'
check3Status = self.checkBox3.text() + ', isChecked=' + str(self.checkBox3.isChecked()) + ',checkState=' + str(self.checkBox3.checkState()) + '\n'
print(check1Status + check2Status + check3Status)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QCheckBoxDemo()
main.show()
sys.exit(app.exec_())
17)下拉列表控件(QComboBox)
'''
下拉列表控件(QComboBox)
1. 如果将列表项添加到QComboBox控件中
2. 如何获取选中的列表项
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class QComboBoxDemo(QWidget):
def __init__(self):
super(QComboBoxDemo,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('下拉列表控件演示')
self.resize(300,100)
layout = QVBoxLayout()
self.label = QLabel('请选择编程语言')
self.cb = QComboBox()
self.cb.addItem('C++')
self.cb.addItem('Python')
self.cb.addItems(['Java','C#','Ruby'])
self.cb.currentIndexChanged.connect(self.selectionChange)
layout.addWidget(self.label)
layout.addWidget(self.cb)
self.setLayout(layout)
def selectionChange(self,i):
self.label.setText(self.cb.currentText())
self.label.adjustSize()
for count in range(self.cb.count()):
print('item' + str(count) + '=' + self.cb.itemText(count))
print('current index',i,'selection changed', self.cb.currentText())
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QComboBoxDemo()
main.show()
sys.exit(app.exec_())
18) 滑块控件(QSlider)
'''
滑块控件(QSlider)
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class QSliderDemo(QWidget):
def __init__(self):
super(QSliderDemo,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('滑块控件演示')
self.resize(300,700)
layout = QVBoxLayout()
self.label = QLabel('你好 PyQt5')
self.label.setAlignment(Qt.AlignCenter)
layout.addWidget(self.label)
self.slider = QSlider(Qt.Horizontal)
# 设置最小值
self.slider.setMinimum(12)
# 设置最大值
self.slider.setMaximum(48)
# 步长
self.slider.setSingleStep(3)
# 设置当前值
self.slider.setValue(18)
# 设置刻度的位置,刻度在下方
self.slider.setTickPosition(QSlider.TicksBelow)
# 设置刻度的间隔
self.slider.setTickInterval(6)
layout.addWidget(self.slider)
self.slider.valueChanged.connect(self.valueChange)
self.slider1 = QSlider(Qt.Vertical)
layout.addWidget(self.slider1)
# 设置最小值
self.slider1.setMinimum(10)
# 设置最大值
self.slider1.setMaximum(60)
# 步长
self.slider1.setSingleStep(5)
# 设置当前值
self.slider1.setValue(30)
# 设置刻度的位置,刻度在下方
self.slider1.setTickPosition(QSlider.TicksLeft)
# 设置刻度的间隔
self.slider1.setTickInterval(2)
self.slider1.valueChanged.connect(self.valueChange)
self.setLayout(layout)
def valueChange(self):
print('当前值:%s' % self.sender().value())
size = self.sender().value()
self.label.setFont(QFont('Arial',size))
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QSliderDemo()
main.show()
sys.exit(app.exec_())
19)计数器控件(QSpinBox)
'''
计数器控件(QSpinBox)
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class QSpinBoxDemo(QWidget):
def __init__(self):
super(QSpinBoxDemo,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('QSpinBox演示')
self.resize(300,100)
layout = QVBoxLayout()
self.label = QLabel('当前值')
self.label.setAlignment(Qt.AlignCenter)
layout.addWidget(self.label)
self.sb = QSpinBox()
self.sb.setValue(18)
self.sb.setRange(10,38)
self.sb.setSingleStep(3)
layout.addWidget(self.sb)
self.sb.valueChanged.connect(self.valueChange)
self.setLayout(layout)
def valueChange(self):
self.label.setText('当前值:' + str(self.sb.value()))
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QSpinBoxDemo()
main.show()
sys.exit(app.exec_())
对话框
20)使用QDialog 显示通用对话框
'''
对话框:QDialog
QMessageBox
QColorDialog
QFileDialog
QFontDialog
QInputDialog
QMainWindow
QWidget
QDialog
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class QDialogDemo(QMainWindow):
def __init__(self):
super(QDialogDemo,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('QDialog案例')
self.resize(300,200)
self.button = QPushButton(self)
self.button.setText('弹出对话框')
self.button.move(50,50)
self.button.clicked.connect(self.showDialog)
def showDialog(self):
dialog = QDialog()
button = QPushButton('确定',dialog)
button.clicked.connect(dialog.close)
button.move(50,50)
dialog.setWindowTitle('对话框')
dialog.setWindowModality(Qt.ApplicationModal)
dialog.exec()
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QDialogDemo()
main.show()
sys.exit(app.exec_())
21)显示不同类型的消息对话框
'''
消息对话框:QMessageBox
1. 关于对话框
2. 错误对话框
3. 警告对话框
4. 提问对话框
5. 消息对话框
有2点差异
1. 显示的对话框图标可能不同
2. 显示的按钮是不一样的
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class QMessageBoxDemo(QWidget):
def __init__(self):
super(QMessageBoxDemo,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('QMessageBox案例')
self.resize(300,400)
layout = QVBoxLayout()
self.button1 = QPushButton()
self.button1.setText('显示关于对话框')
self.button1.clicked.connect(self.showDialog)
self.button2 = QPushButton()
self.button2.setText('显示消息对话框')
self.button2.clicked.connect(self.showDialog)
self.button3 = QPushButton()
self.button3.setText('显示警告对话框')
self.button3.clicked.connect(self.showDialog)
self.button4 = QPushButton()
self.button4.setText('显示错误对话框')
self.button4.clicked.connect(self.showDialog)
self.button5 = QPushButton()
self.button5.setText('显示提问对话框')
self.button5.clicked.connect(self.showDialog)
layout.addWidget(self.button1)
layout.addWidget(self.button2)
layout.addWidget(self.button3)
layout.addWidget(self.button4)
layout.addWidget(self.button5)
self.setLayout(layout)
def showDialog(self):
text = self.sender().text()
if text == '显示关于对话框':
QMessageBox.about(self,'关于','这是一个关于对话框')
elif text == '显示消息对话框':
reply = QMessageBox.information(self,'消息','这是一个消息对话框', QMessageBox.Yes | QMessageBox.No,QMessageBox.Yes)
print(reply == QMessageBox.Yes)
elif text == '显示警告对话框':
QMessageBox.warning(self,'警告','这是一个警告对话框',QMessageBox.Yes | QMessageBox.No,QMessageBox.Yes)
elif text == '显示错误对话框':
QMessageBox.critical(self,'警告','这是一个警告对话框',QMessageBox.Yes | QMessageBox.No,QMessageBox.Yes)
elif text == '显示提问对话框':
QMessageBox.question(self,'警告','这是一个警告对话框',QMessageBox.Yes | QMessageBox.No,QMessageBox.Yes)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QMessageBoxDemo()
main.show()
sys.exit(app.exec_())
22) 字体对话框(QFontDialog)
'''
字体对话框:QFontDialog
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class QFontDialogDemo(QWidget):
def __init__(self):
super(QFontDialogDemo,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('Font Dialog例子')
layout = QVBoxLayout()
self.fontButton = QPushButton('选择字体')
self.fontButton.clicked.connect(self.getFont)
layout.addWidget(self.fontButton)
self.fontLabel = QLabel('Hello,测试字体例子')
layout.addWidget(self.fontLabel)
self.setLayout(layout)
def getFont(self):
font, ok = QFontDialog.getFont()
if ok :
self.fontLabel.setFont(font)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QFontDialogDemo()
main.show()
sys.exit(app.exec_())
23)颜色对话框(QColorDialog)
'''
颜色对话框:QColorDialog
'''
'''
字体对话框:QFontDialog
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class QColorDialogDemo(QWidget):
def __init__(self):
super(QColorDialogDemo,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('Color Dialog例子')
layout = QVBoxLayout()
self.colorButton = QPushButton('设置颜色')
self.colorButton.clicked.connect(self.getColor)
layout.addWidget(self.colorButton)
self.colorButton1 = QPushButton('设置背景颜色')
self.colorButton1.clicked.connect(self.getBGColor)
layout.addWidget(self.colorButton1)
self.colorLabel = QLabel('Hello,测试颜色例子')
layout.addWidget(self.colorLabel)
self.setLayout(layout)
def getColor(self):
color = QColorDialog.getColor()
p = QPalette()
p.setColor(QPalette.WindowText,color)
self.colorLabel.setPalette(p)
def getBGColor(self):
color = QColorDialog.getColor()
p = QPalette()
p.setColor(QPalette.Window,color)
self.colorLabel.setAutoFillBackground(True)
self.colorLabel.setPalette(p)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QColorDialogDemo()
main.show()
sys.exit(app.exec_())
24)文件对话框(QFileDialog)
'''
文件对话框:QFileDialog
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class QFileDialogDemo(QWidget):
def __init__(self):
super(QFileDialogDemo,self).__init__()
self.initUI()
def initUI(self):
layout = QVBoxLayout()
self.button1 = QPushButton('加载图片')
self.button1.clicked.connect(self.loadImage)
layout.addWidget(self.button1)
self.imageLabel = QLabel()
layout.addWidget(self.imageLabel)
self.button2 = QPushButton('加载文本文件')
self.button2.clicked.connect(self.loadText)
layout.addWidget(self.button2)
self.contents = QTextEdit()
layout.addWidget(self.contents)
self.setLayout(layout)
self.setWindowTitle('文件对话框演示 ')
def loadImage(self):
fname,_ = QFileDialog.getOpenFileName(self,'打开文件','.','图像文件(*.jpg *.png)')
self.imageLabel.setPixmap(QPixmap(fname))
def loadText(self):
dialog = QFileDialog()
dialog.setFileMode(QFileDialog.AnyFile)
dialog.setFilter(QDir.Files)
if dialog.exec():
filenames = dialog.selectedFiles()
f = open(filenames[0],encoding='utf-8',mode='r')
with f:
data = f.read()
self.contents.setText(data)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QFileDialogDemo()
main.show()
sys.exit(app.exec_())
25)输入对话框(QInputDialog)
'''
输入对话框:QInputDialog
QInputDialog.getItem
QInputDialog.getText
QInputDialog.getInt
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class QInputDialogDemo(QWidget):
def __init__(self):
super(QInputDialogDemo,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('输入对话框')
layout = QFormLayout()
self.button1 = QPushButton('获取列表中的选项')
self.button1.clicked.connect(self.getItem)
self.lineEdit1 = QLineEdit()
layout.addRow(self.button1, self.lineEdit1)
self.button2 = QPushButton('获取字符串')
self.button2.clicked.connect(self.getText)
self.lineEdit2 = QLineEdit()
layout.addRow(self.button2, self.lineEdit2)
self.button3 = QPushButton('获取整数')
self.button3.clicked.connect(self.getInt)
self.lineEdit3 = QLineEdit()
layout.addRow(self.button3, self.lineEdit3)
self.setLayout(layout)
def getItem(self):
items = ('C','C++','Ruby','Python','Java')
item, ok =QInputDialog.getItem(self,'请选择编程语言','语言列表',items)
if ok and item:
self.lineEdit1.setText(item)
def getText(self):
text, ok =QInputDialog.getText(self,'文本输入框','输入姓名')
if ok and text:
self.lineEdit2.setText(text)
def getInt(self):
num, ok =QInputDialog.getInt(self,'整数输入框','输入数字')
if ok and num:
self.lineEdit3.setText(str(num))
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QInputDialogDemo()
main.show()
sys.exit(app.exec_())
绘图API
26)在窗口上绘制文本
'''
绘图API:绘制文本
1. 文本
2. 各种图形(直线,点,椭圆,弧,扇形,多边形等)
3. 图像
QPainter
painter = QPainter()
painter.begin()
painter.drawText(...)
painter.end()
必须在paintEvent事件方法中绘制各种元素
'''
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QPainter, QColor, QFont
from PyQt5.QtCore import Qt
class DrawText(QWidget):
def __init__(self):
super(DrawText, self).__init__()
self.setWindowTitle('在窗口上绘制文本')
self.resize(300, 200)
self.text = "Python从菜鸟到高手"
def paintEvent(self, event):
painter = QPainter(self)
painter.begin(self)
painter.setPen(QColor(150, 43, 5))
painter.setFont(QFont('SimSun', 25))
painter.drawText(event.rect(), Qt.AlignCenter, self.text)
painter.end()
if __name__ == '__main__':
app = QApplication(sys.argv)
main = DrawText()
main.show()
sys.exit(app.exec_())
27)使用像素点绘制曲线
'''
用像素点绘制正弦曲线
-2PI 2PI
drawPoint(x,y)
'''
import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import Qt
class DrawPoints(QWidget):
def __init__(self):
super(DrawPoints,self).__init__()
self.resize(300,300)
self.setWindowTitle('在窗口上用像素点绘制2个周期的正弦曲线')
def paintEvent(self, event):
painter = QPainter()
painter.begin(self)
painter.setPen(Qt.blue)
size = self.size()
for i in range(1000):
x = 100 * (-1 + 2.0 * i/1000) + size.width()/2.0
y = -50 * math.sin((x - size.width()/2.0) * math.pi/50) + size.height()/2.0
painter.drawPoint(x,y)
painter.end()
if __name__ == '__main__':
app = QApplication(sys.argv)
main = DrawPoints()
main.show()
sys.exit(app.exec_())
28)绘制不同类型的直线
'''
绘制不同类型的直线
'''
import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import Qt
class DrawMultiLine(QWidget):
def __init__(self):
super(DrawMultiLine,self).__init__()
self.resize(300,300)
self.setWindowTitle('设置Pen的样式')
def paintEvent(self, event):
painter = QPainter()
painter.begin(self)
pen = QPen(Qt.red,3,Qt.SolidLine)
painter.setPen(pen)
painter.drawLine(20,40,250,40)
pen.setStyle(Qt.DashLine)
painter.setPen(pen)
painter.drawLine(20, 80, 250, 80)
pen.setStyle(Qt.DashDotDotLine)
painter.setPen(pen)
painter.drawLine(20, 120, 250, 120)
pen.setStyle(Qt.DotLine)
painter.setPen(pen)
painter.drawLine(20, 160, 250, 160)
pen.setStyle(Qt.DashDotDotLine)
painter.setPen(pen)
painter.drawLine(20, 200, 250, 200)
pen.setStyle(Qt.CustomDashLine)
pen.setDashPattern([1,10,5,8])
painter.setPen(pen)
painter.drawLine(20, 240, 250, 240)
size = self.size()
painter.end()
if __name__ == '__main__':
app = QApplication(sys.argv)
main = DrawMultiLine()
main.show()
sys.exit(app.exec_())
29)绘制各种图形
'''
绘制各种图形
弧
圆形
椭圆
矩形(正方形)
多边形
绘制图像
'''
import sys, math
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class DrawAll(QWidget):
def __init__(self):
super(DrawAll, self).__init__()
self.resize(300, 600)
self.setWindowTitle('绘制各种图形')
def paintEvent(self, event):
qp = QPainter()
qp.begin(self)
qp.setPen(Qt.blue)
# 绘制弧
rect = QRect(0, 10, 100, 100)
# alen: 1个alen等于1/16度 45 * 16
qp.drawArc(rect, 0, 50 * 16)
# 通过弧绘制圆
qp.setPen(Qt.red)
qp.drawArc(120, 10, 100, 100, 0, 360 * 16)
# 绘制带弦的弧
qp.drawChord(10, 120, 100, 100, 12, 130 * 16)
# 绘制扇形
qp.drawPie(10, 240, 100, 100, 12, 130 * 16)
# 椭圆
qp.drawEllipse(120, 120, 150, 100)
# 绘制5边形
point1 = QPoint(140, 380)
point2 = QPoint(270, 420)
point3 = QPoint(290, 512)
point4 = QPoint(290, 588)
point5 = QPoint(200, 533)
polygon = QPolygon([point1, point2, point3, point4, point5])
qp.drawPolygon(polygon)
# 绘制图像
image = QImage('./images/book1.png')
rect = QRect(10, 400, image.width() / 3, image.height() / 3)
# image.save('./images/book1.png')
qp.drawImage(rect, image)
qp.end()
if __name__ == '__main__':
app = QApplication(sys.argv)
main = DrawAll()
main.show()
sys.exit(app.exec_())
30)用画刷填充图形区域
'''
用画刷填充图形区域
'''
import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class FillRect(QWidget):
def __init__(self):
super(FillRect,self).__init__()
self.resize(600,600)
self.setWindowTitle('用画刷填充区域')
def paintEvent(self,e):
qp = QPainter()
qp.begin(self)
brush = QBrush(Qt.SolidPattern)
qp.setBrush(brush)
qp.drawRect(10,15,90,60)
brush = QBrush(Qt.Dense1Pattern)
qp.setBrush(brush)
qp.drawRect(130,15,90,60)
brush = QBrush(Qt.Dense2Pattern)
qp.setBrush(brush)
qp.drawRect(250,15,90,60)
brush = QBrush(Qt.Dense3Pattern)
qp.setBrush(brush)
qp.drawRect(10, 105, 90, 60)
brush = QBrush(Qt.HorPattern)
qp.setBrush(brush)
qp.drawRect(130, 105, 90, 60)
qp.end()
if __name__ == '__main__':
app = QApplication(sys.argv)
main = FillRect()
main.show()
sys.exit(app.exec_())
31)让控件支持拖拽动作
'''
让控件支持拖拽动作
A.setDragEnabled(True)
B.setAcceptDrops(True)
B需要两个事件
1. dragEnterEvent 将A拖到B触发
2. dropEvent 在B的区域放下A时触发
'''
import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class MyComboBox(QComboBox) :
def __init__(self):
super(MyComboBox,self).__init__()
self.setAcceptDrops(True)
def dragEnterEvent(self,e):
print(e)
if e.mimeData().hasText():
e.accept()
else:
e.ignore()
def dropEvent(self,e):
self.addItem(e.mimeData().text())
class DrapDropDemo(QWidget):
def __init__(self):
super(DrapDropDemo,self).__init__()
formLayout = QFormLayout()
formLayout.addRow(QLabel("请将左边的文本拖拽到右边的下拉列表中"))
lineEdit = QLineEdit()
lineEdit.setDragEnabled(True) # 让QLineEdit控件可拖动
combo = MyComboBox()
formLayout.addRow(lineEdit,combo)
self.setLayout(formLayout)
self.setWindowTitle('拖拽案例')
if __name__ == '__main__':
app = QApplication(sys.argv)
main = DrapDropDemo()
main.show()
sys.exit(app.exec_())
32)使用剪贴板
'''
使用剪贴板
'''
import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class ClipBoard(QDialog):
def __init__(self):
super(ClipBoard,self).__init__()
textCopyButton = QPushButton('复制文本')
textPasteButton = QPushButton('粘贴文本')
htmlCopyButton = QPushButton('复制HTML')
htmlPasteButton = QPushButton('粘贴HTML')
imageCopyButton = QPushButton('复制图像')
imagePasteButton = QPushButton('粘贴图像')
self.textLabel = QLabel('默认文本')
self.imageLabel=QLabel()
# self.imageLabel.setPixmap(QPixmap('./images/book1.png'))
layout = QGridLayout()
layout.addWidget(textCopyButton,0,0)
layout.addWidget(imageCopyButton,0,1)
layout.addWidget(htmlCopyButton,0,2)
layout.addWidget(textPasteButton,1,0)
layout.addWidget(htmlPasteButton,1,1)
layout.addWidget(imagePasteButton,1,2)
layout.addWidget(self.textLabel,2,0,1,2)
layout.addWidget(self.imageLabel,2,2)
self.setLayout(layout)
textCopyButton.clicked.connect(self.copyText)
textPasteButton.clicked.connect(self.pasteText)
htmlCopyButton.clicked.connect(self.copyHtml)
htmlPasteButton.clicked.connect(self.pasteHtml)
imageCopyButton.clicked.connect(self.copyImage)
imagePasteButton.clicked.connect(self.pasteImage)
self.setWindowTitle('剪贴板演示')
def copyText(self):
clipboard = QApplication.clipboard()
clipboard.setText('hello world')
def pasteText(self):
clipboard = QApplication.clipboard()
self.textLabel.setText(clipboard.text())
def copyImage(self):
clipboard = QApplication.clipboard()
clipboard.setPixmap(QPixmap('./images/book.png'))
def pasteImage(self):
clipboard = QApplication.clipboard()
self.imageLabel.setPixmap(clipboard.pixmap())
def copyHtml(self):
mimeData = QMimeData()
mimeData.setHtml('<b>Bold and <font color=red>Red</font></b>')
clipboard = QApplication.clipboard()
clipboard.setMimeData(mimeData)
def pasteHtml(self):
clipboard = QApplication.clipboard()
mimeData = clipboard.mimeData()
if mimeData.hasHtml():
self.textLabel.setText(mimeData.html())
if __name__ == '__main__':
app = QApplication(sys.argv)
main = ClipBoard()
main.show()
sys.exit(app.exec_())
33)日历控件
'''
日历控件
QCalendarWidget
'''
import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class MyCalendar(QWidget):
def __init__(self):
super(MyCalendar, self).__init__()
self.initUI()
def initUI(self):
self.cal = QCalendarWidget(self)
self.cal.setMinimumDate(QDate(1988,1,1))
self.cal.setMaximumDate(QDate(2088,1,1))
self.cal.setGridVisible(True)
self.cal.move(20,20)
self.cal.clicked.connect(self.showDate)
self.label = QLabel(self)
date = self.cal.selectedDate()
self.label.setText(date.toString("yyyy-MM-dd dddd"))
self.label.move(20,300)
self.resize(400,350)
self.setWindowTitle("日历演示")
def showDate(self,date):
#self.label.setText((date.toString("yyyy-MM-dd dddd")))
self.label.setText((self.cal.selectedDate().toString("yyyy-MM-dd dddd")))
if __name__ == '__main__':
app = QApplication(sys.argv)
main = MyCalendar()
main.show()
sys.exit(app.exec_())
34)设置不同风格的日期和时间及高级操作
'''
输入各种风格的日期和时间
QDateTimeEdit
'''
import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class DateTimeEdit(QWidget):
def __init__(self):
super(DateTimeEdit, self).__init__()
self.initUI()
def initUI(self):
vlayout = QVBoxLayout()
dateTimeEdit1 = QDateTimeEdit()
dateTimeEdit2 = QDateTimeEdit(QDateTime.currentDateTime())
dateTimeEdit1.setMinimumDate(QDate.currentDate().addDays(-365))
dateTimeEdit1.setMaximumDate(QDate.currentDate().addDays(365))
self.dateTimeEdit = dateTimeEdit1
dateTimeEdit2.setCalendarPopup(True)
dateEdit = QDateTimeEdit(QDate.currentDate())
timeEdit = QDateTimeEdit(QTime.currentTime())
dateTimeEdit1.setDisplayFormat("yyyy-MM-dd HH:mm:ss")
dateTimeEdit2.setDisplayFormat("yyyy/MM/dd HH-mm-ss")
dateEdit.setDisplayFormat("yyyy.MM.dd")
timeEdit.setDisplayFormat("HH:mm:ss")
dateTimeEdit1.dateChanged.connect(self.onDateChanged)
dateTimeEdit1.timeChanged.connect(self.onTimeChanged)
dateTimeEdit1.dateTimeChanged.connect(self.onDateTimeChanged)
vlayout.addWidget(dateTimeEdit1)
vlayout.addWidget(dateTimeEdit2)
vlayout.addWidget(dateEdit)
vlayout.addWidget(timeEdit)
self.btn = QPushButton('获取日期和时间')
self.btn.clicked.connect(self.onButtonClick)
vlayout.addWidget(self.btn)
self.setLayout(vlayout)
self.resize(300,90)
self.setWindowTitle("设置不同风格的日期和时间")
# 日期变化
def onDateChanged(self,date):
print(date)
# 时间变化
def onTimeChanged(self,time):
print(time)
# 日期和时间变化
def onDateTimeChanged(self,datetime):
print(datetime)
def onButtonClick(self):
datetime = self.dateTimeEdit.dateTime()
print(datetime)
# 最大日期
print(self.dateTimeEdit.maximumDate())
# 最大日期和时间
print(self.dateTimeEdit.maximumDateTime())
# 最小日期
print(self.dateTimeEdit.minimumDateTime())
if __name__ == '__main__':
app = QApplication(sys.argv)
main = DateTimeEdit()
main.show()
sys.exit(app.exec_())
菜单栏,工具栏,状态栏
35)创建和使用菜单栏
'''
创建和使用菜单
'''
import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class Menu(QMainWindow) :
def __init__(self):
super(Menu,self).__init__()
bar = self.menuBar() # 获取菜单栏
file = bar.addMenu("文件")
file.addAction("新建")
save = QAction("保存",self)
save.setShortcut("Ctrl + S")
file.addAction(save)
save.triggered.connect(self.process)
edit = bar.addMenu("Edit")
edit.addAction("copy")
edit.addAction("paste")
quit = QAction("退出",self)
file.addAction(quit)
def process(self,a):
print(self.sender().text())
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Menu()
main.show()
sys.exit(app.exec_())
36)创建和使用工具栏
'''
创建和使用工具栏
工具栏默认按钮:只显示图标,将文本作为悬停提示展示
工具栏按钮有3中显示状态
1. 只显示图标
2. 只显示文本
3. 同时显示文本和图标
'''
import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class Toolbar(QMainWindow) :
def __init__(self):
super(Toolbar,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("工具栏例子")
self.resize(300,200)
tb1 = self.addToolBar("File")
new = QAction(QIcon('./images/new.png'),"new",self)
tb1.addAction(new)
open = QAction(QIcon('./images/open.png'),"open",self)
tb1.addAction(open)
save = QAction(QIcon('./images/save.png'),"save",self)
tb1.addAction(save)
tb2 = self.addToolBar("File1")
new1 = QAction(QIcon('./images/new.png'),"新建",self)
tb2.addAction(new1)
tb2.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
tb1.actionTriggered.connect(self.toolbtnpressed)
tb2.actionTriggered.connect(self.toolbtnpressed)
def toolbtnpressed(self,a):
print("按下的工具栏按钮是",a.text())
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Toolbar()
main.show()
sys.exit(app.exec_())
37)创建和使用状态栏
'''
创建和使用状态栏
'''
import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class StatusBar(QMainWindow) :
def __init__(self):
super(StatusBar,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("状态栏演示")
self.resize(300,200)
bar = self.menuBar()
file = bar.addMenu("File")
file.addAction("show")
file.triggered.connect(self.processTrigger)
self.setCentralWidget(QTextEdit())
self.statusBar = QStatusBar()
self.setStatusBar(self.statusBar)
def processTrigger(self,q):
if q.text() == "show" :
self.statusBar.showMessage(q.text() + " 菜单被点击了",5000)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = StatusBar()
main.show()
sys.exit(app.exec_())
使用打印机
38)使用打印机
'''
使用打印机
'''
from PyQt5 import QtGui, QtWidgets, QtPrintSupport
from PyQt5.QtWidgets import *
import sys
class PrintSupport(QMainWindow):
def __init__(self):
super(PrintSupport,self).__init__()
self.setGeometry(500, 200, 300, 300)
self.button = QPushButton('打印QTextEdit控件中的内容',self)
self.button.setGeometry(20,20,260,30)
self.editor = QTextEdit('默认文本',self)
self.editor.setGeometry(20,60,260,200)
self.button.clicked.connect(self.print)
def print(self):
printer = QtPrintSupport.QPrinter()
painter = QtGui.QPainter()
# 将绘制的目标重定向到打印机
painter.begin(printer)
screen = self.editor.grab()
painter.drawPixmap(10,10,screen)
painter.end()
print("print")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
gui = PrintSupport()
gui.show()
app.exec_()
39)显示打印对话框
'''
显示打印对话框
'''
from PyQt5.QtWidgets import QWidget, QApplication, QPushButton, QTextEdit, QFileDialog, QDialog
from PyQt5.QtPrintSupport import QPageSetupDialog, QPrintDialog, QPrinter
import sys
class PrintDialog(QWidget):
def __init__(self):
super(PrintDialog,self).__init__()
self.printer = QPrinter()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 500, 400)
self.setWindowTitle('打印对话框')
self.editor = QTextEdit(self)
self.editor.setGeometry(20,20,300,270)
self.openButton = QPushButton('打开文件',self)
self.openButton.move(350,20)
self.settingsButton = QPushButton('打印设置',self)
self.settingsButton.move(350,50)
self.printButton = QPushButton('打印文档',self)
self.printButton.move(350,80)
self.openButton.clicked.connect(self.openFile)
self.settingsButton.clicked.connect(self.showSettingsDialog)
self.printButton.clicked.connect(self.showPrintDialog)
# 打开文件
def openFile(self):
fname = QFileDialog.getOpenFileName(self,'打开文本文件','./')
if fname[0]:
with open(fname[0],'r',encoding='utf-8',errors = 'ignore') as f:
self.editor.setText(f.read())
# 显示打印设置对话框
def showSettingsDialog(self):
printDialog = QPageSetupDialog(self.printer,self)
printDialog.exec()
# 显示打印对话框
def showPrintDialog(self):
printdialog = QPrintDialog(self.printer,self)
if QDialog.Accepted == printdialog.exec():
self.editor.print(self.printer)
if __name__ == '__main__':
app = QApplication(sys.argv)
gui = PrintDialog()
gui.show()
sys.exit(app.exec_())
二维表
40)显示二维表数据(QTableView)
'''
显示二维表数据(QTableView控件)
数据源
Model
需要创建QTableView实例和一个数据源(Model),然后将两者关联
MVC:Model Viewer Controller
MVC的目的是将后端的数据和前端页面的耦合度降低
'''
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import sys
class TableView(QWidget):
def __init__(self, arg=None):
super(TableView, self).__init__(arg)
self.setWindowTitle("QTableView表格视图控件演示")
self.resize(500,300);
self.model = QStandardItemModel(4,3)
self.model.setHorizontalHeaderLabels(['id','姓名','年龄'])
self.tableview = QTableView()
# 关联QTableView控件和Model
self.tableview.setModel(self.model)
# 添加数据
item11 = QStandardItem('10')
item12 = QStandardItem('雷神')
item13 = QStandardItem('2000')
self.model.setItem(0,0,item11)
self.model.setItem(0,1, item12)
self.model.setItem(0,2, item13)
item31 = QStandardItem('30')
item32 = QStandardItem('死亡女神')
item33 = QStandardItem('3000')
self.model.setItem(2,0,item31)
self.model.setItem(2,1, item32)
self.model.setItem(2,2, item33)
layout = QVBoxLayout()
layout.addWidget(self.tableview)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
table = TableView()
table.show()
sys.exit(app.exec_())
41)显示列表数据(QListView)
'''
显示列表数据(QListView控件)
'''
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QListView, QMessageBox
from PyQt5.QtCore import QStringListModel
import sys
class ListViewDemo(QWidget):
def __init__(self, parent=None):
super(ListViewDemo, self).__init__(parent)
self.setWindowTitle("QListView 例子")
self.resize(300, 270)
layout = QVBoxLayout()
listview = QListView()
listModel = QStringListModel()
self.list = ["列表项1","列表项2", "列表项3"]
listModel.setStringList(self.list)
listview.setModel(listModel)
listview.clicked.connect(self.clicked)
layout.addWidget(listview)
self.setLayout(layout)
def clicked(self,item):
QMessageBox.information(self,"QListView","您选择了:" + self.list[item.row()])
if __name__ == "__main__":
app = QApplication(sys.argv)
win = ListViewDemo()
win.show()
sys.exit(app.exec_())
42)扩展的列表控件(QListWidget)
'''
扩展的列表控件(QListWidget),QListView的子类
可以使用mvc模式,也可以直接添加数据
QListView
'''
from PyQt5.QtWidgets import *
import sys
class ListWidgetDemo(QMainWindow):
def __init__(self, parent=None):
super(ListWidgetDemo, self).__init__(parent)
self.setWindowTitle("QListWidget 例子")
self.resize(300, 270)
self.listwidget = QListWidget()
self.listwidget.addItem("item1")
self.listwidget.addItem("item2")
self.listwidget.addItem("item3")
self.listwidget.addItem("item4")
self.listwidget.addItem("item5")
self.listwidget.itemClicked.connect(self.clicked)
self.setCentralWidget(self.listwidget)
def clicked(self,Index):
QMessageBox.information(self,"QListWidget","您选择了:" + self.listwidget.item(self.listwidget.row(Index)).text())
if __name__ == "__main__":
app = QApplication(sys.argv)
win = ListWidgetDemo()
win.show()
sys.exit(app.exec_())
42)扩展的表格控件(QListWidget)
'''
扩展的表格控件(QTableWidget)
QTableView的子类
每一个Cell(单元格)是一个QTableWidgetItem
'''
import sys
from PyQt5.QtWidgets import (QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem, QAbstractItemView)
class TableWidgetDemo(QWidget):
def __init__(self):
super(TableWidgetDemo,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QTableWidget演示")
self.resize(430, 230);
layout = QHBoxLayout()
tablewidget = QTableWidget()
tablewidget.setRowCount(4)
tablewidget.setColumnCount(3)
layout.addWidget(tablewidget)
tablewidget.setHorizontalHeaderLabels(['姓名','年龄','籍贯'])
nameItem = QTableWidgetItem("小明")
tablewidget.setItem(0,0,nameItem)
ageItem = QTableWidgetItem("24")
tablewidget.setItem(0,1,ageItem)
jgItem = QTableWidgetItem("北京")
tablewidget.setItem(0,2,jgItem)
# 禁止编辑
tablewidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
# 整行选择
tablewidget.setSelectionBehavior(QAbstractItemView.SelectRows)
# 调整列和行
tablewidget.resizeColumnsToContents()
tablewidget.resizeRowsToContents()
tablewidget.horizontalHeader().setVisible(False)
# tablewidget.verticalHeader().setVisible(False)
tablewidget.setVerticalHeaderLabels(["a","b"])
# 隐藏表格线
tablewidget.setShowGrid(False)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
example = TableWidgetDemo()
example.show()
sys.exit(app.exec_())
43)在单元格中放置控件
'''
在单元格中放置控件
setItem:将文本放到单元格中
setCellWidget:将控件放到单元格中
setStyleSheet:设置控件的样式(QSS)
'''
import sys
from PyQt5.QtWidgets import (QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem, QAbstractItemView,
QComboBox, QPushButton)
class PlaceControlInCell(QWidget):
def __init__(self):
super(PlaceControlInCell,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("在单元格中放置控件")
self.resize(430, 300);
layout = QHBoxLayout()
tableWidget = QTableWidget()
tableWidget.setRowCount(4)
tableWidget.setColumnCount(3)
layout.addWidget(tableWidget)
tableWidget.setHorizontalHeaderLabels(['姓名','性别','体重(kg)'])
textItem = QTableWidgetItem('小明')
tableWidget.setItem(0,0,textItem)
combox = QComboBox()
combox.addItem('男')
combox.addItem('女')
# QSS Qt StyleSheet
combox.setStyleSheet('QComboBox{margin:3px};')
tableWidget.setCellWidget(0,1,combox)
modifyButton = QPushButton('修改')
modifyButton.setDown(True)
modifyButton.setStyleSheet('QPushButton{margin:3px};')
tableWidget.setCellWidget(0,2,modifyButton)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
example = PlaceControlInCell()
example.show()
sys.exit(app.exec_())
44)在表格中搜索cell行定位
'''
在表格中快速定位到特定的行
1. 数据的定位:findItems 返回一个列表
2. 如果找到了满足条件的单元格,会定位到单元格所在的行:setSliderPosition(row)
'''
import sys
from PyQt5.QtWidgets import *
from PyQt5 import QtCore
from PyQt5.QtGui import QColor, QBrush
class DataLocation(QWidget):
def __init__(self):
super(DataLocation,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QTableWidget 例子")
self.resize(600, 800);
layout = QHBoxLayout()
tableWidget = QTableWidget()
tableWidget.setRowCount(40)
tableWidget.setColumnCount(4)
layout.addWidget(tableWidget)
for i in range(40):
for j in range(4):
itemContent = '(%d,%d)' %(i,j)
tableWidget.setItem(i,j,QTableWidgetItem(itemContent))
self.setLayout(layout)
# 搜索满足条件的Cell
text = '(1'
items = tableWidget.findItems(text,QtCore.Qt.MatchStartsWith)
if len(items) > 0:
item = items[0]
item.setBackground(QBrush(QColor(0,255,0)))
item.setForeground(QBrush(QColor(255,0,0)))
row = item.row()
# 定位到指定的行
tableWidget.verticalScrollBar().setSliderPosition(row)
if __name__ == '__main__':
app = QApplication(sys.argv)
example = DataLocation()
example.show()
sys.exit(app.exec_())
45)设置单元格字体和颜色
'''
设置单元格字体和颜色
'''
import sys
from PyQt5.QtWidgets import (QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem)
from PyQt5.QtGui import QBrush, QColor, QFont
class CellFontAndColor(QWidget):
def __init__(self):
super(CellFontAndColor,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("设置单元格字体和颜色")
self.resize(430, 230);
layout = QHBoxLayout()
tableWidget = QTableWidget()
tableWidget.setRowCount(4)
tableWidget.setColumnCount(3)
layout.addWidget(tableWidget)
tableWidget.setHorizontalHeaderLabels(['姓名', '性别', '体重(kg)'])
newItem = QTableWidgetItem('雷神')
newItem.setFont(QFont('Times',14,QFont.Black))
newItem.setForeground(QBrush(QColor(255,0,0)))
tableWidget.setItem(0,0,newItem)
newItem = QTableWidgetItem('女')
newItem.setForeground(QBrush(QColor(255,255,0)))
newItem.setBackground(QBrush(QColor(0,0,255)))
tableWidget.setItem(0,1,newItem)
newItem = QTableWidgetItem('160')
newItem.setFont(QFont('Times',20,QFont.Black))
newItem.setForeground(QBrush(QColor(0,0,255)))
tableWidget.setItem(0,2,newItem)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
example = CellFontAndColor()
example.show()
sys.exit(app.exec_())
46)按表格的某一列排序
'''
按列排序
1. 按哪一列排序
2. 排序类型:升序或降序
sortItems(columnIndex,orderType)
'''
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class ColumnSort(QWidget):
def __init__(self):
super(ColumnSort,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("按列排序")
self.resize(430, 230);
layout = QVBoxLayout()
self.tableWidget = QTableWidget()
self.tableWidget.setRowCount(4)
self.tableWidget.setColumnCount(3)
layout.addWidget(self.tableWidget)
self.tableWidget.setHorizontalHeaderLabels(['姓名', '性别', '体重(kg)'])
newItem = QTableWidgetItem('张三')
self.tableWidget.setItem(0,0,newItem)
newItem=QTableWidgetItem('男')
self.tableWidget.setItem(0,1,newItem)
newItem=QTableWidgetItem('165')
self.tableWidget.setItem(0,2,newItem)
newItem = QTableWidgetItem('李四')
self.tableWidget.setItem(1, 0, newItem)
newItem = QTableWidgetItem('女')
self.tableWidget.setItem(1, 1, newItem)
newItem = QTableWidgetItem('160')
self.tableWidget.setItem(1, 2, newItem)
newItem = QTableWidgetItem('王五')
self.tableWidget.setItem(2, 0, newItem)
newItem = QTableWidgetItem('男')
self.tableWidget.setItem(2, 1, newItem)
newItem = QTableWidgetItem('170')
self.tableWidget.setItem(2, 2, newItem)
self.button = QPushButton('排序')
self.button.clicked.connect(self.order)
layout.addWidget(self.button)
self.orderType = Qt.DescendingOrder
self.setLayout(layout)
def order(self):
if self.orderType == Qt.DescendingOrder:
self.orderType = Qt.AscendingOrder
else:
self.orderType = Qt.DescendingOrder
self.tableWidget.sortItems(2,self.orderType)
if __name__ == '__main__':
app = QApplication(sys.argv)
example = ColumnSort()
example.show()
sys.exit(app.exec_())
47)设置单元格的文本对齐方式
'''
设置单元格的文本对齐方式
setTextAlignment
Qt.AlignRight Qt.AlignBottom
'''
import sys
from PyQt5.QtWidgets import (QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem)
from PyQt5.QtCore import Qt
class CellTextAlignment(QWidget):
def __init__(self):
super(CellTextAlignment,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("设置单元格的文本对齐方式")
self.resize(430, 230);
layout = QHBoxLayout()
tableWidget = QTableWidget()
tableWidget.setRowCount(4)
tableWidget.setColumnCount(3)
layout.addWidget(tableWidget)
tableWidget.setHorizontalHeaderLabels(['姓名', '性别', '体重(kg)'])
newItem = QTableWidgetItem('雷神')
newItem.setTextAlignment(Qt.AlignRight | Qt.AlignBottom)
tableWidget.setItem(0,0,newItem)
newItem = QTableWidgetItem('男')
newItem.setTextAlignment(Qt.AlignCenter | Qt.AlignBottom)
tableWidget.setItem(0,1,newItem)
newItem = QTableWidgetItem('190')
newItem.setTextAlignment(Qt.AlignRight)
tableWidget.setItem(0,2,newItem)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
example = CellTextAlignment()
example.show()
sys.exit(app.exec_())
48)合并单元格
'''
合并单元格
setSpan(row,col,要合并的行数,要合并的列数)
'''
import sys
from PyQt5.QtWidgets import (QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem)
class Span(QWidget):
def __init__(self):
super(Span,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("合并单元格")
self.resize(430, 230);
layout = QHBoxLayout()
tableWidget = QTableWidget()
tableWidget.setRowCount(4)
tableWidget.setColumnCount(3)
layout.addWidget(tableWidget)
tableWidget.setHorizontalHeaderLabels(['姓名', '性别', '体重(kg)'])
newItem = QTableWidgetItem('雷神')
tableWidget.setItem(0,0,newItem)
tableWidget.setSpan(0, 0, 3, 1)
newItem = QTableWidgetItem('男')
tableWidget.setItem(0,1,newItem)
tableWidget.setSpan(0,1,2,1)
newItem = QTableWidgetItem('160')
tableWidget.setItem(0,2,newItem)
tableWidget.setSpan(0,2,4,1)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
example = Span()
example.show()
sys.exit(app.exec_())
49)设置单元格的尺寸
'''
设置单元格尺寸
'''
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QBrush, QColor, QFont
class CellSize(QWidget):
def __init__(self):
super(CellSize,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QTableWidget 例子")
self.resize(530, 300);
layout = QHBoxLayout()
tableWidget = QTableWidget()
tableWidget.setRowCount(4)
tableWidget.setColumnCount(3)
layout.addWidget(tableWidget)
tableWidget.setHorizontalHeaderLabels(['姓名', '性别', '体重(kg)'])
tableWidget.setRowHeight(0, 80)
tableWidget.setColumnWidth(2, 120)
tableWidget.setRowHeight(2,100)
newItem = QTableWidgetItem('雷神')
newItem.setFont(QFont('Times',40,QFont.Black))
newItem.setForeground(QBrush(QColor(255,0,0)))
tableWidget.setItem(0,0,newItem)
newItem = QTableWidgetItem('女')
newItem.setForeground(QBrush(QColor(255,255,0)))
newItem.setBackground(QBrush(QColor(0,0,255)))
tableWidget.setItem(0,1,newItem)
newItem = QTableWidgetItem('160')
newItem.setFont(QFont('Times',60,QFont.Black))
newItem.setForeground(QBrush(QColor(0,0,255)))
tableWidget.setItem(0,2,newItem)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
example = CellSize()
example.show()
sys.exit(app.exec_())
50) 在单元格中实现图文混排的效果
'''
在单元格中实现图文混排的效果
'''
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
class CellImageText(QWidget):
def __init__(self):
super(CellImageText,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("在单元格中实现图文混排的效果")
self.resize(500, 300);
layout = QHBoxLayout()
self.tableWidget = QTableWidget()
self.tableWidget.setRowCount(5)
self.tableWidget.setColumnCount(4)
layout.addWidget(self.tableWidget)
self.tableWidget.setHorizontalHeaderLabels(['姓名', '性别', '体重', '显示图片'])
newItem = QTableWidgetItem('李宁')
self.tableWidget.setItem(0,0,newItem)
newItem = QTableWidgetItem('男')
self.tableWidget.setItem(0,1,newItem)
newItem = QTableWidgetItem('160')
self.tableWidget.setItem(0,2,newItem)
newItem = QTableWidgetItem(QIcon('./images/bao1.png'),'背包')
self.tableWidget.setItem(0,3,newItem)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
example = CellImageText()
example.show()
sys.exit(app.exec_())
51)改变单元格中图片的尺寸
'''
改变单元格中图片的尺寸
setIconSize(QSize(width,height))
'''
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class CellImageSize(QWidget):
def __init__(self):
super(CellImageSize,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("改变单元格中图片的尺寸")
self.resize(1000, 900);
layout = QHBoxLayout()
tablewidget = QTableWidget()
tablewidget.setIconSize(QSize(300,200))
tablewidget.setColumnCount(3)
tablewidget.setRowCount(5)
tablewidget.setHorizontalHeaderLabels(['图片1', '图片2', '图片3'])
# 让列的宽度和图片的宽度相同
for i in range(3):
tablewidget.setColumnWidth(i,300)
# 让行的高度和图片的高度相同
for i in range(15):
tablewidget.setRowHeight(i,200)
for k in range(15):
i = k / 3 # 行
j = k % 3 # 列
item = QTableWidgetItem()
item.setIcon(QIcon('./images/bao%d.png' % k))
tablewidget.setItem(i,j,item)
layout.addWidget(tablewidget)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
example = CellImageSize()
example.show()
sys.exit(app.exec_())
52)在表格中显示上下文菜单
'''
在表格中显示上下文菜单
1. 如何弹出菜单
2. 如果在满足条件的情况下弹出菜单
QMenu.exec_
'''
import sys
from PyQt5.QtWidgets import (QMenu, QPushButton, QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem,
QHeaderView)
from PyQt5.QtCore import QObject, Qt
class TableWidgetContextMenu(QWidget):
def __init__(self):
super(TableWidgetContextMenu,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("在表格中显示上下文菜单")
self.resize(500, 300);
layout = QHBoxLayout()
self.tableWidget = QTableWidget()
self.tableWidget.setRowCount(5)
self.tableWidget.setColumnCount(3)
layout.addWidget(self.tableWidget)
self.tableWidget.setHorizontalHeaderLabels(['姓名', '性别', '体重'])
newItem = QTableWidgetItem("张三")
self.tableWidget.setItem(0, 0, newItem)
newItem = QTableWidgetItem("男")
self.tableWidget.setItem(0, 1, newItem)
newItem = QTableWidgetItem("160")
self.tableWidget.setItem(0, 2, newItem)
# 表格中第二行记录
newItem = QTableWidgetItem("李四")
self.tableWidget.setItem(1, 0, newItem)
newItem = QTableWidgetItem("女")
self.tableWidget.setItem(1, 1, newItem)
newItem = QTableWidgetItem("170")
self.tableWidget.setItem(1, 2, newItem)
# 表格中第二行记录
newItem = QTableWidgetItem("李")
self.tableWidget.setItem(2, 0, newItem)
newItem = QTableWidgetItem("女")
self.tableWidget.setItem(2, 1, newItem)
newItem = QTableWidgetItem("170")
self.tableWidget.setItem(2, 2, newItem)
self.tableWidget.setContextMenuPolicy(Qt.CustomContextMenu)
self.tableWidget.customContextMenuRequested.connect(self.generateMenu)
self.setLayout(layout)
def generateMenu(self,pos):
print(pos)
for i in self.tableWidget.selectionModel().selection().indexes():
rowNum = i.row()
# 如果选择的行索引小于2,弹出上下文菜单
if rowNum < 2:
menu = QMenu()
item1 = menu.addAction("菜单项1")
item2 = menu.addAction("菜单项2")
item3 = menu.addAction("菜单项3")
screenPos = self.tableWidget.mapToGlobal(pos)
print(screenPos)
# 被阻塞
action = menu.exec(screenPos)
if action == item1:
print('选择了第1个菜单项',self.tableWidget.item(rowNum,0).text(),
self.tableWidget.item(rowNum,1).text(),
self.tableWidget.item(rowNum, 2).text())
elif action == item2:
print('选择了第2个菜单项',self.tableWidget.item(rowNum,0).text(),
self.tableWidget.item(rowNum,1).text(),
self.tableWidget.item(rowNum, 2).text())
elif action == item3:
print('选择了第3个菜单项',self.tableWidget.item(rowNum,0).text(),
self.tableWidget.item(rowNum,1).text(),
self.tableWidget.item(rowNum, 2).text())
else:
return
if __name__ == '__main__':
app = QApplication(sys.argv)
example = TableWidgetContextMenu()
example.show()
sys.exit(app.exec_())
53)树控件(QTreeWidget)
'''
树控件(QTreeWidget)的基本用法
'''
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon, QBrush, QColor
from PyQt5.QtCore import Qt
class BasicTreeWidget(QMainWindow):
def __init__(self, parent=None):
super(BasicTreeWidget, self).__init__(parent)
self.setWindowTitle('树控件(QTreeWidget)的基本用法')
self.tree = QTreeWidget()
# 为树控件指定列数
self.tree.setColumnCount(2)
# 指定列标签
self.tree.setHeaderLabels(['Key','Value'])
root = QTreeWidgetItem(self.tree)
root.setText(0,'根节点')
root.setIcon(0,QIcon('./images/root.png'))
self.tree.setColumnWidth(0,160)
# 添加子节点1
child1 = QTreeWidgetItem(root)
child1.setText(0,'子节点1')
child1.setText(1,'子节点1的数据')
child1.setIcon(0,QIcon('./images/bao3.png'))
child1.setCheckState(0,Qt.Checked)
# 添加子节点2
child2 = QTreeWidgetItem(root)
child2.setText(0,'子节点2')
child2.setIcon(0,QIcon('./images/bao6.png'))
# 为child2添加一个子节点
child3 = QTreeWidgetItem(child2)
child3.setText(0,'子节点2-1')
child3.setText(1,'新的值')
child3.setIcon(0,QIcon('./images/music.png'))
self.tree.expandAll()
self.setCentralWidget(self.tree)
if __name__ == '__main__':
app = QApplication(sys.argv)
tree = BasicTreeWidget()
tree.show()
sys.exit(app.exec_())
54)为树节点添加响应事件
'''
为树节点添加响应事件
'''
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
class TreeEvent(QMainWindow):
def __init__(self, parent=None):
super(TreeEvent, self).__init__(parent)
self.setWindowTitle('为树节点添加响应事件')
self.tree = QTreeWidget()
self.tree.setColumnCount(2)
self.tree.setHeaderLabels(['Key','Value'])
root = QTreeWidgetItem(self.tree)
root.setText(0,'root')
root.setText(1, '0')
child1 = QTreeWidgetItem(root)
child1.setText(0,'child1')
child1.setText(1,'1')
child2 = QTreeWidgetItem(root)
child2.setText(0,'child2')
child2.setText(1,'2')
child3 = QTreeWidgetItem(child2)
child3.setText(0,'child3')
child3.setText(1,'3')
self.tree.clicked.connect(self.onTreeClicked)
self.setCentralWidget(self.tree)
def onTreeClicked(self,index):
item = self.tree.currentItem()
print(index.row())
print('key=%s,value=%s' % (item.text(0),item.text(1)))
if __name__ == '__main__':
app = QApplication(sys.argv)
tree = TreeEvent()
tree.show()
sys.exit(app.exec_())
55)增加,修改,删除树控件节点
'''
添加、修改和删除树控件中的节点
'''
import sys
from PyQt5.QtWidgets import *
class ModifyTree(QWidget):
def __init__(self, parent=None):
super(ModifyTree, self).__init__(parent)
self.setWindowTitle('TreeWidget 例子')
operatorLayout = QHBoxLayout()
addBtn = QPushButton('添加节点')
updateBtn = QPushButton('修改节点')
deleteBtn = QPushButton('删除节点')
operatorLayout.addWidget(addBtn)
operatorLayout.addWidget(updateBtn)
operatorLayout.addWidget(deleteBtn)
addBtn.clicked.connect(self.addNode)
updateBtn.clicked.connect(self.updateNode)
deleteBtn.clicked.connect(self.deleteNode)
self.tree = QTreeWidget()
self.tree.setColumnCount(2)
self.tree.setHeaderLabels(['Key','Value'])
root = QTreeWidgetItem(self.tree)
root.setText(0,'root')
root.setText(1, '0')
child1 = QTreeWidgetItem(root)
child1.setText(0,'child1')
child1.setText(1,'1')
child2 = QTreeWidgetItem(root)
child2.setText(0,'child2')
child2.setText(1,'2')
child3 = QTreeWidgetItem(child2)
child3.setText(0,'child3')
child3.setText(1,'3')
self.tree.clicked.connect(self.onTreeClicked)
mainLayout = QVBoxLayout(self)
mainLayout.addLayout(operatorLayout)
mainLayout.addWidget(self.tree)
self.setLayout(mainLayout)
def onTreeClicked(self,index):
item = self.tree.currentItem()
print(index.row())
print('key=%s,value=%s' % (item.text(0),item.text(1)))
# 添加节点
def addNode(self):
print('添加节点')
item = self.tree.currentItem()
print(item)
node = QTreeWidgetItem(item)
node.setText(0,'新节点')
node.setText(1,'新值')
def updateNode(self):
print('修改节点')
item = self.tree.currentItem()
item.setText(0,'修改节点')
item.setText(1, '值已经被修改')
def deleteNode(self):
print('删除节点')
item = self.tree.currentItem()
root = self.tree.invisibleRootItem()
for item in self.tree.selectedItems():
(item.parent() or root).removeChild(item)
if __name__ == '__main__':
app = QApplication(sys.argv)
tree = ModifyTree()
tree.show()
sys.exit(app.exec_())
56)QTreeView控件与系统定制模式
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import sys
'''
QTreeView控件与系统定制模式
QTreeWidget
Model
QDirModel
'''
if __name__ == '__main__':
app = QApplication(sys.argv)
model = QDirModel()
tree = QTreeView()
tree.setModel(model)
tree.setWindowTitle('QTreeView控件与系统定制模式')
tree.resize(600,400)
tree.show()
sys.exit(app.exec_())
容器控件
57)选项卡控件(QTabWidget)
'''
选项卡控件:QTabWidget
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class TabWidgetDemo(QTabWidget):
def __init__(self, parent=None):
super(TabWidgetDemo, self).__init__(parent)
self.setWindowTitle("选项卡控件:QTabWidget")
# 创建用于显示控件的窗口
self.tab1 = QWidget()
self.tab2 = QWidget()
self.tab3 = QWidget()
self.addTab(self.tab1,'选项卡1')
self.addTab(self.tab2,'选项卡2')
self.addTab(self.tab3,'选项卡3')
self.tab1UI()
self.tab2UI()
self.tab3UI()
def tab1UI(self):
layout = QFormLayout()
layout.addRow('姓名',QLineEdit())
layout.addRow('地址',QLineEdit())
self.setTabText(0,'联系方式')
self.tab1.setLayout(layout)
def tab2UI(self):
layout = QFormLayout()
sex = QHBoxLayout()
sex.addWidget(QRadioButton('男'))
sex.addWidget(QRadioButton('女'))
layout.addRow(QLabel('性别'),sex)
layout.addRow('生日',QLineEdit())
self.setTabText(1,'个人详细信息')
self.tab2.setLayout(layout)
def tab3UI(self):
layout = QHBoxLayout()
layout.addWidget(QLabel('科目'))
layout.addWidget(QCheckBox('物理'))
layout.addWidget(QCheckBox('高数'))
self.setTabText(2,'教育程度')
self.tab3.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = TabWidgetDemo()
demo.show()
sys.exit(app.exec_())
58)堆栈窗口控件(QStackedWidget)
'''
堆栈窗口控件(QStackedWidget)
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class StackedExample(QWidget):
def __init__(self):
super(StackedExample, self).__init__()
self.setGeometry(300, 50, 10, 10)
self.setWindowTitle('堆栈窗口控件(QStackedWidget)')
self.list = QListWidget()
self.list.insertItem(0,'联系方式')
self.list.insertItem(1,'个人信息')
self.list.insertItem(2,'教育程度')
self.stack1 = QWidget()
self.stack2 = QWidget()
self.stack3 = QWidget()
self.tab1UI()
self.tab2UI()
self.tab3UI()
self.stack = QStackedWidget()
self.stack.addWidget(self.stack1)
self.stack.addWidget(self.stack2)
self.stack.addWidget(self.stack3)
hbox = QHBoxLayout()
hbox.addWidget(self.list)
hbox.addWidget(self.stack)
self.setLayout(hbox)
self.list.currentRowChanged.connect(self.display)
def tab1UI(self):
layout = QFormLayout()
layout.addRow('姓名',QLineEdit())
layout.addRow('地址',QLineEdit())
self.stack1.setLayout(layout)
def tab2UI(self):
layout = QFormLayout()
sex = QHBoxLayout()
sex.addWidget(QRadioButton('男'))
sex.addWidget(QRadioButton('女'))
layout.addRow(QLabel('性别'),sex)
layout.addRow('生日',QLineEdit())
self.stack2.setLayout(layout)
def tab3UI(self):
layout = QHBoxLayout()
layout.addWidget(QLabel('科目'))
layout.addWidget(QCheckBox('物理'))
layout.addWidget(QCheckBox('高数'))
self.stack3.setLayout(layout)
def display(self,index):
self.stack.setCurrentIndex(index)
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = StackedExample()
demo.show()
sys.exit(app.exec_())
59) 停靠控件(QDockWidget)
'''
停靠控件(QDockWidget)
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class DockDemo(QMainWindow):
def __init__(self, parent=None):
super(DockDemo, self).__init__(parent)
self.setWindowTitle("停靠控件(QDockWidget)")
layout = QHBoxLayout()
self.items = QDockWidget('Dockable',self)
self.listWidget = QListWidget()
self.listWidget.addItem('item1')
self.listWidget.addItem('item2')
self.listWidget.addItem('item3')
self.items.setWidget(self.listWidget)
self.setCentralWidget(QLineEdit())
self.items.setFloating(True)
self.addDockWidget(Qt.RightDockWidgetArea,self.items)
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = DockDemo()
demo.show()
sys.exit(app.exec_())
60)容纳多文档的窗口(QMdiArea)
'''
容纳多文档的窗口
QMdiArea
QMdiSubWindow
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class MultiWindows(QMainWindow):
count = 0
def __init__(self, parent=None):
super(MultiWindows, self).__init__(parent)
self.setWindowTitle("容纳多文档的窗口")
self.mdi = QMdiArea()
self.setCentralWidget(self.mdi)
bar = self.menuBar()
file = bar.addMenu("File")
file.addAction("New")
file.addAction("cascade")
file.addAction("Tiled")
file.triggered.connect(self.windowaction)
def windowaction(self,q):
print(q.text())
if q.text() == "New":
MultiWindows.count = MultiWindows.count + 1
sub = QMdiSubWindow()
sub.setWidget(QTextEdit())
sub.setWindowTitle("子窗口" + str(MultiWindows.count))
self.mdi.addSubWindow(sub)
sub.show()
elif q.text() == "cascade":
self.mdi.cascadeSubWindows()
elif q.text() == "Tiled":
self.mdi.tileSubWindows()
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = MultiWindows()
demo.show()
sys.exit(app.exec_())
61)滚动条控件(QScrollBar)
'''
滚动条控件(QScrollBar)
QScrollBar的作用
1. 通过滚动条值的变化控制其他控件状态的变化
2. 通过滚动条值的变化控制控件位置的变化
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class ScrollBar(QWidget):
def __init__(self):
super(ScrollBar, self).__init__()
self.initUI()
def initUI(self):
hbox = QHBoxLayout()
self.label = QLabel('拖动滚动条去改变文字颜色')
hbox.addWidget(self.label)
self.scrollbar1 = QScrollBar()
self.scrollbar1.setMaximum(255)
self.scrollbar1.sliderMoved.connect(self.sliderMoved)
self.scrollbar2 = QScrollBar()
self.scrollbar2.setMaximum(255)
self.scrollbar2.sliderMoved.connect(self.sliderMoved)
self.scrollbar3 = QScrollBar()
self.scrollbar3.setMaximum(255)
self.scrollbar3.sliderMoved.connect(self.sliderMoved)
self.scrollbar4 = QScrollBar()
self.scrollbar4.setMaximum(255)
self.scrollbar4.sliderMoved.connect(self.sliderMoved1)
hbox.addWidget(self.scrollbar1)
hbox.addWidget(self.scrollbar2)
hbox.addWidget(self.scrollbar3)
hbox.addWidget(self.scrollbar4)
self.setGeometry(300,300,300,200)
self.setLayout(hbox)
self.y = self.label.pos().y()
def sliderMoved(self):
print(self.scrollbar1.value(),self.scrollbar2.value(),self.scrollbar3.value())
palette = QPalette()
c = QColor(self.scrollbar1.value(),self.scrollbar2.value(),self.scrollbar3.value(),255)
palette.setColor(QPalette.Foreground,c)
self.label.setPalette(palette)
def sliderMoved1(self):
self.label.move(self.label.x(),self.y + self.scrollbar4.value())
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = ScrollBar()
demo.show()
sys.exit(app.exec_())
多线程
62)动态显示当前时间(QTimer)
'''
动态显示当前时间
QTimer
QThread
多线程:用于同时完成多个任务
'''
from PyQt5.QtWidgets import QWidget, QPushButton, QApplication, QListWidget, QGridLayout, QLabel
from PyQt5.QtCore import QTimer, QDateTime
import sys
class ShowTime(QWidget):
def __init__(self, parent=None):
super(ShowTime, self).__init__(parent)
self.setWindowTitle("动态显示当前时间")
self.label = QLabel('显示当前时间')
self.startBtn = QPushButton('开始')
self.endBtn = QPushButton('结束')
layout= QGridLayout()
self.timer = QTimer()
self.timer.timeout.connect(self.showTime)
layout.addWidget(self.label,0,0,1,2)
layout.addWidget(self.startBtn,1,0)
layout.addWidget(self.endBtn,1,1)
self.startBtn.clicked.connect(self.startTimer)
self.endBtn.clicked.connect(self.endTimer)
self.setLayout(layout)
def showTime(self):
time = QDateTime.currentDateTime()
timeDisplay = time.toString("yyyy-MM-dd hh:mm:ss dddd")
self.label.setText(timeDisplay)
def startTimer(self):
self.timer.start(1000)
self.startBtn.setEnabled(False)
self.endBtn.setEnabled(True)
def endTimer(self):
self.timer.stop()
self.startBtn.setEnabled(True)
self.endBtn.setEnabled(False)
if __name__ == "__main__":
app = QApplication(sys.argv)
form = ShowTime()
form.show()
sys.exit(app.exec_())
63)让窗口定时关闭
'''
让程序定时关闭
QTimer.singleShot
'''
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
if __name__ == '__main__':
app = QApplication(sys.argv)
label = QLabel('<font color=red size=140><b>Hello World,窗口在5秒后自动关闭!</b></font>')
label.setWindowFlags(Qt.SplashScreen | Qt.FramelessWindowHint)
label.show()
QTimer.singleShot(5000,app.quit)
sys.exit(app.exec_())
64)使用线程类(QThread)
'''
使用线程类(QThread)编写计数器
QThread
def run(self):
while True:
self.sleep(1)
if sec == 5:
break;
QLCDNumber
WorkThread(QThread)
用到自定义信号
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
sec = 0
class WorkThread(QThread):
timer = pyqtSignal() # 每隔1秒发送一次信号
end = pyqtSignal() # 计数完成后发送一次信号
def run(self):
while True:
self.sleep(1) # 休眠1秒
if sec == 5:
self.end.emit() # 发送end信号
break
self.timer.emit() # 发送timer信号
class Counter(QWidget):
def __init__(self, parent=None):
super(Counter, self).__init__(parent)
self.setWindowTitle("使用线程类(QThread)编写计数器")
self.resize(300, 120)
layout = QVBoxLayout()
self.lcdNumber = QLCDNumber()
layout.addWidget(self.lcdNumber)
button = QPushButton('开始计数')
layout.addWidget(button)
self.workThread = WorkThread()
self.workThread.timer.connect(self.countTime)
self.workThread.end.connect(self.end)
button.clicked.connect(self.work)
self.setLayout(layout)
def countTime(self):
global sec
sec += 1
self.lcdNumber.display(sec)
def end(self):
QMessageBox.information(self,'消息','计数结束',QMessageBox.Ok)
def work(self):
self.workThread.start()
if __name__ == "__main__":
app = QApplication(sys.argv)
form = Counter()
form.show()
sys.exit(app.exec_())
web交互技术
65)使用web浏览器控件(QWebEngineView)
'''
用Web浏览器控件(QWebEngineView)显示网页
PyQt5和Web的交互技术
同时使用Python和Web开发程序,混合开发
Python+JavaScript+HTML5+CSS
QWebEngineView
'''
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import sys
class WebEngineView(QMainWindow):
def __init__(self ):
super(WebEngineView, self).__init__()
self.setWindowTitle('打开外部网页例子')
self.setGeometry(5, 30, 1355, 730)
self.browser = QWebEngineView()
self.browser.load(QUrl('https://www.jd.com'))
self.setCentralWidget(self.browser)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = WebEngineView()
win.show()
sys.exit(app.exec_())
66)装载本地web页面
'''
装载本地Web页面
'''
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import sys
import os
class WebEngineView(QMainWindow):
def __init__(self ):
super(WebEngineView, self).__init__()
self.setWindowTitle('装载本地Web页面')
self.setGeometry(5, 30, 1355, 730)
url = os.getcwd() + '/test.html'
self.browser = QWebEngineView()
self.browser.load(QUrl.fromLocalFile(url))
self.setCentralWidget(self.browser)
print(os.getcwd())
if __name__ == '__main__':
app = QApplication(sys.argv)
win = WebEngineView()
win.show()
sys.exit(app.exec_())
67)显示嵌入web页面
'''
显示嵌入Web页面
'''
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import sys
import os
class InnerHTML(QMainWindow):
def __init__(self ):
super(InnerHTML, self).__init__()
self.setWindowTitle('显示嵌入Web页面')
self.setGeometry(5, 30, 1355, 730)
self.browser = QWebEngineView()
self.browser.setHtml('''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试页面</title>
</head>
<body>
<h1>Hello PyQt5</h1>
<h2>Hello PyQt5</h2>
<h3>Hello PyQt5</h3>
<h4>Hello PyQt5</h4>
</body>
</html>
''')
self.setCentralWidget(self.browser)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = InnerHTML()
win.show()
sys.exit(app.exec_())
68)pyqt5调用js代码
'''
PyQt5调用JavaScript代码
PyQt5和JavaScript交互
什么叫交互
PyQt5 <-> JavaScript
'''
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import sys
import os
class PyQtCallJS(QWidget):
def __init__(self):
super(PyQtCallJS, self).__init__()
self.setWindowTitle('PyQt5调用JavaScript')
self.setGeometry(5, 30, 1355, 730)
self.layout = QVBoxLayout()
self.setLayout(self.layout)
self.browser = QWebEngineView()
url = os.getcwd() + '/tt.html'
self.browser.load(QUrl.fromLocalFile(url))
self.layout.addWidget(self.browser)
button = QPushButton('设置全名')
button.clicked.connect(self.fullname)
self.layout.addWidget(button)
def js_callback(self,result):
print(result)
def fullname(self):
self.value = 'hello world'
self.browser.page().runJavaScript('fullname("' + self.value + '");',self.js_callback)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = PyQtCallJS()
win.show()
sys.exit(app.exec_())
69)js调用Python API
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtCore import *
from MySharedObject import MySharedObject
from PyQt5.QtWebChannel import QWebChannel
import sys
import os
'''
JavaScript调用Python函数计算阶乘
将Python的一个对象映射到JavaScript中
将槽函数映射到JavaScript中
'''
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import sys
import os
from factorial import *
channel = QWebChannel()
factorial = Factorial()
class PyFactorial(QWidget):
def __init__(self):
super(PyFactorial, self).__init__()
self.setWindowTitle('Python计算阶乘')
self.resize(600,300)
layout=QVBoxLayout()
self.browser = QWebEngineView()
url = os.getcwd() + '/f.html'
self.browser.load(QUrl.fromLocalFile(url))
channel.registerObject("obj",factorial)
self.browser.page().setWebChannel(channel)
layout.addWidget(self.browser)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = PyFactorial()
win.show()
sys.exit(app.exec_())
html 调用js,js调用Python api
<html>
<head>
<title>A Demo Page</title>
<meta charset="UTF-8">
<script src="./qwebchannel.js"></script>
<script language="javascript">
function callback(result) {
alert('计算结果:' + result)
}
document.addEventListener("DOMContentLoaded", function () {
new QWebChannel( qt.webChannelTransport, function(channel) {
window.obj = channel.objects.obj;
});
});
function onFactorial() {
if ( window.obj) {
var n = parseInt(document.getElementById('n').value);
window.obj.factorial(n,callback)
}
}
</script>
</head>
<body>
<form>
<label >请输入N:</label>
<input type="text" id="n"></input>
<br />
<input type="button" value="计算阶乘" onclick="onFactorial()">
</form>
</body>
</html>
js 调用Python(官方可以下载)
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtWebChannel module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
"use strict";
var QWebChannelMessageTypes = {
signal: 1,
propertyUpdate: 2,
init: 3,
idle: 4,
debug: 5,
invokeMethod: 6,
connectToSignal: 7,
disconnectFromSignal: 8,
setProperty: 9,
response: 10,
};
var QWebChannel = function(transport, initCallback)
{
if (typeof transport !== "object" || typeof transport.send !== "function") {
console.error("The QWebChannel expects a transport object with a send function and onmessage callback property." +
" Given is: transport: " + typeof(transport) + ", transport.send: " + typeof(transport.send));
return;
}
var channel = this;
this.transport = transport;
this.send = function(data)
{
if (typeof(data) !== "string") {
data = JSON.stringify(data);
}
channel.transport.send(data);
}
this.transport.onmessage = function(message)
{
var data = message.data;
if (typeof data === "string") {
data = JSON.parse(data);
}
switch (data.type) {
case QWebChannelMessageTypes.signal:
channel.handleSignal(data);
break;
case QWebChannelMessageTypes.response:
channel.handleResponse(data);
break;
case QWebChannelMessageTypes.propertyUpdate:
channel.handlePropertyUpdate(data);
break;
default:
console.error("invalid message received:", message.data);
break;
}
}
this.execCallbacks = {};
this.execId = 0;
this.exec = function(data, callback)
{
if (!callback) {
// if no callback is given, send directly
channel.send(data);
return;
}
if (channel.execId === Number.MAX_VALUE) {
// wrap
channel.execId = Number.MIN_VALUE;
}
if (data.hasOwnProperty("id")) {
console.error("Cannot exec message with property id: " + JSON.stringify(data));
return;
}
data.id = channel.execId++;
channel.execCallbacks[data.id] = callback;
channel.send(data);
};
this.objects = {};
this.handleSignal = function(message)
{
var object = channel.objects[message.object];
if (object) {
object.signalEmitted(message.signal, message.args);
} else {
console.warn("Unhandled signal: " + message.object + "::" + message.signal);
}
}
this.handleResponse = function(message)
{
if (!message.hasOwnProperty("id")) {
console.error("Invalid response message received: ", JSON.stringify(message));
return;
}
channel.execCallbacks[message.id](message.data);
delete channel.execCallbacks[message.id];
}
this.handlePropertyUpdate = function(message)
{
for (var i in message.data) {
var data = message.data[i];
var object = channel.objects[data.object];
if (object) {
object.propertyUpdate(data.signals, data.properties);
} else {
console.warn("Unhandled property update: " + data.object + "::" + data.signal);
}
}
channel.exec({type: QWebChannelMessageTypes.idle});
}
this.debug = function(message)
{
channel.send({type: QWebChannelMessageTypes.debug, data: message});
};
channel.exec({type: QWebChannelMessageTypes.init}, function(data) {
for (var objectName in data) {
var object = new QObject(objectName, data[objectName], channel);
}
// now unwrap properties, which might reference other registered objects
for (var objectName in channel.objects) {
channel.objects[objectName].unwrapProperties();
}
if (initCallback) {
initCallback(channel);
}
channel.exec({type: QWebChannelMessageTypes.idle});
});
};
function QObject(name, data, webChannel)
{
this.__id__ = name;
webChannel.objects[name] = this;
// List of callbacks that get invoked upon signal emission
this.__objectSignals__ = {};
// Cache of all properties, updated when a notify signal is emitted
this.__propertyCache__ = {};
var object = this;
// ----------------------------------------------------------------------
this.unwrapQObject = function(response)
{
if (response instanceof Array) {
// support list of objects
var ret = new Array(response.length);
for (var i = 0; i < response.length; ++i) {
ret[i] = object.unwrapQObject(response[i]);
}
return ret;
}
if (!response
|| !response["__QObject*__"]
|| response.id === undefined) {
return response;
}
var objectId = response.id;
if (webChannel.objects[objectId])
return webChannel.objects[objectId];
if (!response.data) {
console.error("Cannot unwrap unknown QObject " + objectId + " without data.");
return;
}
var qObject = new QObject( objectId, response.data, webChannel );
qObject.destroyed.connect(function() {
if (webChannel.objects[objectId] === qObject) {
delete webChannel.objects[objectId];
// reset the now deleted QObject to an empty {} object
// just assigning {} though would not have the desired effect, but the
// below also ensures all external references will see the empty map
// NOTE: this detour is necessary to workaround QTBUG-40021
var propertyNames = [];
for (var propertyName in qObject) {
propertyNames.push(propertyName);
}
for (var idx in propertyNames) {
delete qObject[propertyNames[idx]];
}
}
});
// here we are already initialized, and thus must directly unwrap the properties
qObject.unwrapProperties();
return qObject;
}
this.unwrapProperties = function()
{
for (var propertyIdx in object.__propertyCache__) {
object.__propertyCache__[propertyIdx] = object.unwrapQObject(object.__propertyCache__[propertyIdx]);
}
}
function addSignal(signalData, isPropertyNotifySignal)
{
var signalName = signalData[0];
var signalIndex = signalData[1];
object[signalName] = {
connect: function(callback) {
if (typeof(callback) !== "function") {
console.error("Bad callback given to connect to signal " + signalName);
return;
}
object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || [];
object.__objectSignals__[signalIndex].push(callback);
if (!isPropertyNotifySignal && signalName !== "destroyed") {
// only required for "pure" signals, handled separately for properties in propertyUpdate
// also note that we always get notified about the destroyed signal
webChannel.exec({
type: QWebChannelMessageTypes.connectToSignal,
object: object.__id__,
signal: signalIndex
});
}
},
disconnect: function(callback) {
if (typeof(callback) !== "function") {
console.error("Bad callback given to disconnect from signal " + signalName);
return;
}
object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || [];
var idx = object.__objectSignals__[signalIndex].indexOf(callback);
if (idx === -1) {
console.error("Cannot find connection of signal " + signalName + " to " + callback.name);
return;
}
object.__objectSignals__[signalIndex].splice(idx, 1);
if (!isPropertyNotifySignal && object.__objectSignals__[signalIndex].length === 0) {
// only required for "pure" signals, handled separately for properties in propertyUpdate
webChannel.exec({
type: QWebChannelMessageTypes.disconnectFromSignal,
object: object.__id__,
signal: signalIndex
});
}
}
};
}
/**
* Invokes all callbacks for the given signalname. Also works for property notify callbacks.
*/
function invokeSignalCallbacks(signalName, signalArgs)
{
var connections = object.__objectSignals__[signalName];
if (connections) {
connections.forEach(function(callback) {
callback.apply(callback, signalArgs);
});
}
}
this.propertyUpdate = function(signals, propertyMap)
{
// update property cache
for (var propertyIndex in propertyMap) {
var propertyValue = propertyMap[propertyIndex];
object.__propertyCache__[propertyIndex] = propertyValue;
}
for (var signalName in signals) {
// Invoke all callbacks, as signalEmitted() does not. This ensures the
// property cache is updated before the callbacks are invoked.
invokeSignalCallbacks(signalName, signals[signalName]);
}
}
this.signalEmitted = function(signalName, signalArgs)
{
invokeSignalCallbacks(signalName, signalArgs);
}
function addMethod(methodData)
{
var methodName = methodData[0];
var methodIdx = methodData[1];
object[methodName] = function() {
var args = [];
var callback;
for (var i = 0; i < arguments.length; ++i) {
if (typeof arguments[i] === "function")
callback = arguments[i];
else
args.push(arguments[i]);
}
webChannel.exec({
"type": QWebChannelMessageTypes.invokeMethod,
"object": object.__id__,
"method": methodIdx,
"args": args
}, function(response) {
if (response !== undefined) {
var result = object.unwrapQObject(response);
if (callback) {
(callback)(result);
}
}
});
};
}
function bindGetterSetter(propertyInfo)
{
var propertyIndex = propertyInfo[0];
var propertyName = propertyInfo[1];
var notifySignalData = propertyInfo[2];
// initialize property cache with current value
// NOTE: if this is an object, it is not directly unwrapped as it might
// reference other QObject that we do not know yet
object.__propertyCache__[propertyIndex] = propertyInfo[3];
if (notifySignalData) {
if (notifySignalData[0] === 1) {
// signal name is optimized away, reconstruct the actual name
notifySignalData[0] = propertyName + "Changed";
}
addSignal(notifySignalData, true);
}
Object.defineProperty(object, propertyName, {
configurable: true,
get: function () {
var propertyValue = object.__propertyCache__[propertyIndex];
if (propertyValue === undefined) {
// This shouldn't happen
console.warn("Undefined value in property cache for property \"" + propertyName + "\" in object " + object.__id__);
}
return propertyValue;
},
set: function(value) {
if (value === undefined) {
console.warn("Property setter for " + propertyName + " called with undefined value!");
return;
}
object.__propertyCache__[propertyIndex] = value;
webChannel.exec({
"type": QWebChannelMessageTypes.setProperty,
"object": object.__id__,
"property": propertyIndex,
"value": value
});
}
});
}
// ----------------------------------------------------------------------
data.methods.forEach(addMethod);
data.properties.forEach(bindGetterSetter);
data.signals.forEach(function(signal) { addSignal(signal, false); });
for (var name in data.enums) {
object[name] = data.enums[name];
}
}
//required for use with nodejs
if (typeof module === 'object') {
module.exports = {
QWebChannel: QWebChannel
};
}
阶乘函数
from PyQt5.QtCore import *
class Factorial(QObject):
@pyqtSlot(int, result=int)
def factorial(self,n):
if n == 0 or n == 1:
return 1
else:
return self.factorial(n - 1) * n
布局
70)绝对布局
'''
绝对布局, 通过.move(x,y )来定位
'''
import sys,math
from PyQt5.QtWidgets import *
class AbsoluteLayout(QWidget) :
def __init__(self):
super(AbsoluteLayout,self).__init__()
self.setWindowTitle("绝对布局")
self.label1 = QLabel('欢迎',self)
self.label1.move(15,20)
self.label2 = QLabel('学习',self)
self.label2.move(35,40)
self.label3 = QLabel('PyQt5',self)
self.label3.move(55,80)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = AbsoluteLayout()
main.show()
sys.exit(app.exec_())
71)水平盒布局(QHBoxLayout)
'''
水平盒布局(QHBoxLayout)
'''
import sys,math
from PyQt5.QtWidgets import *
class HBoxLayout(QWidget) :
def __init__(self):
super(HBoxLayout,self).__init__()
self.setWindowTitle("水平盒布局")
hlayout = QHBoxLayout()
hlayout.addWidget(QPushButton('按钮1'))
hlayout.addWidget(QPushButton('按钮2'))
hlayout.addWidget(QPushButton('按钮3'))
hlayout.addWidget(QPushButton('按钮4'))
hlayout.addWidget(QPushButton('按钮5'))
hlayout.setSpacing(40)
self.setLayout(hlayout)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = HBoxLayout()
main.show()
sys.exit(app.exec_())
72)设置控件的对齐方式
'''
设置控件的对齐方式
'''
import sys, math
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
class HBoxLayoutAlign(QWidget):
def __init__(self):
super(HBoxLayoutAlign, self).__init__()
self.setWindowTitle("水平盒布局")
hlayout = QHBoxLayout()
hlayout.addWidget(QPushButton('按钮1'), 2, Qt.AlignLeft | Qt.AlignTop)
hlayout.addWidget(QPushButton('按钮2'), 4, Qt.AlignLeft | Qt.AlignTop)
hlayout.addWidget(QPushButton('按钮3'), 1, Qt.AlignLeft | Qt.AlignTop)
hlayout.addWidget(QPushButton('按钮4'), 1, Qt.AlignLeft | Qt.AlignBottom)
hlayout.addWidget(QPushButton('按钮5'), 1, Qt.AlignLeft | Qt.AlignBottom)
hlayout.setSpacing(40)
self.setLayout(hlayout)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = HBoxLayoutAlign()
main.show()
sys.exit(app.exec_())
73)垂直盒布局(QBoxLayout)
'''
垂直盒布局(QBoxLayout)
'''
import sys,math
from PyQt5.QtWidgets import *
class VBoxLayout(QWidget) :
def __init__(self):
super(VBoxLayout,self).__init__()
self.setWindowTitle("垂直盒布局")
layout = QVBoxLayout()
layout.addWidget(QPushButton('按钮1'))
layout.addWidget(QPushButton('按钮2'))
layout.addWidget(QPushButton('按钮3'))
layout.addWidget(QPushButton('按钮4'))
layout.addWidget(QPushButton('按钮5'))
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = VBoxLayout()
main.show()
sys.exit(app.exec_())
74)设置布局的伸缩量
'''
设置伸缩量(addStretch)
'''
import sys,math
from PyQt5.QtWidgets import *
class Stretch(QWidget) :
def __init__(self):
super(Stretch,self).__init__()
self.setWindowTitle("设置伸缩量")
btn1 = QPushButton(self)
btn2 = QPushButton(self)
btn3 = QPushButton(self)
btn1.setText("按钮1")
btn2.setText("按钮2")
btn3.setText("按钮3")
layout = QHBoxLayout()
layout.addStretch(1)
layout.addWidget(btn1)
layout.addStretch(2)
layout.addWidget(btn2)
layout.addStretch(3)
layout.addWidget(btn3)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Stretch()
main.show()
sys.exit(app.exec_())
75)让按钮永远在窗口的右下角
'''
让按钮永远在窗口右下角
'''
import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
class RightBottomButton(QWidget) :
def __init__(self):
super(RightBottomButton,self).__init__()
self.setWindowTitle("让按钮永远在右下角")
self.resize(400,300)
okButton = QPushButton("确定")
cancelButton = QPushButton("取消")
hbox = QHBoxLayout()
hbox.addStretch(1)
hbox.addWidget(okButton)
hbox.addWidget(cancelButton)
vbox = QVBoxLayout()
btn1 = QPushButton("按钮1")
btn2 = QPushButton("按钮2")
btn3 = QPushButton("按钮3")
vbox.addStretch(0)
vbox.addWidget(btn1)
vbox.addWidget(btn2)
vbox.addWidget(btn3)
vbox.addStretch(1)
vbox.addLayout(hbox)
self.setLayout(vbox)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = RightBottomButton()
main.show()
sys.exit(app.exec_())
76)栅格布局:用循环方式实现计算器UI
'''
栅格布局:实现计算器UI
'''
import sys, math
from PyQt5.QtWidgets import *
class Calc(QWidget):
def __init__(self):
super(Calc, self).__init__()
self.setWindowTitle("栅格布局")
grid = QGridLayout()
self.setLayout(grid)
names = ['Cls', 'Back', '', 'Close',
'7', '8', '9', '/',
'4', '5', '6', '*',
'1', '2', '3', '-',
'0', '.', '=', '+']
positions = [(i, j) for i in range(5) for j in range(4)]
print(positions)
for position, name in zip(positions, names):
if name == '':
continue
button = QPushButton(name)
# print(position)
grid.addWidget(button, *position)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Calc()
main.show()
sys.exit(app.exec_())
77)栅格布局:进行表单UI设计
'''
栅格布局:表单设计
'''
import sys,math
from PyQt5.QtWidgets import *
class GridForm(QWidget) :
def __init__(self):
super(GridForm,self).__init__()
self.setWindowTitle("栅格布局:表单设计")
titleLabel = QLabel('标题')
authorLabel = QLabel('作者')
contentLabel = QLabel('内容')
titleEdit = QLineEdit()
authorEdit = QLineEdit()
contentEdit = QTextEdit()
grid = QGridLayout()
grid.setSpacing(10)
grid.addWidget(titleLabel,1,0)
grid.addWidget(titleEdit,1,1)
grid.addWidget(authorLabel,2,0)
grid.addWidget(authorEdit,2,1)
grid.addWidget(contentLabel,3,0)
grid.addWidget(contentEdit,3,1,5,1)
self.setLayout(grid)
self.resize(350,300)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = GridForm()
main.show()
sys.exit(app.exec_())
78)表单布局
'''
表单布局(QFormLayout)
'''
import sys,math
from PyQt5.QtWidgets import *
class FormForm(QWidget) :
def __init__(self):
super(FormForm,self).__init__()
self.setWindowTitle("表单布局")
self.resize(350,300)
formLayout = QFormLayout()
titleLabel = QLabel('标题')
authorLabel = QLabel('作者')
contentLabel = QLabel('内容')
titleEdit = QLineEdit()
authorEdit = QLineEdit()
contentEdit = QTextEdit()
formLayout.addRow(titleLabel,titleEdit)
formLayout.addRow(authorLabel,authorEdit)
formLayout.addRow(contentLabel,contentEdit)
self.setLayout(formLayout)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = FormForm()
main.show()
sys.exit(app.exec_())
79)拖动控件之间的边界(QSplitter分裂器)
'''
拖动控件之间的边界(QSplitter)
'''
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class Splitter(QWidget):
def __init__(self):
super(Splitter, self).__init__()
self.initUI()
def initUI(self):
hbox = QHBoxLayout(self)
self.setWindowTitle('QSplitter 例子')
self.setGeometry(300, 300, 300, 200)
topleft = QFrame()
topleft.setFrameShape(QFrame.StyledPanel)
bottom = QFrame()
bottom.setFrameShape(QFrame.StyledPanel)
splitter1 = QSplitter(Qt.Horizontal)
textedit = QTextEdit()
splitter1.addWidget(topleft)
splitter1.addWidget(textedit)
splitter1.setSizes([200,100])
splitter2 = QSplitter(Qt.Vertical)
splitter2.addWidget(splitter1)
splitter2.addWidget(bottom)
hbox.addWidget(splitter2)
self.setLayout(hbox)
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = Splitter()
demo.show()
sys.exit(app.exec_())