0

An external module launches this QDialog window in which I want to have labels, buttons and an image. In this new window, I am struggling with two factors: 1) it clicked.connects buttons before they are even displayed, and 2) when I try to incorporate the image into the QtWidgets Layouts the way I normally do with QHBoxLayouts, QVBoxLayouts, and .addLayouts, the image always appears at the top left of the window (or in the .move position) rather than stacking up in the QHBoxLayouts and QVBoxLayouts as expected.

The external module calls the window object (see arrow in screen grab below):

def photoButtonPressed(self):
        print("Photo button pressed")          
        
        photoWidget = FieldPhotos(self.photoFP, self.photoDT, self)
        photoWidget.show()

First, I comment out all the pixmap/image related content to troubleshoot the buttons and the code automatically runs the updateImagePressed method (passing the direction variable "next") before the window is even displayed (much less clicking the next button):

class FieldPhotos(QtWidgets.QDialog):

    def __init__(self, photoPath, photoDT, parent=None):        
        # Paths and DTs are lists of photos/datetimes within the time limit

        super().__init__(parent)
        self.setModal(True)
        self.photoPath = photoPath
        self.photoDT = photoDT
        self.left = 300
        self.top = 300
        self.width = 800
        self.height = 1000
        self.imageSelect = 0

        self.initUI()
        
    def initUI(self):
        self.setWindowTitle(f'{self.photoDT[0]} {os.path.split(self.photoPath[self.imageSelect])[-1]}')
        self.setGeometry(self.left, self.top, self.width, self.height)
    
        # Create widgets ############################
        # self.labelImage = QtWidgets.QLabel(self)
        labelNote = QtWidgets.QLabel('Close this window to continue.',self)   
        listLabel = QtWidgets.QLabel(f'Number of images found within 90 mins of data: {len(self.photoPath)} ',self)

        self.nextButton = QtWidgets.QPushButton('>')
        self.nextButton.setToolTip('Next image in list')

        self.previousButton = QtWidgets.QPushButton('<')
        self.previousButton.setToolTip('Previous image in list')
        self.nextButton.clicked.connect(self.updateImagePressed('next'))
        self.previousButton.clicked.connect(self.updateImagePressed('previous'))
                
        # Setup Layout ##################################
        self.VBox = QtWidgets.QVBoxLayout()
        # self.VBox.addWidget(labelImage)
        self.VBox.addWidget(labelNote)

        self.HBox = QtWidgets.QHBoxLayout()
        self.HBox.addWidget(listLabel)
        self.HBox.addWidget(self.previousButton)
        self.HBox.addWidget(self.nextButton)
        self.VBox.addLayout(self.HBox)

        # # Set initial photo
        # self.pixmap = QPixmap(self.photoPath[self.imageSelect])
        # self.pixmapScaled = self.pixmap.scaled(800,800,QtCore.Qt.KeepAspectRatio)
        # self.labelImage.setPixmap(self.pixmapScaled)
        # self.resize(self.pixmapScaled.width(),self.pixmapScaled.height())  
        # self.labelImage.move(0,100)  # Since it won't work in VBox, move down to make space?

        # self.updateImagePressed('first')

    def updateImagePressed(self, direction):
        print(f'Display {direction} image: {self.photoPath[self.imageSelect]}') 

        if self.imageSelect ==0:
            self.previousButton.setDisabled(1)
        if self.imageSelect == len(self.photoPath):
            self.nextButton.setDisabled(0)
        
        if direction == 'next':
            self.imageSelect += 1
        if direction == 'previous':
            self.imageSelect -= 1

        # Set photo
        # self.pixmap = QPixmap(self.photoPath[self.imageSelect])
        # self.pixmapScaled = self.pixmap.scaled(800,800,QtCore.Qt.KeepAspectRatio)
        # self.labelImage.setPixmap(self.pixmapScaled)
        # self.resize(self.pixmapScaled.width(),self.pixmapScaled.height())  
        # self.labelImage.move(0,100) 

Results in the following:

