[pyqt5]setGeometry设置后控件宽高和预期设置不一样

一直以来以为setGeometry可以设置控件宽高,某一天发现一个代码

# -*- coding: utf-8 -*-
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.Qt import QPixmap, QPoint, Qt, QPainter
from PyQt5.QtWidgets import QWidget


class ImageBox(QWidget):
    def __init__(self):
        super(ImageBox, self).__init__()
        self.setGeometry(QtCore.QRect(0, 0, 800, 600))
        #self.setFixedSize(800,600)
        self.img = None
        self.scaled_img = QPixmap()
        self.scaled_img.fill(Qt.white)
        self.start_pos = None
        self.end_pos = None
        self.left_click = False
        self.wheel_flag = False
        self.setMouseTracking(True)
        self.scale = 1
        self.old_scale = 1
        self.point = QPoint(0, 0)
        self.x = -1
        self.y = -1
        self.new_height = -1
        self.new_width = -1
        # self.set_image(r'E:\pao.jpg')
        self.setStyleSheet('background:green')


    def init_ui(self):
        self.setWindowTitle("ImageBox")

    def set_image(self, img_path):
        self.img = QPixmap(img_path)
        width, height = self.img.width(), self.img.height()
        if height / width > self.height() / self.width():
            new_height = self.height()
            new_width = width * self.height() / height
        else:
            new_height = height * self.width() / width
            new_width = self.width()
        self.point = QPoint(int((self.width() - new_width) * 0.5), int((self.height() - new_height) * 0.5))
        self.img = self.img.scaled(new_width, new_height, Qt.KeepAspectRatio)
        self.scaled_img = self.img

        self.new_height = new_height
        self.new_width = new_width
        self.scale = 1

    def paintEvent(self, e):
        if self.scaled_img:
            painter = QPainter()
            painter.begin(self)
            painter.scale(self.scale, self.scale)
            if self.wheel_flag:  # 定点缩放
                self.wheel_flag = False
                # 判断当前鼠标pos在不在图上
                this_left_x = self.point.x() * self.old_scale
                this_left_y = self.point.y() * self.old_scale
                this_scale_width = self.new_width * self.old_scale
                this_scale_height = self.new_height * self.old_scale

                # 鼠标点在图上,以鼠标点为中心动作
                gap_x = self.x - this_left_x
                gap_y = self.y - this_left_y
                if 0 < gap_x < this_scale_width and 0 < gap_y < this_scale_height:
                    new_left_x = int(self.x / self.scale - gap_x / self.old_scale)
                    new_left_y = int(self.y / self.scale - gap_y / self.old_scale)
                    self.point = QPoint(new_left_x, new_left_y)
                # 鼠标点不在图上,固定左上角进行缩放
                else:
                    true_left_x = int(self.point.x() * self.old_scale / self.scale)
                    true_left_y = int(self.point.y() * self.old_scale / self.scale)
                    self.point = QPoint(true_left_x, true_left_y)
            painter.drawPixmap(self.point, self.scaled_img)  # 此函数中还会用scale对point进行处理
            painter.end()

    def wheelEvent(self, event):
        angle = event.angleDelta() / 8  # 返回QPoint对象,为滚轮转过的数值,单位为1/8度
        angleY = angle.y()
        self.old_scale = self.scale
        self.x, self.y = event.x(), event.y()
        self.wheel_flag = True
        # 获取当前鼠标相对于view的位置
        if angleY > 0:
            self.scale *= 1.08
        else:  # 滚轮下滚
            self.scale *= 0.92
        if self.scale < 0.3:
            self.scale = 0.3
        self.adjustSize()
        self.update()

    def mouseMoveEvent(self, e):
        print('鼠标移动:', e.pos())
        print('控件宽高:w={},h={}'.format(self.width(), self.height()))
        if self.left_click:
            self.end_pos = e.pos() - self.start_pos  # 当前位置-起始位置=差值
            self.point = self.point + self.end_pos / self.scale  # 左上角的距离变化
            self.start_pos = e.pos()
            self.repaint()

    def mousePressEvent(self, e):
        if e.button() == Qt.LeftButton:
            self.left_click = True
            self.start_pos = e.pos()

    def mouseReleaseEvent(self, e):
        if e.button() == Qt.LeftButton:
            self.left_click = False


class Ui_Form(QWidget):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(800, 600)
        # 创建QScrollArea容器
        self.scrollArea = QtWidgets.QScrollArea(Form)
        self.scrollArea.setGeometry(QtCore.QRect(0, 0, 800, 600))
        self.scrollArea.setStyleSheet('background:black')
        self.scrollArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        # self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        # 创建QWidget容器
        self.scrollAreaWidgetContents = QtWidgets.QWidget()
        self.scrollAreaWidgetContents.setStyleSheet("background:red")
        self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 800, 600))
        self.scrollAreaWidgetContents.setMinimumSize(QtCore.QSize(100, 100))
        self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
        # 在QWidget容器容器上创建一个QGridLayout网格布局
        self.gridLayout = QtWidgets.QGridLayout(self.scrollAreaWidgetContents)
        self.gridLayout.setObjectName("gridLayout")
        # 创建一个图片容器
        self.box = ImageBox()
        # 将图片容器放到网格布局
        self.gridLayout.addWidget(self.box, 0, 0, 1, 1)
        # 将QWidget容器放到scrollArea
        self.scrollArea.setWidget(self.scrollAreaWidgetContents)

        #print('self.scrollAreaWidgetContents width={},height={}'.format(self.scrollAreaWidgetContents.width(),self.scrollAreaWidgetContents.height()))



        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_Form()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

你可以运行看看,发现imagebox宽高一直是778x578宽高都是少了22像素,这个让我百思不得其解,反复调试都没发现问题,难道哪里把尺寸改过,后来发现一直没什么问题,但是这个不可控的控件尺寸很明显会影响开发,比如我就要800x600怎么办,后来在代码加了一句就可以了

self.setFixedSize(800,600)

然后控件尺寸就变成800x600但是为什么setGeometry却不行了,从字面理解setGeometry就是设置控件位置和显示尺寸,但是不是设置真实控件尺寸。因此需要用设置控件尺寸函数去设置才应该合理,但是为什么不设置固定尺寸,为啥是778x578呢,这个我一直没弄明白,而且至今也没弄明白为什么会是这个值,也许将成为永久的未解之谜了。

你可能感兴趣的:(qt,开发语言)