#QWebEngineView 控件 可以当做浏览器(setting 中添加 PyQtWebEngine 包)
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
class WebEngineView(QMainWindow):
def __init__(self):
super().__init__()
self.resize(1000,600)
webbrowser = QWebEngineView() #QWebEngineView也是一个容器控件
webbrowser.load(QUrl('https://www.baidu.com'))
self.setCentralWidget(webbrowser) #QMainWindow 继承自QWidget ,带有菜单栏,工具栏,状态栏等额外的内容,当然也可以设置setCentralWidget,这样一对比,QWidget难道是全裸么?
self.button = QPushButton('btn') #QPushButton 继承顺序是 QPushButton->QAbstractButton->QWidget->QObject,没有经过QMainWindow
if __name__ == '__main__':
app = QApplication(sys.argv)
main = WebEngineView()
main.show()
sys.exit(app.exec_())
#装载本地web页面
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import os
class WebEngineView(QMainWindow):
def __init__(self):
super().__init__()
self.resize(1000,600)
self.setWindowTitle('装载本地文本页面')
webbrowser = QWebEngineView()
url = os.getcwd()+'/index.html' #获取当前路径 Return a unicode string representing the current working directory.
webbrowser.load(QUrl.fromLocalFile(url)) #用QUrl.fromLocalFile加载url
self.setCentralWidget(webbrowser)
self.button = QPushButton('btn')
if __name__ == '__main__':
app = QApplication(sys.argv)
main = WebEngineView()
main.show()
sys.exit(app.exec_())
#显示嵌入的HTML代码
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import os
class WebEngineView(QMainWindow):
def __init__(self):
super().__init__()
self.resize(1000,600)
self.setWindowTitle('装载本地文本页面')
webbrowser = QWebEngineView()
webbrowser.setHtml('''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<h1>hello</h1>
<h2>hello</h2>
<h3>Hello</h3>
</body>
</html>
''')
self.setCentralWidget(webbrowser)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = WebEngineView()
main.show()
sys.exit(app.exec_())
# 前面的三种加载web页面的方式很LOW!!!,这个例子介绍PyQt5和JavaScript交互 ,互相传递数据
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import os
class PyQtCallJavaScript(QWidget):
def __init__(self):
super().__init__()
self.resize(300, 200)
self.setWindowTitle('装载本地文本页面')
layout = QVBoxLayout(self) #这里用到布局,类就要继承QWidget,如果继承QMainWindow好像没有效果
url = os.getcwd()+'/index.html'
self.webbrowser = QWebEngineView()
self.webbrowser.load(QUrl.fromLocalFile(url))
#这只一个button调用html中的js代码
self.button = QPushButton('点击')
layout.addWidget(self.webbrowser)
layout.addWidget(self.button)
self.button.clicked.connect(self.btn_click)
def callback(self,value):#接收js函数的返回值,并打印
print(value)
def btn_click(self):
self.value = 'tom'
self.webbrowser.page().runJavaScript('myname("'+self.value+'");',self.callback)
#runJavaScript 第一个参数是html页面的js函数,后面callback是回调函数,并把js函数结果给到回调函数的参数
if __name__ == '__main__':
app = QApplication(sys.argv)
main = PyQtCallJavaScript()
main.show()
sys.exit(app.exec_())
html代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
<script>
function myname(value){
alert(value)
document.getElementById('username').value = value
return 'hello' //返回值
}
</script>
</head>
<body>
<form>
<label>姓名:</label><input type="text" name="name" id="username">
<label>年龄:</label><input type="text" name="age" >
<input type="submit" />
</form>
</body>
</html>
# 水平盒布局
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import os
class QHBoxLayoutDemo(QWidget):
def __init__(self):
super().__init__()
self.resize(300, 200)
self.setWindowTitle('水平盒布局')
layout = QHBoxLayout(self)
#layout = QVBoxLayout(self) #垂直布局
layout.addWidget(QPushButton('btn1'),1,Qt.AlignLeft|Qt.AlignTop)
layout.addWidget(QPushButton('btn2'),2,Qt.AlignLeft|Qt.AlignTop)
layout.addWidget(QPushButton('btn3'),1,Qt.AlignLeft|Qt.AlignTop)
layout.addWidget(QPushButton('btn4'),1,Qt.AlignLeft|Qt.AlignBottom)
layout.addWidget(QPushButton('btn5'),1,Qt.AlignLeft|Qt.AlignBottom)
layout.setSpacing(20)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QHBoxLayoutDemo()
main.show()
sys.exit(app.exec_())
# QThread线程再测试
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import os
import time
class MyThread(QThread): #这里创建一个线程,用于每1秒,输出到控制台一个hello
def __init__(self):
super().__init__()
def run(self): #线程是持续的,
while 1:
time.sleep(1)
print('hello')
class PyQtCallJavaScript(QWidget):
def __init__(self):
super().__init__()
self.resize(300, 200)
self.setWindowTitle('QThread demo')
self.layout = QHBoxLayout(self)
self.button = QPushButton('start thread')
self.button.clicked.connect(self.btn_click) #绑定按钮单击信号和槽函数
self.layout.addWidget(self.button)
self.thread1 = MyThread() #一般把线程定义在初始化的地方
def btn_click(self):
# thread1 = MyThread()
# thread1.start()
self.label = QLabel('hello')
self.layout.addWidget(self.label) #在槽函数里,可以动态添加控件label,却没法动态实例一个线程并运行,程序会被迫关闭
if __name__ == '__main__':
app = QApplication(sys.argv)
main = PyQtCallJavaScript()
main.show()
sys.exit(app.exec_())
# 设置伸缩量
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import os
class Stretch(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('设置伸缩量')
layout = QHBoxLayout(self)
self.btn1 = QPushButton('btn1')
self.btn2 = QPushButton('btn2')
self.btn3 = QPushButton('btn3')
self.btn4 = QPushButton('btn4')
self.btn5 = QPushButton('btn5')
layout.addStretch(0)
layout.addWidget(self.btn1)
layout.addWidget(self.btn2)
layout.addWidget(self.btn3)
layout.addWidget(self.btn4)
layout.addStretch(1)
layout.addWidget(self.btn5) #前面4个按钮靠左紧凑排列,最后一个靠右
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Stretch()
main.show()
sys.exit(app.exec_())
# 设置伸缩量
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import os
class Stretch(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('设置伸缩量')
self.resize(400,300)
layout = QHBoxLayout() #水平布局放3个右下角的按钮
self.btn1 = QPushButton('Cancel')
self.btn2 = QPushButton('Apply')
self.btn3 = QPushButton('Ok')
layout.addStretch(1)
layout.addWidget(self.btn1)
layout.addWidget(self.btn2)
layout.addWidget(self.btn3)
layout2 = QVBoxLayout() #垂直布局放3个按钮及右下角的按钮
self.btn4 = QPushButton('btn1')
self.btn5 = QPushButton('btn2')
self.btn6 = QPushButton('btn3')
layout2.addStretch(0)
layout2.addWidget(self.btn4)
layout2.addWidget(self.btn5)
layout2.addWidget(self.btn6)
layout2.addStretch(1)
layout2.addLayout(layout)
self.setLayout(layout2) #设置整个界面的垂直布局
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Stretch()
main.show()
sys.exit(app.exec_())
# 栅格布局 QGridLayout
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import os
class QGridLayoutDemo(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('栅格布局')
layout = QGridLayout()
self.setLayout(layout)
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)] #列表推导式 ,嗯,代码很优雅!!!
for position,name in zip(positions,names): #zip拉链函数 ,可以把多个迭代器 一一对应 连在一起
if name != '':
layout.addWidget(QPushButton(name),*position) #*加元素等于打散 *(int1,int2)=int1 int2
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QGridLayoutDemo()
main.show()
sys.exit(app.exec_())
# 栅格布局 表单设计
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import os
class QGridLayoutDemo(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('栅格布局表单')
self.resize(300,200)
label1 = QLabel('标题')
label2 = QLabel('作者')
label3 = QLabel('内容')
edit1 = QLineEdit()
edit2 = QLineEdit()
edit3 = QTextEdit()
grid = QGridLayout()
grid.setSpacing(10)
grid.addWidget(label1,1,0)
grid.addWidget(edit1,1,1)
grid.addWidget(label2, 2, 0)
grid.addWidget(edit2, 2, 1)
grid.addWidget(label3, 3, 0)
grid.addWidget(edit3, 3, 1,5,1)
self.setLayout(grid)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QGridLayoutDemo()
main.show()
sys.exit(app.exec_())
# 表单布局
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import os
class QFormLayoutDemo(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('栅格布局表单')
self.resize(300,200)
label1 = QLabel('标题')
label2 = QLabel('作者')
label3 = QLabel('内容')
edit1 = QLineEdit()
edit2 = QLineEdit()
edit3 = QTextEdit()
formLayout = QFormLayout()
formLayout.setSpacing(10)
formLayout.addRow(label1,edit1) #添加的是行
formLayout.addRow(label2,edit2)
formLayout.addRow(label3,edit3)
self.setLayout(formLayout)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QFormLayoutDemo()
main.show()
sys.exit(app.exec_())
# 拖动改变控件边界 QSplitter
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
import os
class Splitter(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('QSplitter')
self.resize(300,200)
layout = QHBoxLayout()
topleft = QFrame()
topleft.setFrameShape(QFrame.StyledPanel)
bottom = QFrame()
bottom.setFrameShape(QFrame.StyledPanel)
splitter1 = QSplitter(Qt.Horizontal) #水平
textEdit = QTextEdit()
splitter1.addWidget(topleft)
splitter1.addWidget(textEdit)
splitter2 = QSplitter(Qt.Vertical) #垂直
splitter2.addWidget(splitter1)
splitter2.addWidget(bottom)
layout.addWidget(splitter2)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Splitter()
main.show()
sys.exit(app.exec_())
#信号和槽 自定义,实现对象之间通讯
import sys
from PyQt5.QtCore import *
class MySignal(QObject):
signal = pyqtSignal(object) #定义信号 后面还要加参数 object
def run(self):#定义触发
self.signal.emit('argument') #触发,还带了一个参数
class MySlot(QObject):
def get(self,argv): #接收信号发来的参数
print('slot:'+argv)
if __name__ == '__main__':
signal1 = MySignal()
slot = MySlot()
signal1.signal.connect(slot.get)
signal1.run()
signal1.signal.disconnect() #断开
signal1.run()
#信号和槽 自定义,实现对象之间通讯,多个参数
import sys
from PyQt5.QtCore import *
class MySignal(QObject):
signal = pyqtSignal(object) #定义信号 后面还要加参数 object
signal1 = pyqtSignal(str,int,int)#定义带三个参数的信号 ,要一致
def run(self):#定义触发
self.signal.emit('argument') #触发,还带了一个参数
def run1(self):#定义触发
self.signal1.emit('argument',4,5) #触发,带三个参数
class MySlot(QObject):
def get(self,argv): #接收信号发来的参数
print('slot:'+argv)
def get1(self,argv,a,b): #接收信号发来的参数
print('slot:'+argv)
print(a+b)
if __name__ == '__main__':
signal2 = MySignal()
slot = MySlot()
signal2.signal1.connect(slot.get1)
signal2.run1()
#为类添加多个信号
from PyQt5.QtCore import *
class MultiSignal(QObject):
signal1 = pyqtSignal() #首先创建带参数信号
signal2 = pyqtSignal(int)
signal3 = pyqtSignal(int,str)
signal4 = pyqtSignal(list)
signal5 = pyqtSignal(dict)
signal6 = pyqtSignal([int,str],[str]) #重载版本的信号,也就是槽函数的参数可以是int或str 也可以只有一个str
def __init__(self):
super().__init__()
self.signal1.connect(self.signal_call1) #绑定
self.signal2.connect(self.signal_call2)
self.signal3.connect(self.signal_call3)
self.signal4.connect(self.signal_call4)
self.signal5.connect(self.signal_call5)
self.signal6[str].connect(self.signal_call61) #绑定时候要指定哪个类型的参数,这里只绑了1个str参数的信号类型
self.signal6[int,str].connect(self.signal_call62)
self.signal1.emit() #信号触发,传实参
self.signal2.emit(5)
self.signal3.emit(5,'hello')
self.signal4.emit([1,2,'111'])
self.signal5.emit({'name':'tom','age':30})
self.signal6[str].emit('haha') #这里触发 同样要指定
self.signal6[int,str].emit(1,'haha')
def signal_call1(self):print('signal1 emit:') #定义响应的槽函数
def signal_call2(self,argv1):print('signal2 emit:',argv1)
def signal_call3(self,argv1,argv2):print('signal3 emit:',argv1,argv2)
def signal_call4(self,argv1):print('signal4 emit:',argv1)
def signal_call5(self,argv1):print('signal5 emit:',argv1)
def signal_call61(self,argv1):print('signal6 emit:',argv1)
def signal_call62(self,argv1,argv2):print('signal6 emit:',argv1,argv2)
if __name__ == '__main__':
multisignal = MultiSignal()