基本框架
# PyQt5引入的组件其实只需要QtWidgets、QApplication就可以实现最基本的窗体显示
# 还需要引入sys作为窗体应用进程的控制
from PyQt5.QtWidgets import QApplication,QWidget,QHBoxLayout,QLineEdit,QPushButton
import sys
class TemplateForm(QWidget):
def __init__(self):
super().__init__()
hlayout=QHBoxLayout()
self.setLayout(hlayout)
lineEdit=QLineEdit()
lineEdit.setText('Hello,world!')
button=QPushButton()
button.setText('Please press me!')
button.clicked.connect(self.close)
hlayout.addWidget(lineEdit,1)
hlayout.addWidget(button,2)
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
app=QApplication(sys.argv)
form=TemplateForm()
form.show()
app.exit(app.exec_())
基本组件使用
- QMainWindow
- QWidget
from PyQt5.QtCore import Qt
# 设置窗口背景透明
mywin.setAttribute(Qt.WA_TranslucentBackground)
# 隐藏窗口边框
mywin.setWindowFlags(Qt.FramelessWindowHint)
# 设置窗口边框带阴影
from PyQt5.QtWidgets import QGraphicsDropShadowEffect
effect=QGraphicsDropShadowEffect(self)
effect.setBlurRadius(12) # 设置阴影画笔强度
effect.setOffset(0,0)
effect.setColor(Qt.gray)
mywin.setGraphicsEffect(effect)
在隐藏窗体边框后鼠标不能拖动窗体,需要重写鼠标事件,首先为窗体设置一个变量m_Drag判断鼠标左键是否按下。
# 在窗体类里定义m_Drag
def __init__(self):
super().__init__()
self.m_Drag=False
# 重写鼠标事件
"""重写隐藏边框后的鼠标事件,因为隐藏边框后不能移动窗体"""
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.m_Drag = True
# event.globalPos()是鼠标当前点击位置相对于电脑桌面左上角的坐标
# self.pos()是当前窗体相对于电脑桌面左上角的坐标
self.m_DragPosition = event.globalPos() - self.pos()
# 将拖动时鼠标的光标形状变成小手
self.setCursor(QCursor(Qt.OpenHandCursor))
def mouseMoveEvent(self, event):
# 只有单击鼠标左键才能移动
if Qt.LeftButton and self.m_Drag:
# move(QPoint()),是将窗体移动到某一点
self.move(event.globalPos() - self.m_DragPosition)
def mouseReleaseEvent(self, event):
self.m_Drag = False
self.setCursor(QCursor(Qt.ArrowCursor))
- QPushButton
按键用得最多的就是“单击事件”:
def myfunc():
pass
button=QPushButton()
button.clicked.connect(myfunc)
# 如果自定义函数是带参数的,使用lambda表达式
button.clicked.connect(lambda : myfunc(parm1,parm2...))
然后就是对QPushButton的QSS装饰(QSS代码):
/*QPushButton的正常样式*/
QPushButton{
width:100px;
height:25px;
background-color:#FFFFFF;
/*设置圆角*/
border:1px solid #00CCCC;
border-radius:5px;
color:#000000;
}
# 当鼠标悬浮在QPushButton时的样式
QPushButton:hover{
background-color:#00CCFF;
color:#888888;
}
# 单击QPushButton时的样式
QPushButton:pressed{
background-color:red;
color:black;
}
第二就是如何使用QPushButton控件做一个圆形的logo,主要还是qss的修饰:
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton,QHBoxLayout,QGraphicsDropShadowEffect
from PyQt5.Qt import Qt # 使用Qt里的颜色
import sys
qssStyleSheet='''
QPushButton {
/*限制最小最大尺寸*/
min-width: 96px;
max-width: 96px;
min-height: 96px;
max-height: 96px;
border-radius: 48px; /*圆形*/
border:none;
background:white;
/* 设置按钮的背景图片 */
border-image:url(./backgroundimg2.png);
}
'''
class MyLogoButtonForm(QWidget):
def __init__(self):
super(MyLogoButtonForm, self).__init__()
self.myButton=QPushButton()
hlayout=QHBoxLayout()
hlayout.addWidget(self.myButton)
self.setLayout(hlayout)
# 为按钮周边设置阴影
logoShadow=QGraphicsDropShadowEffect(self) # 这里的self是当前按钮的父控件,不一定是self
logoShadow.setBlurRadius(8)
logoShadow.setOffset(0,0)
logoShadow.setColor(Qt.gray)
self.myButton.setGraphicsEffect(logoShadow)
self.setStyleSheet(qssStyleSheet)
if __name__ == '__main__':
app=QApplication(sys.argv)
myform=MyLogoButtonForm()
myform.show()
sys.exit(app.exec_())
第三是将按键设置成那种带小图标的样式:
# 在上述例子中引入QIcon和QPixmap
from PyQt5.QtGui import QIcon,QPixmap # 设置一个图标样式的按钮
# 为按钮准备一个小图标
icon=QIcon()
# 用QPixmap为按键添加图标图片
icon.addPixmap(QPixmap('./searchIcon48.png'),QIcon.Normal,QIcon.Off)
self.myBtn2=QPushButton()
self.myBtn2.setObjectName('searchpushButton')
self.myBtn2.setIcon(icon)
# 还要将按钮文本设为空字符串
self.myBtn2.setText('')
然后按照惯例修饰一下按钮(QSS代码)
QPushButton#searchpushButton{
width:60px;
height:25px;
background-color:#FFFFFF;
border:1px solid #00CCCC;
border-radius:5px;
color:#000000;
}
QPushButton#searchpushButton:hover{
background-color:#00CCFF;
color:#888888;
}
- QLineEdit
单行文本输入框我只使用了其获取文本的功能/设置提示文本功能/设置掩码(密码输入)功能,至于还有什么骚操作有待探索。
# 单行文本框获取文本的方法
myLineEdit=QlineEdit()
textstr=myLineEdit.text()
# 设置文本框为掩码模式,输入密码是是黑点
textstr.setEchoMode(QLineEdit.Password)
# 设置提示文本
textstr.setPlaceholderText("你想要的提示文本")
- QProgressBar—进度条
进度条的使用是动态的,进度值是在后台不断变化的,这就需要我们在使用时进度条时引入线程,不然界面在进度条动态变化时可能会“假死”。
首先,来看如何创建进度条:
# 首先来看如何创建进度条,先引入需要的组件
from PyQt5.QtWidgets import QApplication,QWidget,QProgressBar,QHBoxLayout
import sys
class ProgressBarForm(QWidget):
def __init__(self):
super(ProgressBarForm, self).__init__()
self.myprogressbar=QProgressBar()
hlayout=QHBoxLayout()
hlayout.addWidget(self.myprogressbar)
self.setLayout(hlayout)
if __name__ =='__main__':
app=QApplication(sys.argv)
myform=ProgressBarForm()
myform.show()
myform.setProgressBarValue()
sys.exit(app.exec_())
这样的进度条是不会动的,要使进度条的进度值显示动态变化,引入线程:
为了实现目的,我们需要增加三样东西:
1.线程ProgressBarThread,其中使用了Qt的signal-slot机制,在线程中改变进度条的值,再用信号signal绑定回调函数slot,使用信号将进度条的进度值传递给回调函数(通知)。
2.回调函数setProgressBarValue_CallBack,接收信号传递来的进度值,然后更新进度条显示的进度值。
3.控制函数setProgressBarValue,创建线程对象、将线程中的信号signal和回调函数slot绑定起来、启动线程。
from PyQt5.QtWidgets import QApplication,QWidget,QProgressBar,QHBoxLayout
# 引入线程使得进度条值在后台自动变化
from PyQt5.QtCore import QThread,pyqtSignal
import sys
import time # 用于停止线程
class ProgressBarThread(QThread):
'''
线程,用于控制进度条的进度值
'''
triggerSignal=pyqtSignal(int)
def __init__(self):
super(ProgressBarThread, self).__init__()
def run(self):
num=1
while num<100:
self.triggerSignal.emit(num)
time.sleep(1)
num+=1
class ProgressBarForm(QWidget):
def __init__(self):
super(ProgressBarForm, self).__init__()
self.myProgressBar=QProgressBar()
hlayout=QHBoxLayout()
hlayout.addWidget(self.myProgressBar)
self.setLayout(hlayout)
def setProgressBarValue(self):
self.myThread=ProgressBarThread()
self.myThread.triggerSignal.connect(self.setProgressBarValue_CallBack)
self.myThread.start()
def setProgressBarValue_CallBack(self,ivalue):
self.myProgressBar.setValue(ivalue)
if __name__ =='__main__':
app=QApplication(sys.argv)
myform=ProgressBarForm()
myform.show()
myform.setProgressBarValue()
sys.exit(app.exec_())
第三是来看看进度条如何美化(QSS代码):
qssStyleSheet='''
/* 设置进度条的三种样式 */
#RedProgressBar {
/* 进度值居中 */
text-align:center;
}
#RedProgressBar::chunk {
/* 设置进度条里进度值显示的栅栏格子样式 */
background-color:#F44336;
}
#GreenProgressBar {
min-height: 12px;
max-height: 12px;
border-radius: 6px;
}
#GreenProgressBar::chunk {
/* 设置进度条里进度值显示的栅栏格子样式 */
background-color:#009688;
border-radius: 6px;
}
#BlueProgressBar {
text-align:center;
/* 设置进度条边框及其颜色 */
border: 2px solid #00CCCC;
/* 设置圆角 */
border-radius: 5px;
background-color:#FFFFFF;
}
#BlueProgressBar::chunk {
/* 设置进度条里进度值显示的栅栏格子样式 */
background-color:#00CCCC;
width: 5px;
margin: 0.5px;
}
'''
- QThread—Qt线程
在进度条使用例子里,就是我第一次接触QThread,主要思路就是创建一个自己的类继承QThread,然后自定义线程类的run函数即可。
from PyQt5.QtCore import QThread
class MyThread(QThread):
def __init__(self):
super(MyThread,self).__init__()
def run(self):
# 自定义的功能函数
- QTableWidget—QT表格控件
QTableWidget主要包括:
水平表头、垂直表头
表格行、列
单元格
如何使用表格,主要包括:
先看modifierTableWidget里如何设置表格
再看如何往表格里添加内容,包括添加文本、添加控件
然后是如何删除表格的内容、如何清空表格内容
最后是如何美化表格(qss)
from PyQt5.QtWidgets import QApplication,QWidget,QHBoxLayout,QPushButton,\
QTableWidget,QAbstractItemView,QHeaderView,QTableWidgetItem
from PyQt5.Qt import Qt
import sys
class MyTableWidget(QWidget):
def __init__(self):
super(MyTableWidget, self).__init__()
hlayout=QHBoxLayout()
self.tableWidget=QTableWidget()
# 设置表格属性
self.modifierTableWidget()
# 为表格添加点内容
btnStr='Hello,world!'
btn=QPushButton(btnStr)
btn1=QPushButton(btnStr)
# 在表格添加文本
textItem=QTableWidgetItem('I am super man!')
# self.tableWidget.insertRow(0) # 增加第一行
self.tableWidget.setItem(0,0,textItem)
# 在表格添加控件
# self.tableWidget.insertRow(1) # 增加第一行
self.tableWidget.setCellWidget(1,0,btn) # 在第一行、第一列放置按钮
# self.tableWidget.insertRow(2) # 增加第二行
self.tableWidget.setCellWidget(2,1,btn1) # 在第二行、第一列放置按钮
# 删除表格内容
# self.tableWidget.removeCellWidget(1,0) # 删除表格中第二行第一列的内容
# self.tableWidget.removeColumn(1) # 删除表格的某一列
# self.tableWidget.removeRow(1) # 删除表格的某一行
# self.tableWidget.takeItem(1,0) # 这个也是删除某行某列的内容,但好像不起作用
# 获取单击按钮所在的表格行位置
rowIndex=self.tableWidget.indexAt(btn.pos()).row() # 这里好像返回的都是0,没搞清楚
print(rowIndex)
# 清空表格内容
# self.tableWidget.clear()
# self.tableWidget.clearContents()
# self.tableWidget.setRowCount(0)
hlayout.addWidget(self.tableWidget)
self.setLayout(hlayout)
self.setStyleSheet(qssStyleSheet)
def modifierTableWidget(self):
self.tableWidget.setRowCount(5) # 设置行数,设置了行数就不需要用insertRow
self.tableWidget.setColumnCount(2) # 设置表格列数
self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) # 禁止编辑
self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows) # 整行选中
self.tableWidget.horizontalHeader().setVisible(False) # 设置水平表头不可见
self.tableWidget.verticalHeader().setVisible(True) # 设置垂直表头可见
# self.tableWidget.verticalHeader().setSectionResizeMode(QHeaderView.Stretch) # 设置行高根据内容伸缩
self.tableWidget.verticalHeader().setSectionResizeMode(QHeaderView.Fixed) # 设置行高固定
self.tableWidget.verticalHeader().setDefaultSectionSize(
int(self.tableWidget.height() / 7)
) # 设置每一行的默认高度
self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 设置列根据内容伸缩
# self.mywidget.tableWidget.setFrameStyle(QFrame.NoFrame) # 去掉边框
self.tableWidget.setShowGrid(False) # 去掉单元格虚线
self.tableWidget.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) # 设置滚动条
self.tableWidget.setVerticalHeaderLabels(['header1','header2']) # 设置垂直表头内容
if __name__ == '__main__':
app=QApplication(sys.argv)
myform=MyTableWidget()
myform.show()
sys.exit(app.exec_())
- QDateEdit/QDateTimeEdit
from PyQt5.QtWidgets import QApplication,QWidget,QHBoxLayout,QDateEdit,QDateTimeEdit
from PyQt5.QtCore import QDate,QTime,QDateTime
import sys
class MyDateEditForm(QWidget):
def __init__(self):
super(MyDateEditForm, self).__init__()
hlayout=QHBoxLayout()
self.dateEdit=QDateEdit()
self.dateTimeEdit=QDateTimeEdit()
# 设置日期控件为日历
self.dateEdit.setCalendarPopup(True)
# 设置日期控件显示为当前时间
self.dateEdit.setDate(QDate.currentDate())
# 设置时间控件显示的时间格式为“yy-mm-dd"
self.dateEdit.setDisplayFormat("yyyy-MM-dd")
# 设置日期控件为日历
self.dateTimeEdit.setCalendarPopup(True)
# 设置日期控件显示为当前时间
self.dateTimeEdit.setDate(QDate.currentDate())
self.dateTimeEdit.setTime(QTime.currentTime())
self.dateTimeEdit.setDateTime(QDateTime.currentDateTime())
# 设置时间控件显示的时间格式为“yy-mm-dd"
self.dateTimeEdit.setDisplayFormat("yyyy-MM-dd hh:mm:ss")
# 获取控件时间的方法
time1=self.dateEdit.date()
print(time1)
time2=self.dateTimeEdit.time().hour()
print(time2)
hlayout.addWidget(self.dateEdit)
hlayout.addWidget(self.dateTimeEdit)
self.setLayout(hlayout)
if __name__ =='__main__':
app=QApplication(sys.argv)
myform=MyDateEditForm()
myform.show()
sys.exit(app.exec_())
结语
好了,懒懒的自己将毕设的东西慢慢整理出来,走出校园,走进职场,只能慢慢努力了,做一个热爱编程的人。
—偷得浮生半日闲,又摘桃花换酒钱!