pyqt5笔记

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_())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值