当其他内容更改小部件中的宽度时,PyQt Image(pixmap)被裁剪

时间:2018-08-28 03:25:40

标签: python pyqt pyqt5

我正在制作一个类似表格的小部件,用于显示图像,文件名和两个框选择区域。我有两个对象“ grid_row”和“ grid_table”(都使用QGridLayout),grid_row是单行,grid_table包含x个数量的grid_rows(我正在设计它,因为它很容易跟踪我的自定义属性)。

该工具看起来像这样

最终的布局是QVBoxLayout,然后从上到下,我有QHBoxLayout(带有标签和组合框的一个),grid_row(用于标题1,2,3),一个scroll_area,其中包含每个grid_table正在grid_rows。最后是按钮的另一个QHBoxLayout。

每个grid_row包含一个“图像小部件”和两个区域标签(QLabel)。图像小部件包含一个标签(我使用setPixmap进行显示)和一个按钮。这是我的grid_row和image_widget类:

class grid_row(QWidget):
    def __init__(self, parent=None):
        super().__init__()
        #self.frame = frame_main()

        self.grid_layout = QGridLayout()
        self.grid_layout.setSpacing(50)

        self.image_widget = image_widget()

        self.grid_layout.addWidget(self.image_widget, 0, 0, 1, 1, Qt.AlignHCenter)


        self.region_2 = QLabel('null')
        self.grid_layout.addWidget(self.region_2, 0, 2, 1, 1, Qt.AlignHCenter)

        self.setLayout(self.grid_layout)

        self.region_1 = QLabel('null')
        self.grid_layout.addWidget(self.region_1, 0, 1, 1, 1, Qt.AlignHCenter)
class image_widget(QWidget):
    def __init__(self, parent=None):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setAcceptDrops(True)
        self.image_widget_layout = QHBoxLayout()
        self.image_widget_label = QLabel()
        self.image_widget_label.setPixmap(QPixmap('default.png').scaled(96, 54))
        self.image_widget_layout.addWidget(self.image_widget_label)
        self.img_btn = QPushButton()
        self.img_btn.setEnabled(False)
        self.img_btn.setText('Drag Here!') 
        self.image_widget_layout.addWidget(self.img_btn)
        self.setLayout(self.image_widget_layout)
if __name__ == '__main__': 
    app = QApplication(sys.argv)
    widget = QWidget()
    layout = QVBoxLayout()
    grid_row = grid_row()
    layout.addWidget(grid_row)
    btn = QPushButton('press')
    btn.clicked.connect(lambda: grid_row.region_1.setText('[0,0,1920,1080]'))
    layout.addWidget(btn)
    widget.setLayout(layout)
    scroll_area = QScrollArea()
    scroll_area.setWidget(widget)
    scroll_area.show()
    sys.exit(app.exec_())

因此,目前,我已经实现了一些事件,这些事件使我可以将图像拖到image_widget中,然后单击按钮以修改两个被框住的区域(格式:[x1,y1,x2,y2])。问题是当我这样做时(例如,区域值从'null'变为'[20,20,500,500]',图像被压缩了,因为现在标签占据了更大的宽度。

我意识到需要设置一些大小策略(也许还有其他属性),但是我不知道要使用哪个属性以及在哪个窗口小部件上。我希望图像保持不变。也许延长grid_row的每一列的宽度?

为澄清起见,我希望包含像素图的标签始终保持相同大小(始终为96 * 54),并始终完全显示(不裁剪或拉伸)。

我提供了一个简化的可执行代码来显示我的问题,这些类与我的代码相同,我只是将grid_row放在scroll_area内,并添加了一个按钮来更改该区域的值之一以模拟情况。如果需要,可以提供其他代码。预先感谢!

2 个答案:

答案 0 :(得分:1)

哇,有时候答案确实是额外的一行代码... 因此documentation提到默认情况下QScrollArea遵循其小部件的大小。这就是为什么当我更改区域(更改为更大/更多文本的值)时,小部件不会自动调整的原因。

我需要添加

scroll_area.setWidgetResizable(True)

允许窗口小部件重新调整大小,从而提示滚动条出现。这样,我的像素图图像不会因没有足够的空间而被裁剪。

答案 1 :(得分:0)

最简单的方法是在添加到布局之前在标签上添加尺寸限制

 self.image_widget_label.adjustSize()
 self.image_widget_label.setFixedSize(self.image_widget_label.size())
 self.image_widget_layout.addWidget(self.image_widget_label)

adjustSize将根据内容调整标签的大小。

更困难的方法是回答问题:

  

”当我更改整个窗口的大小时,我该如何   特定项目表现如何?当窗口达到最小尺寸时,   我想隐藏或隐藏哪些项目?窗满时   尺寸,我要在哪里留空点?”

要更好地回答这些问题,请阅读Qt Layout management