您的位置:首页 > 编程语言 > Qt开发

PyQt5的学习笔记

2018-03-08 20:01 281 查看

学习PyQt

因为喜欢

内容参考自 ARCHi的博客

一.面向对象的创建GUI

1.根据如下格式即可创建图形化界面

class Example(QWidget):
# 上述可以继承自QWidget 与 QMainWindow,分别表示其是控件或者是主窗口
def __init__(self):
super().__init__()
self.initUI()

def initUI(self):
self.setGeometry(300, 300, 300, 200)
self.setWindowTitle('Sample')
self.setWindowIcon(QIcon('icon.jpg'))   #设置Icon
self.show()

if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())   # 进入主循环


2.添加按钮以及连接槽与信号

btn = QPushButton('Quit', self)
btn.clicked.connect(QCoreApplication.instance().quit)
# clicked信号发出后由 QCoreApplication的一个实例接受,退出
# 经测试这里面可以使用 qApp.quit() 替换 QCoreApplication.instance().quit
# 上述现象的原因:QApplication对象是可以通过全局变量qApp访问
btn.resize(btn.sizeHint())  #sizeHint()用于获取一个合适的大小
btn.move(0,0)


3.移动窗口使其居中

def __init__:
...
self.center()   #调用center以居中
...

def center(self):
# 居中
qr = self.frameGeometry()  # 获得与主窗口的特定矩形,含框架
cp = QDesktopWidget().availableGeometry().center()  # 计算屏幕中心位置
qr.moveCenter(cp)  # 获得的矩形的中心移动到屏幕中心位置
self.move(qr.topLeft())  # 将应用窗口的左上方移动到qr矩形的左上方


4.重载closeEvent() 以实现复杂退出动作

