QT - QPixmap 不会使用当前父大小重新缩放



我正在尝试构建一个topBar来放入其他小部件layout但我不知道为什么'QPixmap在我们更改应用程序窗口大小时没有重新缩放。代码如下:

QPixmapQLabel QWidgetQHBoxLayout范围内,QMainWindow centralWidget

QT 5.8 - 蟒蛇 3.6

我已经在2017年3月24日更新了此代码并删除了以前的版本。

0 - 依赖项

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys

1 - 主窗口

class MainWindow(QMainWindow):
    def __init__(self):
        print("I've been in main window")
        super().__init__()
        self.initUI()
    def initUI(self):
        self.setWindowTitle("I'm here, the main window")

2 - 顶栏

class topBar(QWidget):
    def __init__(self):
        print("I've been in topBar")
        super().__init__()
        self.initUI()
    def initUI(self):
        self.setObjectName("topBar")
        self.setStyleSheet("""
        QWidget {background-color: pink;}
        QLabel {background-color: green; }""")
    def resizeEvent(self,event):
        resizeHandler(self,event) # You'll see this little dude right next

3 - resizeEvent处理程序,我相信问题是

def resizeHandler(self,event):
    print(" I've been in resizeHandler")
    if self.objectName() == "topBar":
        print("I've been resizing the topBar")
        logo = QPixmap('some_Image')
        # Debug
        # You'll be able to see that it does re-scale, but it's not updating the Pixmap.
        logo.scaled(event.size(),Qt.KeepAspectRatio).save("pixmap.png")
        # ...
        logoContainer = QLabel()
        logoContainer.setPixmap(logo.scaled(event.size(),Qt.KeepAspectRatio,Qt.FastTransformation))  
        logoContainer.setMaximumSize(logo.width(),logo.height())
        containerLayout = QHBoxLayout()
        containerLayout.addWidget(logoContainer,0)
        container = QWidget()
        container.setLayout(containerLayout)
        # Layout
        layout = QHBoxLayout()
        layout.addWidget(container,0)
        self.setLayout(layout)
        main.setCentralWidget(self)

4 - 测试

if __name__ == '__main__':
    print("I've been in __main__")
    app = 0
    app = QApplication(sys.argv)
    app.aboutToQuit.connect(app.deleteLater)
    app.setWindowIcon(QIcon('someIcon'))
    main = MainWindow() 
    main.layout().setSizeConstraint(QLayout.SetNoConstraint)
    bar = topBar()
    main.setCentralWidget(bar)
    main.show()
    app.exec_()

如果可能的话,我还想topBar限制它self垂直不超过当前屏幕尺寸的 20%(setMaximumHeight?但基于什么?但我不确定如何。

谢谢!

若要获取小组件以填充容器,您需要将垂直和水平大小策略设置为最小、展开、最小展开或忽略。 http://doc.qt.io/qt-5/qsizepolicy.html#Policy-enum

至于第二个问题,它不是Qt小部件的内置功能。你可能会得到更好的运气与QML或Web引擎。你可以创建一个QWidget的子类,它使用setGeometry((和一些窗口计算来约束它的大小。

我认为您在尝试诊断问题时在这里看错了东西。

您的最后一条评论指出...

真正的问题是QPixmap没有更新其大小

这是因为显示它的QLabel没有调整大小。 回到您的原始代码,我认为您需要做的就是在containerQLabel logo之间插入布局......

class topBar(QWidget):
def __init__(self,parent):
    super().__init__()
    container = QWidget()
    container.setMaximumSize(587,208)
    container.setMinimumSize(0,0)
    ## Logo
    logo = QLabel(container)
    #logo = QLabel(container_layout)
    logo.setPixmap(QPixmap('.some_image_in_the_current_working_dir.png'))
    logo.setScaledContents(1)
    # G.M.
    container_layout = QHBoxLayout(container)
    container_layout.addWidget(logo)
    # Layout
    ## to center content horizontally in wrapper w/o preventing rescale
    layout = QHBoxLayout(self)
    layout.addWidget(container)
    self.setStyleSheet("""
    QWidget {background-color: red;}
    QLabel {background-color: green; Qt::KeepAspectRatio;}""")
if __name__ == '__main__':
    app = 0
    app = QApplication(sys.argv)
    app.aboutToQuit.connect(app.deleteLater)
    test = topBar(None)
    test.show()
    app.exec_()

(寻找通用汽车的评论(

上面的代码只是为container创建一个布局container_layout,并使logo成为它的子项。 这似乎解决了我认为您所描述的问题

经过大量的调试和阅读,我想出了以下解决方案(使用numpy来帮助重新缩放(:

def resizeHandler(self,event):
    if self.objectName() == "topBar":
        # Wiping the old layout
        temp = QWidget()
        temp.setLayout(self.layout())
        # Pixmap
        logoPixmap = QPixmap('./img/exampleImage.png')
        # Label
        logoLabel = QLabel()
        logoLabel.setPixmap(logoPixmap)
        logoLabel.setScaledContents(True)
        ## Label Container Layout
        containerLayout = QHBoxLayout()
        containerLayout.addWidget(logoLabel,0)
        # Label Container
        logoContainer = QWidget()
        logoContainer.setLayout(containerLayout)
        # Finding the width and height of the scaled box
        # Image unit vectors
        imageSize = np.array((logoPixmap.width(),logoPixmap.height()))
        screenSize = np.array((event.size().width(),event.size().height()))
        # Proportion of each dimension in relation to the smallest side
        # Note that one will always be the unit vector and the other greater than a unit
        screenUVec = screenSize / screenSize.min()
        imageUVec = imageSize / imageSize.min()

        # minBorder 11 is the distance between the Application vertical border and the central widget
        # 22 is the minimum height where the CentralWidget begins to appear 
        # Which should vary according to the height of menubar and statsbar of the QMainWindow
        minBorder = np.array([11,22]) *2
        screenSize -= minBorder
        for axis,size in enumerate(screenSize):
            if size < 0:
                screenSize[axis] = 0
        maxSize = np.zeros(2)
        # Ideal ratio based on the maxSide
        ratio =  int(round(screenSize[imageUVec.argmax()] / imageUVec.max() - 0.49999999))
        if ratio >=1 and 0 not in screenSize: # Image is scalable on the current screen
            maxSize[imageUVec.argmin()] = min(screenSize[imageUVec.argmin()],ratio) # We should add imageSize[imageUVec.argmin()] if we want to limit the maxSize to the maximum size of the image
            maxSize[imageUVec.argmax()] = maxSize[imageUVec.argmin()] * imageUVec.max()
            sizeUVec = maxSize / maxSize.min()

        # Layout
        layout = QHBoxLayout()
        layout.addWidget(logoContainer,0)
        logoLabel.setMaximumSize(QSize(maxSize[0],maxSize[1]))
        self.setLayout(layout)

特别感谢@alexisdm,他在这里向我展示了我们应该首先擦拭旧布局。当我开始观看globals时,我看到几个布局堆叠在一起。

至于重新缩放部分,我仍然经历了一条非常规的道路,但它的行为方式是我想要的。

相关内容

  • 没有找到相关文章

最新更新