简体   繁体   中英

PyQt5 Pixmap in Label dynamic resize via Splitter

I am currently trying to solve a problem with resizing Pixmap dynamically, I have a QLabel in one corner of my QMainWindow, from both sides surrounded by two different QSplitters when I change picture it is scaled by the size of the label with KeepAspectRatio. Both splitters also are connected with signal to a function that once again scales the pixmap to fit as much as it can.

The problem I ran into is, that I cannot figure out how to be able to decrease the size when the pixmap already fits all the space available, because at that moment the splitters just stop working.

This is the pixmap setup:

self.picture_field.setStyleSheet("border: 4px solid")
self.pixmap = QPixmap('dandelion.jpg')
self.picture_field.setAlignment(Qt.AlignCenter) 
self.picture_field.setPixmap(self.pixmap.scaled(self.picture_field.width()-8, 
self.picture_field.height()-8, Qt.KeepAspectRatio))

The -8 has to be there because of the border, if it was missing, the widget gets bigger with every change

One of the Qsplitters:

right_splitter = QSplitter(Qt.Vertical)
right_splitter.addWidget(self.picture_field)
right_splitter.addWidget(self.person_field)
right_splitter.splitterMoved.connect(self.dynamic_scaling)

Person_field is simple QTreeView

The dynamic scaling function:

def dynamic_scaling(self):
    self.picture_field.setPixmap(self.pixmap.scaled(self.picture_field.width()-8, self.picture_field.height()-8, Qt.KeepAspectRatio))

EDIT: I tested it a little bit more, and it seems, that the pixmap reacts, but only once either the width or height is halved.

Judging by this statement, "I cannot figure out how to be able to decrease the size when the pixmap already fits all the space available, because at that moment the splitters just stop working", I think I know what the problem is. Every QWidget has a minimum size, available through the function QWidget.minimumSize . From experience I know that a QSplitter honors the minimum sizes of its children, and it will not allow the user to move the sash to a position that would force one of the children to take a size less than its minimum.

You say that one of the splitter's children is a QLabel. By design, QLabels are pretty smart about their own size requirements. If you change the text of a QLabel, for example, it will automatically recompute its size values and trigger a re-layout. I assume it does the same thing if you change the Pixmap, although I have not tried this myself. The point is that the QLabel's minimum size changes as its contents change.

Because of the dynamic resizing of the QLabel, and the refusal of a QSplitter to allow a child widget to violate its minimum size, the splitter may appear to "get stuck" and prevent you from making it smaller.

To fix this you need to make the QLabel have a minimum size that's very small, say (1,1). There are a few ways to do this. Since I don't have your complete application I can't be sure which one will work best for you.

Subclass QLabel and override minimumSize to return (0,0) This is pretty straightforward.

Set the size policy on the QLabel object to QSizePolicy.Ignore . See the docs for the function QWidget.SetSizePolicy .

Use the function QWidget.SetMimimumSize . I'm not sure this will work for QLabels since any change you try to make may get undone the next time you change the pixmap.

Replace your QLabel with a custom widget subclassed directly from QWidget . A generic QWidget has no minimum size, so your problem goes away. You will need to write a small function to set a new pixmap into your control, which will entail a paint event handler.

I hope that one of these methods will work for you (and that I have understood the problem correctly).

try that:

w = QtGui.Qlabel.width();
h = QtGui.Qlabel.height();

#set a scaled pixmap to a w x h window keeping its aspect ratio 
QtGui.Qlabel.setPixmap(p.scaled(w, h, Qt.KeepAspectRatio))

now try to change h and w .

If you get any issues comment below.

🅿🆈🆀🆃

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM