vandelay
vandelay

Reputation: 2065

Pixmap image size in Qlabel

I'm trying to get an image to fit my label entirely without using setScaledContents(True) since I'd like my ImageGrab to have the exact same dimensions as the QLabel space.

I use a PIL ImageGrab with a bbox. if I chance the parameters to a wider width and higher height it will crash the program without any errors. I have attached a picture where the Image in the Label is localed left center. I'd like it to the top left. So that it can expand down and to the right if I increased the size.

But I am curious as to why I am unable to increase the size of the bbox. (0, 0, 400, 220) works fine but (0, 0, 420, 220) will not upload the Image and closes down the GUI without any errors.

I'd like to have a ImageGrab with bbox (0, 0, 800, 700) and a QLabel with size(800, 700) so it can fit it perfectly.

class Main(QMainWindow):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.setGeometry(200, 200, 1000, 700)
        self.setWindowTitle('threads')

        self.mainFrame = QFrame(self)
        self.mainFrame.resize(1000, 650)
        self.mainFrame.move(0, 50)
        self.mainFrame.setStyleSheet("background-color: rbg(50, 50, 50)")

        self.testButton = QPushButton("Click", self)
        self.testButton.resize(500,30)
        self.connect(self.testButton, SIGNAL("clicked()"), self.Capture)    

        self.label_ = QLabel(self.mainFrame)
        self.label_.move(10, 10)
        self.label_.resize(980, 630)
        self.label_.setStyleSheet("background-color: rbg(150, 150, 150)")

    @pyqtSlot(QImage) 
    def ChangeFrame(self, image):  

        pixmap = QPixmap.fromImage(image)           
        self.label_.setPixmap(pixmap)

    def Capture(self):       
        self.thread_ = CaptureScreen()        
        self.connect(self.thread_, SIGNAL("ChangeFrame(QImage)"), self.ChangeFrame, Qt.QueuedConnection)
        self.thread_.start()     


class CaptureScreen(QThread):
    pixmap = pyqtSignal(QImage)

    def __init__(self, parent = None):
        QThread.__init__(self)

    def __del__(self):
        print("?????")
        self.exiting = True
        self.wait()

    def run(self):         
        while(True):
            time.sleep(1/60)

            img = ImageGrab.grab(bbox=(0, 0, 420, 220))

            frame = ImageQt(img)
            frame = QImage(frame)

            self.emit( SIGNAL("ChangeFrame(QImage)"), frame)

enter image description here

Upvotes: 1

Views: 2712

Answers (1)

eyllanesc
eyllanesc

Reputation: 243955

The solution is to use layouts, and set the alignment in QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft.

I also recommend using the new connection syntax, on the other hand if you are going to inherit from QMainWindow in the constructor you must call it. And finally when you use QMainWindow you must set a central widget.

import time
from PyQt4 import QtCore, QtGui
from PIL import ImageGrab, ImageQt


class Main(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)

        self.setGeometry(200, 200, 1000, 700)
        self.setWindowTitle('threads')

        main_widget = QtGui.QWidget()
        self.setCentralWidget(main_widget)

        lay = QtGui.QVBoxLayout(main_widget)
        self.testButton = QtGui.QPushButton("Click")
        self.testButton.setFixedHeight(30)
        self.testButton.clicked.connect(self.capture)

        mainFrame = QtGui.QFrame()
        mainFrame.setStyleSheet("background-color: rbg(50, 50, 50)")

        _lay = QtGui.QVBoxLayout(mainFrame)
        _lay.setContentsMargins(0, 0, 0, 0)
        self.label_ = QtGui.QLabel()
        _lay.addWidget(self.label_, 0, QtCore.Qt.AlignTop|QtCore.Qt.AlignLeft)

        lay.addWidget(self.testButton)
        lay.addWidget(mainFrame)

    @QtCore.pyqtSlot(QtGui.QImage) 
    def changeFrame(self, image):  
        pixmap = QtGui.QPixmap.fromImage(image)           
        self.label_.setPixmap(pixmap)

    @QtCore.pyqtSlot() 
    def capture(self):       
        self.thread_ = CaptureScreen()       
        self.thread_.changedFrame.connect(self.changeFrame, QtCore.Qt.QueuedConnection)
        self.thread_.start()     
        self.testButton.setDisabled(True)


class CaptureScreen(QtCore.QThread):
    changedFrame = QtCore.pyqtSignal(QtGui.QImage)

    def __del__(self):
        print("?????")
        self.exiting = True
        self.quit()
        self.wait()

    def run(self):         
        while True:
            time.sleep(1/60)
            w, h = 420, 220
            img = ImageGrab.grab(bbox=(0, 0, w, h))
            frame = ImageQt.toqimage(img)
            self.changedFrame.emit(QtGui.QImage(frame))


if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    w = Main()
    w.show()
    sys.exit(app.exec_())

Upvotes: 2

Related Questions