def closeEvent(self, event):
reply = QMessageBox.question(self, 'Message', "Are you sure to quit?",
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
event.accept()
else:
event.ignore()




二、菜单与工具箱

1.菜单按钮

# 定义一个用来实现退出的动作
exitAction = QAction('&Exit', self) #定义了一个抽象动作,可以在第一个参数里面添加上QIcon
exitAction.setShortcut('Ctrl+Q')    #定义快捷键
exitAction.setStatusTip('Exit application') #定义StatusBar上面显示的信息
exitAction.triggered.connect(qApp.quit) #其槽与 qApp.quit 相连接

self.statusBar()    #添加statusBar以显示状态

# 创建菜单栏并添加菜单
menuBar = self.menuBar()    #创建了菜单栏
fileMenu.addAction(exitAction)  #将退出动作添加为新菜单的 Action


2.工具箱

#或者可以加入到工具栏中去
self.toolbar = self.addToolBar('Exit')
self.toolbar.addAction(exitAction)

c0df
#测试此处不使用self. 而只使用toolBar没有问题,虽然原因不清楚,但是感觉这样似乎是合理一点。




三.布局

1.绝对定位布局

感觉用处不大…略

2.箱式布局

okButton = QPushButton('OK')
okButton.clicked.connect(qApp.quit)
canelButton = QPushButton('Cance')

# '''
# 这里建立了一个基于hbox与vbox的箱布局
hbox = QHBoxLayout()
vbox = QVBoxLayout()

hbox.addStretch(1)  #增加了一个拉伸因子使得按钮被推到了窗口的右边
hbox.addWidget(okButton)
hbox.addWidget(canelButton)

vbox.addStretch(1) #增加一个拉伸因子,使得按钮被推到了窗口的下面
vbox.addLayout(hbox)

self.setLayout(vbox)




3.网式布局

grid = QGridLayout()
self.setLayout(grid)
names = ['Cls', 'Bck', '', 'Close',
'7', '8', '9', '/',
'4', '5', '6', '*',
'1', '2', '3', '-',
'0', '.', '=', '+']
positons = [(i, j) for i in range(5) for j in range(4)]
for positon, name in zip(positons, names):
if (name == ''):
continue
button = QPushButton(name)
print(positon,"    " ,*positon, type(positon), "   ", type(positon))
grid.addWidget(button, *positon)    #此处关于 * positons 存疑!




4.文本审阅布局

其实就是可以跨行的grid

# 文本审阅布局??
title = QLabel('Title')
author = QLabel('Author')
review = QLabel('Review')

titleEdit = QLineEdit()
authorEdit = QLineEdit()
reviewEdit = QTextEdit()

grid = QGridLayout()
grid.setSpacing(10) # 设置组件之间的间距

grid.addWidget(title, 1, 0)
grid.addWidget(titleEdit, 1, 1)

grid.addWidget(author, 2, 0)
grid.addWidget(authorEdit, 2, 1)

grid.addWidget(review, 3, 0, 5, 1)
grid.addWidget(reviewEdit, 3, 1, 5, 1)  #跨了5行




四事件与信号

1.简单的例子

# 信号与槽
lcd = QLCDNumber(self)  # 显示lcd数字(类似于计算器上面的数字)
sld = QSlider(Qt.Horizontal, self)  # sliderbar 滑动条

vbox = QVBoxLayout()
vbox.addWidget(lcd)
vbox.addWidget(sld)
self.setLayout(vbox)

# 连接滑动块的valueChanged 信号与 lcd的display槽
sld.valueChanged.connect(lcd.display)




2.通过 sender 获取信号发送者的信息

self.label = QLabel('Hello')
btn1 = QPushButton('Button 1')
btn2 = QPushButton('Button 2')
btn1.clicked.connect(self.buttonClicked)
btn2.clicked.connect(self.buttonClicked)
hbox = QHBoxLayout()
hbox.addWidget(self.label)
hbox.addStretch()
hbox.addWidget(btn1)
hbox.addWidget(btn2)
vbox.addLayout(hbox)
# vbox.addWidget(label)

def buttonClicked(self):
sender = self.sender()  # sender立马存有信号发送者的信息
self.label.setText(sender.text()+"  was pressed")




3.可以自己建立一个类用来发送信号,具体见代码

...
self.c = Communicate()
self.c.closeApp.connect(self.close)
...

class Communicate(QObject):
closeApp = pyqtSignal()

def mousePressEvent(self, event):
self.c.closeApp.emit()


四、对话框

1.简单的对话框:

self.le = QLineEdit(self)
vbox.addWidget(self.le)

def showDialog(self):
text, ok = QInputDialog.getText(self, 'Input Dialog', 'Enter your name')
# if ok:
self.le.setText(text)   # 上面的 if 被注释了是因为发现其存在与否没有意义
# !!!并不是这样,我发现如果我没有判断是不是点了 ok 的话,当我选择Cancel的时候就会
#把之前lineEdit里面的内容删掉(不管我有没有在dialog里面输入)






五、简单插件

1.进度条

使用QProgressBar来显示进度条

# 添加ProgressBar 与 timer
# ProgressBar
self.pbar = QProgressBar()
vbox.addWidget(self.pbar)

# Timer
self.timer = QBasicTimer()
self.step = 0
self.btn1.clicked.connect(self.doAction)

def timerEvent(self, QTimerEvent):
# 重写timerEvent 函数以根据set调整ProgressBar
if self.step >= 100:
self.timer.stop()
self.btn1.setText('Finished')
return
self.step += 1
self.pbar.setValue(self.step)

def doAction(self):
# 这是按钮被点击之后触发的函数
if self.timer.isActive():   # 按钮被点击时timer是否处于激活态
self.timer.stop()   #显然是要暂停
self.btn1.setText('Start')

else:
self.timer.start(100, self) # 非激活态被点击自然是希望开始计时啦
self.btn1.setText('Stop')
# 下面的操作使得当前进度结束后可以重新开始,在实际中用不上,但是学习时可以方便观察其哟行机制
if self.step >= 100:
self.step = 0
self.btn1.setText('Start')
self.timer.stop()
self.pbar.setValue(0)








头文件

#! /usr/bin/python3
# coding = utf-8
# from PyQt5 import QtGui,QtCore,Qt
import sys
from PyQt5.QtCore import Qt,pyqtSignal,QSize,QRect,QMetaObject, QCoreApplication, pyqtSlot,QPropertyAnimation,QThread
from PyQt5.QtGui import QIcon, QFont, QPixmap, QPainter, QImage
from PyQt5.QtWidgets import QMainWindow, QApplication

import cv2
from PyQt5. import SIGNAL, time
from PyQt5 import QtCore
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: