pyQt5模块分布
控件
1、QCheckBox复选框控件
checkbox = QCheckBox('Show title', self)
checkbox.move(20, 20)
checkbox.toggle() //默认√
checkbox.stateChanged.connect(self.changeTitle)
2、Togglebutton 开关按钮
//一种特殊的Qbutton
redb = QPushButton('Red', self)
redb.setCheckable(True)
redb.move(10, 10)
redb.clicked[bool].connect(self.setColor)
3、滑动条 QSlider
sld = QSlider(Qt.Horizontal, self)
sld.setFocusPolicy(Qt.NoFocus) //默认不获取焦点
sld.setGeometry(30, 40, 100, 30)
sld.valueChanged[int].connect(self.changeValue)
4、进度条QProgressBar
pbar = QProgressBar(self)
pbar.setGeometry(30, 40, 200, 25)
5、处理图片控件QPixmap
hbox = QHBoxLayout(self)
pixmap = QPixmap("icon.png")
lbl = QLabel(self)
lbl.setPixmap(pixmap)
hbox.addWidget(lbl)
self.setLayout(hbox)
6、文本框 QLineEdit
def initUI(self):
self.lbl = QLabel(self)
qle = QLineEdit(self)
qle.move(60, 100)
self.lbl.move(60, 40)
qle.textChanged[str].connect(self.onChanged)
self.setGeometry(300, 300, 280, 170)
self.setWindowTitle('QLineEdit')
self.show()
def onChanged(self, text):
self.lbl.setText(text)
self.lbl.adjustSize()
7、拖动子控件边界QSplitter
topleft = QFrame(self)
topleft.setFrameShape(QFrame.StyledPanel)
splitter1 = QSplitter(Qt.Horizontal)
splitter1.addWidget(topleft)
8、下拉列表 QComboBox
combo = QComboBox(self)
combo.addItem("Ubuntu")
combo.addItem("Mandriva")
combo.addItem("Fedora")
combo.addItem("Arch")
combo.addItem("Gentoo")
combo.activated[str].connect(self.onActivated)
9、列表控件QListWidget
import sys
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QListWidget, QListWidgetItem, QHBoxLayout
class Demo(QWidget):
def __init__(self):
super(Demo, self).__init__()
self.pic_label = QLabel(self)
self.pic_label.setPixmap(QPixmap('arrow.png'))
self.listwidget_1 = QListWidget(self) #实例化列表控件
self.listwidget_2 = QListWidget(self)
self.listwidget_1.doubleClicked.connect(lambda: self.change_func(self.listwidget_1))
#双击列表控件时发出信号
self.listwidget_2.doubleClicked.connect(lambda: self.change_func(self.listwidget_2))
for i in range(6):
text = 'Item {}'.format(i)
self.item = QListWidgetItem(text) #把字符串转化为QListWidgetItem项目对象
self.listwidget_1.addItem(self.item) #添加项目
self.item_6 = QListWidgetItem('Item 6', self.listwidget_1) # 实例化后直接添加
self.listwidget_1.addItem('Item 7') #直接添加项目,不用QListWidgetItem对象,【功能可能不全】
str_list = ['Item 9', 'Item 10']
self.listwidget_1.addItems(str_list) #添加项目-列表
self.item_8 = QListWidgetItem('Item 8')
self.listwidget_1.insertItem(8, self.item_8) #插入项目。参数1:索引号,参数2:项目
# self.listwidget_1.insertItem(8, 'Item 8')
self.h_layout = QHBoxLayout()
self.h_layout.addWidget(self.listwidget_1)
self.h_layout.addWidget(self.pic_label)
self.h_layout.addWidget(self.listwidget_2)
self.setLayout(self.h_layout)
self.listwidget_1.itemClicked.connect(self.d) #单击列表控件时发出信号
self.listwidget_1.currentItemChanged.connect(self.g) #当前项目发生变化时发出信号
self.listwidget_1.addItem('Item_11')
def g(self):
print('项目总数发生了改变')
def d(self):
print('你单击了列表控件')
def change_func(self, listwidget):
if listwidget == self.listwidget_1:
item = QListWidgetItem(self.listwidget_1.currentItem()) #转化为QListWidgetItem对象
# self.listwidget_1.currentItem() 返回当前项目。是个对象。<PyQt5.QtWidgets.QListWidgetItem object at 0x0000008425463A68>
self.listwidget_2.addItem(item) #添加项目。参数是QListWidgetItem对象
print(self.listwidget_2.count()) #返回项目总数
else:
self.listwidget_2.takeItem(self.listwidget_2.currentRow())#删除指定索引号的项目
#self.listwidget_2.currentRow() 返回当前项目的行索引号
print(self.listwidget_2.count())
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = Demo()
demo.show()
sys.exit(app.exec_())
10、树形结构
def initUi(self):
self.tree = QTreeWidget(self)
# 设置列数
self.tree.setColumnCount(2)
# 设置头部控件标题
self.tree.setHeaderLabels(["key",'value'])
# 树形控件的列宽度
self.tree.setColumnWidth(0, 160)
# 设置根节点
root = QTreeWidgetItem(self.tree)
root2 = QTreeWidgetItem(self.tree)
root2.setText(0,'root2')
root.setText(0,'root')
# root.setIcon(0,QIcon("./image.png"))
# 设置子节点1
child1 = QTreeWidgetItem(root)
child1.setText(0,'child1')
child1.setText(1, 'ios')
# 设置子节点2
child2 = QTreeWidgetItem(root)
child2.setText(0, 'child2')
child2.setText(1, 'android')
# 设置子节点3
child2 = QTreeWidgetItem(root2)
child2.setText(0, 'child3')
child2.setText(1, 'windows')
self.tree.addTopLevelItem(root)
# 节点展开
self.tree.expandAll()
使用.addTopLevelItem(root)
实现树形结构
def initUi(self):
self.tree = QTreeWidget(self)
# 设置列数
self.tree.setColumnCount(2)
# 设置头部控件标题
self.tree.setHeaderLabels(["key",'value'])
# 树形控件的列宽度
self.tree.setColumnWidth(0, 160)
# 设置根节点
root = QTreeWidgetItem(self.tree)
root.setText(0,'root')
root2 = QTreeWidgetItem(self.tree)
root2.setText(0, 'root')
# root.setIcon(0,QIcon("./image.png"))
# 设置子节点1
child1 = QTreeWidgetItem()
child1.setText(0,'child1')
child1.setText(1, 'ios')
# 设置子节点2
child2 = QTreeWidgetItem()
child2.setText(0, 'child2')
child2.setText(1, 'android')
rootlist = []
rootlist.append(root)
rootlist.append(root2)
root.addChild(child1)
root.addChild(child2)
self.tree.insertTopLevelItems(0,rootlist)
# 节点展开
self.tree.expandAll()
11、页面结构
self.tabWiget = QTabWidget(self) # 创建一个QTabWidget对象,指定父窗口为self
self.tabWiget.setTabsClosable(True)
self.tabWiget.tabCloseRequested.connect(self.closeTab) # 重写关闭页面的函数
tabArea = QMdiArea() # 添加页面窗口
sub = QMdiSubWindow() # 创建子页面
sub.setWindowIcon(QIcon("icon.png"))
sub.setWindowFlags(Qt.Tool) # 设置窗口样式
sub.setWidget(imageWidget) # 子页面添加窗口组件
tabArea.addSubWindow(sub) # 将子页面添加到子窗口组件中,可以添加多个
self.tabWiget.addTab(tabArea, "页面标题")
self.tabWiget.setCurrentWidget(tabArea) # 设置为当前页面
# 关闭页面函数
def closeTab(self,index):
MainWindow.tabCount -= 1
self.tabWiget.removeTab(index)
应用实例
1、实现图像拖动、放大的例子
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import QPixmap, QFont,QImage,QPalette
import cv2
class Main(QWidget):
def __init__(self):
super().__init__()
self.widget = ImageWithMouseControl(string="icon2.jpg",parent=self)
self.widget.setImage("icon2.jpg")
self.widget.setGeometry(0, 0, 800, 800)
class ImageWithMouseControl(QWidget):
def __init__(self,string, parent=None):
super().__init__(parent)
# 常数
self.resize_point = 10
self.angleY = None # 滚轮转的角度
self.mouse_mv_x = 0 # 记录中途的x坐标
self.mouse_mv_y = 0 # 记录中途的y坐标
self.label_x = 0 # 记录最后的x坐标
self.label_y = 0 # 记录最后的y坐标
self.left_flag = False
self.right_flag = False
self.x1 = 0
self.y1 = 0
self.width = 0 # 一开始所在的位置
self.height = 0 # 一开始所在的位置
self.label_w = 0
self.label_h = 0
self.parent = parent
self.initUI(string)
self.init_background()
def initUI(self,string):
layout = QStackedLayout(self)
path = string
parentwidth = 800 # 父窗口宽
parentheight = 800 # 父窗口高
self.origin_img = cv2.imread(path) # 原始图片大小
origin_img_width = self.origin_img.shape[1]
origin_img_height = self.origin_img.shape[0]
if origin_img_width>origin_img_height:
self.origin_img = cv2.resize(self.origin_img,(int(parentwidth),int(origin_img_height*(parentwidth/origin_img_width))))
else:
self.origin_img = cv2.resize(self.origin_img, (int(origin_img_width*(parentheight/origin_img_height)), int(parentheight)))
self.label_w = self.origin_img.shape[1]
self.label_h = self.origin_img.shape[0]
shrink = cv2.cvtColor(self.origin_img, cv2.COLOR_BGR2RGB)
self.QtImg = QImage(shrink.data,
shrink.shape[1],
shrink.shape[0],
shrink.shape[1] * 3,
QImage.Format_RGB888)
self.label = QLabel(self)
self.label.setPixmap(QPixmap.fromImage(self.QtImg))
layout.addWidget(self.label)
self.setGeometry(QRect(0,0,self.label_w,self.label_h))
self.label.setGeometry(QRect(0,0,self.label_w,self.label_h))
self.label.setAlignment(Qt.AlignTop)
self.setLayout(layout)
def setImage(self,string):
path = string
parentwidth = 800 # 父窗口宽
parentheight = 800 # 父窗口高
self.origin_img = cv2.imread(path) # 原始图片大小
origin_img_width = self.origin_img.shape[1]
origin_img_height = self.origin_img.shape[0]
if origin_img_width > origin_img_height:
self.origin_img = cv2.resize(self.origin_img,
(int(parentwidth), int(origin_img_height * (parentwidth / origin_img_width))))
else:
self.origin_img = cv2.resize(self.origin_img, (
int(origin_img_width * (parentheight / origin_img_height)), int(parentheight)))
shrink = cv2.cvtColor(self.origin_img, cv2.COLOR_BGR2RGB)
self.QtImg = QImage(shrink.data,
shrink.shape[1],
shrink.shape[0],
shrink.shape[1] * 3,
QImage.Format_RGB888)
self.label.setPixmap(QPixmap.fromImage(self.QtImg))
def init_background(self):
self.setPalette(QPalette(Qt.gray)) # 这一句是辅助!着色,区分背景。这一句与self.setStyleSheet("background-color:red;")咋看一样,影响不一样
self.setAutoFillBackground(True) # 这一句是关键!!!自动填充背景
def mousePressEvent(self, event):
if event.buttons() == Qt.LeftButton:
self.left_flag = True
self.mouse_mv_x = event.x()
self.mouse_mv_y = event.y()
if event.buttons() == Qt.RightButton:
self.label_x = 0
self.label_y = 0
self.resize_point = 10
self.label.setPixmap(QPixmap.fromImage(self.QtImg))
self.label.setAlignment(Qt.AlignTop)
self.label.setGeometry(0, 0, self.label_w, self.label_h)
# 鼠标释放事件
def mouseReleaseEvent(self, event):
self.left_flag = False
self.right_flag = False
def mouseMoveEvent(self, event): # 重写移动事件
if self.left_flag:
self.x1 = event.x()
self.y1 = event.y()
if self.mouse_mv_x != 0 and self.mouse_mv_y != 0:
self.label_x = self.label_x + (self.x1 - self.mouse_mv_x)
self.label_y = self.label_y + (self.y1 - self.mouse_mv_y)
self.mouse_mv_x = self.x1
self.mouse_mv_y = self.y1
self.label.setGeometry(self.label_x, self.label_y, self.label_w, self.label_h)
def wheelEvent(self, event):
angle = event.angleDelta() / 8
self.angleY = angle.y()
if self.angleY>0:
# 设置上限
if 9 < self.resize_point < 40:
self.resize_point+=1
else:
if 10 < self.resize_point < 41:
self.resize_point -= 1
# 改变图像尺寸
self.cur_resimg = cv2.resize(self.origin_img, (
int(self.origin_img.shape[1] * self.resize_point / 10), int(self.origin_img.shape[0] * self.resize_point / 10)))
img2 = cv2.cvtColor(self.cur_resimg, cv2.COLOR_BGR2RGB)
Image = QImage(img2, self.cur_resimg.shape[1], self.cur_resimg.shape[0], 3 * self.cur_resimg.shape[1],
QImage.Format_RGB888)
self.label_w = self.cur_resimg.shape[1]
self.label_h = self.cur_resimg.shape[0]
print("label.setGeometry",self.label.geometry())
self.label.setPixmap(QPixmap(Image))
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Main()
ex.show()
app.exec_()
2、使用Qt desinger工具生成界面
生成的界面代码文件:
# demo.py --自动生成
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QWidget, QApplication
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(686, 618)
self.label = QtWidgets.QLabel(Form)
self.label.setGeometry(QtCore.QRect(130, 90, 72, 15))
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(Form)
self.label_2.setGeometry(QtCore.QRect(380, 90, 72, 15))
self.label_2.setObjectName("label_2")
self.pushButton = QtWidgets.QPushButton(Form)
self.pushButton.setGeometry(QtCore.QRect(260, 140, 93, 28))
self.pushButton.setObjectName("pushButton")
self.formLayoutWidget = QtWidgets.QWidget(Form)
self.formLayoutWidget.setGeometry(QtCore.QRect(110, 220, 381, 311))
self.formLayoutWidget.setObjectName("formLayoutWidget")
self.formLayout = QtWidgets.QFormLayout(self.formLayoutWidget)
self.formLayout.setContentsMargins(0, 0, 0, 0)
self.formLayout.setObjectName("formLayout")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.label.setText(_translate("Form", "提示1"))
self.label_2.setText(_translate("Form", "提示2"))
self.pushButton.setText(_translate("Form", "确认"))
创建调用UI的的主窗口:
class CallUI(QWidget,Ui_Form):
def __init__(self,parent=None):
super(CallUI, self).__init__(parent)
self.setupUi(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = CallUI()
win.show()
sys.exit(app.exec_())
3、主窗口控件之间的信息传递
控件之间通过主窗口类的方式进行信息传递:
import sys
from PyQt5.QtWidgets import QWidget, QLCDNumber, QSlider, QVBoxLayout, QApplication,QLabel,QLineEdit
from PyQt5.QtCore import Qt
class winform(QWidget):
def __init__(self,parent=None):
super(winform,self).__init__(parent)
self.InitUi()
def InitUi(self):
self.setGeometry(400,400,300,250)
lcd = QLCDNumber(self)
slider = QSlider(Qt.Horizontal,self)
slider.setMaximum(180)
slider.setMinimum(0)
self.label = QLabel(self)
self.edit = QLineEdit(self)
slider.valueChanged.connect(lcd.display)
self.edit.textEdited.connect(self.changeValue)
vBox = QVBoxLayout()
vBox.addWidget(lcd)
vBox.addWidget(slider)
vBox.addWidget(self.label)
vBox.addWidget(self.edit)
self.setLayout(vBox)
def changeValue(self):
self.label.setText(self.edit.text())
if __name__ == '__main__':
app = QApplication(sys.argv)
win = winform()
win.show()
sys.exit(app.exec_())
4、不同窗口之间的信息传递
(1)通过调用属性的方式
import sys
from PyQt5.QtWidgets import QWidget, QCalendarWidget, QDateTimeEdit, QVBoxLayout, QHBoxLayout, QDialogButtonBox, \
QDialog, QApplication, QLineEdit, QPushButton, QGridLayout, QLabel
from PyQt5.QtCore import QDateTime,Qt,pyqtSignal
class DateDialog(QDialog):
# 通过调用属性实现各个窗口之间数据的传输
def __init__(self,parent=None):
super(DateDialog,self).__init__(parent)
self.datetime = QDateTimeEdit(self)
self.datetime.setCalendarPopup(True)
self.datetime.setDateTime(QDateTime.currentDateTime())
layout = QVBoxLayout(self)
layout.addWidget(self.datetime)
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel,Qt.Horizontal,self)
buttons.accepted.connect(self.accept)
buttons.rejected.connect(self.reject)
layout.addWidget(buttons)
def dateTime(self):
return self.datetime.dateTime()
@staticmethod
def getDateTime(parent=None):
dialog = DateDialog(parent)
result = dialog.exec_()
date1 = dialog.dateTime()
return date1.date(),date1.time(), result
class Winform(QWidget):
def __init__(self,parent=None):
super(Winform,self).__init__(parent)
self.resize(100,90)
self.lineEdit = QLineEdit(self)
self.button1 = QPushButton("弹窗1",self)
self.button1.clicked.connect(self.Onbutton1Click)
self.button2 = QPushButton("弹窗2",self)
self.button2.clicked.connect(self.Onbutton2Click)
gridLayout = QGridLayout()
gridLayout.addWidget(self.lineEdit)
gridLayout.addWidget(self.button1)
gridLayout.addWidget(self.button2)
self.setLayout(gridLayout)
def Onbutton1Click(self):
dialog = DateDialog(self)
result = dialog.exec_()
date1 = dialog.dateTime()
if result:
self.lineEdit.setText(date1.date().toString() )
print("\n日期框的返回值")
print("date = %s" % str(date1.date() ))
print("time = %s" % str(date1.time() ))
print("result = %s" % result)
dialog.destroy()
def Onbutton2Click(self):
date,time,result = DateDialog.getDateTime(self)
if result:
self.lineEdit.setText(date.toString())
print("\n日期框的返回值")
print("date = %s" % str(date ))
print("time = %s" % str(time ))
print("result = %s" % result)
(2)通过信号和槽的方式
# 通过信号和槽的方式传递信息
class Dialog2(QDialog):
singnal = pyqtSignal(str) # 静态常量
def __init__(self,parent=None):
super(Dialog2,self).__init__(parent)
self.edit = QLineEdit(self)
layout = QVBoxLayout(self)
layout.addWidget(self.edit)
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel,Qt.Horizontal,self)
buttons.accepted.connect(self.emitSingal)
buttons.rejected.connect(self.reject)
layout.addWidget(buttons)
def emitSingal(self):
text = self.edit.text()
print("信号发射中")
self.singnal.emit(text)
print("信号发射成功")
self.close()
class CallDiolog2(QWidget):
def __init__(self,parent=None):
super(CallDiolog2,self).__init__(parent)
layout = QHBoxLayout()
self.label = QLabel("空",self)
self.button = QPushButton("确定",self)
self.button.clicked.connect(self.opendialog)
layout.addWidget(self.label)
layout.addWidget(self.button)
self.setLayout(layout)
def opendialog(self):
dia = Dialog2(self)
dia.show()
dia.singnal.connect(self.exChanged)
def exChanged(self,data):
self.label.setText(data)
print("接收信号")
5、点击按钮,在主窗口添加子窗口
先用QtDesigner画好框图,在需要添加的子窗口的位置先添加一个Layout布局控件:
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(686, 618)
self.label = QtWidgets.QLabel(Form)
self.label.setGeometry(QtCore.QRect(130, 90, 72, 15))
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(Form)
self.label_2.setGeometry(QtCore.QRect(380, 90, 72, 15))
self.label_2.setObjectName("label_2")
self.pushButton = QtWidgets.QPushButton(Form)
self.pushButton.setGeometry(QtCore.QRect(260, 140, 93, 28))
self.pushButton.setObjectName("pushButton")
self.formLayoutWidget = QtWidgets.QWidget(Form)
self.formLayoutWidget.setGeometry(QtCore.QRect(110, 220, 381, 311))
self.formLayoutWidget.setObjectName("formLayoutWidget")
self.formLayout = QtWidgets.QFormLayout(self.formLayoutWidget)
self.formLayout.setContentsMargins(0, 0, 0, 0)
self.formLayout.setObjectName("formLayout")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.label.setText(_translate("Form", "提示1"))
self.label_2.setText(_translate("Form", "提示2"))
self.pushButton.setText(_translate("Form", "确认"))
然后在主窗口中创建一个子窗口,在按钮点击后,使用layout.addWidget()函数将子窗口添加到主窗口中,注意:添加后需要使用show()函数显示子窗口:
class Main(QMainWindow,Ui_Form):
def __init__(self,parent=None):
super().__init__(parent)
self.win = InputDialog()
self.setupUi(self)
self.pushButton.clicked.connect(self.show_)
def show_(self):
self.formLayout.addWidget(self.win)
self.win.show()
6、图片放大缩小,自由移动
from PyQt5.QtGui import QPixmap, QPainter, QImage
from PyQt5.QtWidgets import QWidget,QApplication
from PyQt5.QtCore import Qt,QPoint
import sys
class Example(QWidget):
def __init__(self,qImage,parent=None):
super(Example,self).__init__(parent)
# self.setAttribute(Qt.WA_TranslucentBackground)
self.setWindowFlags(Qt.Tool)
# self.width = qImage.width()
# self.height = qImage.height()
self.resize(200,200)
self.pix = QPixmap(self.width(),self.height())
print(self.height(),self.width())
self.point = QPoint(0,0)
self.image = qImage
self.scaled_img = self.image
self.leftClick = False
self.startPos = QPoint(0,0)
self.endPos = QPoint(0,0)
def paintEvent(self, event):
painter = QPainter()
painter.begin(self)
self.drawImage(painter)
painter.end()
def drawImage(self, painter):
painter.drawPixmap(self.point,QPixmap.fromImage(self.scaled_img))
def setImage(self,image,color=False):
self.currentImage = image
if color:
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
self.image = QImage(image,image.shape[1], image.shape[0],image.shape[1]*3, QImage.Format_RGB888)
else:
# 第四个参数表示图像每行有多少个字节,不设定时,图像有时会歪,所以一定要设定
self.image = QImage(image, image.shape[1], image.shape[0],image.shape[1], QImage.Format_Grayscale8)
self.scaled_img = self.image
self.point = QPoint((self.width() - self.image.width()) / 2, (self.height() - self.image.height()) / 2)
# self.update()
self.repaint()
def mousePressEvent(self, event):
# 按下左键
if event.button() == Qt.LeftButton and self.isSelectPicture(event):
self.leftClick = True
self.startPos = event.pos()
def mouseMoveEvent(self, event):
# 移动按住移动鼠标
if self.leftClick:
self.endPos = event.pos() - self.startPos
self.point = self.point + self.endPos
self.startPos = event.pos()
self.repaint()
def mouseReleaseEvent(self, event):
# 释放鼠标
if event.button() == Qt.LeftButton:
self.leftClick = False
elif event.button() == Qt.RightButton:
self.point = QPoint((self.width()-self.image.width())/2,(self.height()-self.image.height())/2)
self.scaled_img = self.image
self.repaint()
def wheelEvent(self, event):
speed = 20
if event.angleDelta().y() > 0 and self.isSelectPicture(event):
# 放大图片
self.scaled_img = self.image.scaled(self.scaled_img.width()+speed, self.scaled_img.height()+speed)
# 保证放大图片时,从鼠标处向周围放大
pos_x = (event.x()-self.point.x())/(self.scaled_img.width()-speed) # pos_x为鼠标在放大前图像位置的比例
pos_y = (event.y()-self.point.y())/(self.scaled_img.height()-speed)
new_x = speed * pos_x # new_x为需要向左移动的距离
new_y = speed * pos_y
self.point = QPoint(self.point.x()-new_x, self.point.y()-new_y)
self.repaint()
elif event.angleDelta().y() < 0 and self.isSelectPicture(event):
# 缩小图片
self.scaled_img = self.image.scaled(self.scaled_img.width()-speed, self.scaled_img.height()-speed)
# 保证缩小图片时,从周围鼠标处缩小
pos_x = (event.x() - self.point.x()) / (self.scaled_img.width() + speed)
pos_y = (event.y() - self.point.y()) / (self.scaled_img.height() + speed)
new_x = speed * pos_x
new_y = speed * pos_y
self.point = QPoint(self.point.x() + new_x, self.point.y() + new_y)
self.repaint()
def resizeEvent(self, event):
if self.parent is not None:
self.scaled_img = self.image
self.point = QPoint((self.width()-self.image.width())/2,(self.height()-self.image.height())/2)
self.update()
def isSelectPicture(self,event):
# 鼠标是否放在图片的范围内
if self.point.x()<event.x()<self.point.x()+self.scaled_img.width():
if self.point.y()<event.y()<self.point.y()+self.scaled_img.height():
return True
return False
if __name__ == '__main__':
app = QApplication(sys.argv)
qImage = QImage("test.jpg")
ex = Example(qImage)
ex.show()
sys.exit(app.exec_())
7、给窗口添加菜单
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QMenu,QMessageBox
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QCursor
class Example(QWidget):
def __init__(self):
super().__init__()
# 窗口标题
self.setWindowTitle('右键菜单')
# 定义窗口大小
self.resize(400, 400)
# 将ContextMenuPolicy设置为Qt.CustomContextMenu
# 否则无法使用customContextMenuRequested信号
self.setContextMenuPolicy(Qt.CustomContextMenu)
# 创建QMenu信号事件
self.customContextMenuRequested.connect(self.showMenu)
self.contextMenu = QMenu(self)
self.CP = self.contextMenu.addAction('复制')
self.JQ = self.contextMenu.addAction('剪切')
self.NT = self.contextMenu.addAction('粘贴')
# 二级菜单
self.GN = self.contextMenu.addMenu("功能")
self.ZJ = self.GN.addAction('增加')
self.XG = self.GN.addAction('修改')
self.SC = self.GN.addAction('删除')
# 事件绑定
self.CP.triggered.connect(self.Event)
self.JQ.triggered.connect(self.Event)
self.NT.triggered.connect(self.Event)
self.ZJ.triggered.connect(self.Event)
self.XG.triggered.connect(self.Event)
self.SC.triggered.connect(self.Event)
def showMenu(self, pos):
# pos 鼠标位置
print(pos)
# 菜单显示前,将它移动到鼠标点击的位置
self.contextMenu.exec_(QCursor.pos()) # 在鼠标位置显示
def Event(self):
# sender()记录了发送信号的对象
QMessageBox.information(self, "提示:", ' 您选择了' + self.sender().text())
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())