Photo button pressed
Display next image: /Users/daurin/Projects_Supplemental/HyperPACE/field_data/HyperSAS/VIIRS2019/Photos/IMG_20190908_104845.jpg
Traceback (most recent call last):
  File "/Users/daurin/GitRepos/HyperInSPACE/Source/AnomalyDetection.py", line 356, in photoButtonPressed
    photoWidget = FieldPhotos(self.photoFP, self.photoDT, self)
  File "/Users/daurin/GitRepos/HyperInSPACE/Source/FieldPhotos.py", line 28, in __init__
    self.initUI()
  File "/Users/daurin/GitRepos/HyperInSPACE/Source/FieldPhotos.py", line 45, in initUI
    self.nextButton.clicked.connect(self.updateImagePressed('next'))
TypeError: argument 1 has unexpected type 'NoneType'"

Next, when I comment out the button actions, and restore the QPixmap code like this:

def initUI(self):
        self.setWindowTitle(f'{self.photoDT[0]} {os.path.split(self.photoPath[self.imageSelect])[-1]}')
        self.setGeometry(self.left, self.top, self.width, self.height)
    
        # Create widgets ############################
        self.labelImage = QtWidgets.QLabel(self)
        labelNote = QtWidgets.QLabel('Close this window to continue.',self)   
        listLabel = QtWidgets.QLabel(f'Number of images found within 90 mins of data: {len(self.photoPath)} ',self)

        self.nextButton = QtWidgets.QPushButton('>')
        self.nextButton.setToolTip('Next image in list')
        
        self.previousButton = QtWidgets.QPushButton('<')
        self.previousButton.setToolTip('Previous image in list')
        # self.nextButton.clicked.connect(self.updateImagePressed('next'))
        # self.previousButton.clicked.connect(self.updateImagePressed('previous'))
                
        # Setup Layout ##################################
        self.VBox = QtWidgets.QVBoxLayout()
        self.VBox.addWidget(self.labelImage)
        self.VBox.addWidget(labelNote)

        self.HBox = QtWidgets.QHBoxLayout()
        self.HBox.addWidget(listLabel)
        self.HBox.addWidget(self.previousButton)
        self.HBox.addWidget(self.nextButton)
        self.VBox.addLayout(self.HBox)

        # Set initial photo
        self.pixmap = QPixmap(self.photoPath[self.imageSelect])
        self.pixmapScaled = self.pixmap.scaled(800,800,QtCore.Qt.KeepAspectRatio)
        self.labelImage.setPixmap(self.pixmapScaled)
        self.resize(self.pixmapScaled.width(),self.pixmapScaled.height())  
        self.labelImage.move(0,100)  # Since it won't work in VBox, move down to make space?

        # self.updateImagePressed('first')

It ignores all the VBoxes and HBoxes, and just piles up content in the top left while ignoring buttons: enter image description here

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • use `self.nextButton.clicked.connect(lambda: self.updateImagePressed('next'))` and `self.previousButton.clicked.connect(lambda: self.updateImagePressed('previous'))` – eyllanesc Apr 14 '21 at 20:15
  • Excellent. The lambda: was the key to passing the variable in the method call. Still struggling to get the buttons to show and layout properly. I.e., still looks like the above screen shot. – OceanColorCoder Apr 14 '21 at 20:36
  • I'm confused. I edited the question with the tagline "[Edited: the issue with the clicked.connects is now resolved. The remaining issue is with the incorporation of a QPixmap into the layout. Question below changed to reflect this update.]" but the question remains closed. Should I launch this as a new question instead? – OceanColorCoder Apr 14 '21 at 20:46
  • If you have N problems then you must create N post, this is the SO logic. I'm not going to reopen your post because of the other problems you have. Here the objective is to solve a specific problem and not all the problems of your project. Please read [ask], pass the [tour] and create a new post where there is only one problem. If you have N independent problems then create N post, if you have several dependent problems then only publish a post with the problem that does not depend on another, so when you solve that problem then create a new post with the new independent problem. – eyllanesc Apr 14 '21 at 20:51
  • Note: If you have N questions in the same post, it can be closed by any of them (there is no complaint about it). So you better write a post with just one problem. Since if you have post in addition to the closure as a duplicate, you could also face the closure for "too broad" where you will not get help at all. – eyllanesc Apr 14 '21 at 20:53
  • Understood. I will post the second issue as a separate question. – OceanColorCoder Apr 14 '21 at 21:02

0 Answers0