Reputation: 439
I would like to change the text of a Label widget from the QLabel class to display the file path of an image file chosen by a user when they click a button to open the file dialog to choose an image from their computer. Here is the code:
class GUI(QMainWindow):
#Load the GUI.
def __init__(self):
super().__init__()
#Define the window icon.
self.window_icon = QIcon("LightMap.png")
#Make the UI.
self.init_ui()
#Fill the GUI.
def init_ui(self):
#Load the UI file.
main_window = uic.loadUi("mainwindow.ui", self)
#Set the window icon.
self.setWindowIcon(self.window_icon)
#Add commands for actions under the submenus.
self.command_file_menu(main_window)
self.command_settings_menu(main_window)
self.command_help_menu(main_window)
#Handle the case that the user clicks on the "Open Image" button.
main_window.button_open_image.setStatusTip("Open Image")
main_window.button_open_image.clicked.connect(self.open_file)
#Make sure this variable has been declared so that we can click "Start Mapping" at any time.
self.file_chosen = None
#Handle the case that the user clicks on the "Start Mapping" button.
main_window.button_start_mapping.setStatusTip("Start Mapping")
main_window.button_start_mapping.clicked.connect(self.start_mapping)
#Show the main window.
self.show()
#Add commands for actions under the File menu.
def command_file_menu(self, main_window):
#Back-end logic for Open Image.
main_window.action_open_image.setShortcut("CTRL+O")
main_window.action_open_image.setStatusTip("Open Image")
main_window.action_open_image.triggered.connect(self.open_file)
#Open an image file.
def open_file(self):
#Select the file dialog design.
dialog_style = QFileDialog.DontUseNativeDialog
dialog_style |= QFileDialog.DontUseCustomDirectoryIcons
#Open the file dialog to select an image file.
self.file_chosen, _ = QFileDialog.getOpenFileName(self, "QFileDialog.getOpenFileName()", "",
"JPEG (*.JPEG *.jpeg *.JPG *.jpg *.JPE *.jpe *JFIF *.jfif);; PNG (*.PNG *.png);; GIF (*.GIF *.gif);; Bitmap Files (*.BMP *.bmp *.DIB *.dib);; TIFF (*.TIF *.tif *.TIFF *.tiff);; ICO (*.ICO *.ico)", options=dialog_style)
#Show the path of the file chosen.
if self.file_chosen:
#Change the text on the label to display the file path chosen.
else:
#Change the text on the label to say that "No file was selected. Please select an image."
#This 'else' statement is used to catch the case where the user presses 'Cancel' after opening the file dialog,
#which will close the file dialog without choosing any file, even if they had already previously chosen a file
#from previously opening the file dialog.
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = GUI()
sys.exit(app.exec_())
I have already tried to directly pass main_window
into open_file()
and directly set the label text like this: main_window.label_file_name.setText(self.file_chosen)
, but the file dialog opens immediately as I launch the GUI with the error TypeError: argument1 has unexpected type NoneType
.
I managed to get this feature working with TkInter, but I haven't been able to figure out how to repeat that functionality over to PyQt5. Here is an example of my working TkInter code:
class GUI:
#Structure the GUI.
def __init__(self):
#Create a blank window.
self.root = Tk()
#Create the frame.
frameRoot = Frame(self.root)
frameRoot.pack()
#Create the menu.
menu = Menu(self.root)
self.root.config(menu=menu)
#Create the "File" submenu.
fileMenu = Menu(menu, tearoff=0)
menu.add_cascade(label="File", menu=fileMenu)
fileMenu.add_command(label="Open Image", command=self.openFile)
#Make a button to open the image file.
self.fileChosen = None #Prevent the user from mapping without first selecting an image.
self.buttonFile = Button(frameRoot, text="Open Image...", command=self.openFile)
self.buttonFile.grid(row=3, column=1)
#Display the directory path of the file chosen.
self.fileName = StringVar()
self.fileName.set("No File Selected")
self.labelFileName = Label(frameRoot, textvariable=self.fileName, fg="red")
self.labelFileName.grid(row=4, column=1)
#Keep the window open.
self.root.mainloop()
#Open the image file.
def openFile(self):
#Only accept the following file types.
self.fileChosen = filedialog.askopenfilename(filetypes=[("Bitmap Files", "*.BMP *.bmp *.DIB *.dib"),
("JPEG", "*.JPEG *.jpeg *.JPG *.jpg *.JPE *.jpe *JFIF *.jfif"),
("PNG", "*.PNG *.png"),
("GIF", "*.GIF *.gif"),
("TIFF", "*.TIF *.tif *.TIFF *.tiff"),
("ICO", "*.ICO *.ico")
])
#If a file was selected, show the file path. Else, inform the user.
if self.fileChosen:
self.fileName.set(self.fileChosen)
else:
self.fileName.set("No image was selected. Please select an image.")
if __name__ == "__main__":
#Create an object to access the class.
g = GUI()
The key to my success with my TkInter implementation was the usage of the StringVar() class which comes from TkInter. I've tried doing a mix of TkInter and PyQt5 just to get this requirement working, but that just threw some more errors.
Upvotes: 0
Views: 4722
Reputation: 243897
In your case you should be able to access the variable main_window since it allows me to access the label, for this you must pass it as a parameter, so I would suggest that you use a lambda function and modify your code to:
[...]
main_window.button_open_image.clicked.connect(lambda: self.open_file(main_window))
#Open an image file.
def open_file(self, main_window):
#Select the file dialog design.
dialog_style = QFileDialog.DontUseNativeDialog
dialog_style |= QFileDialog.DontUseCustomDirectoryIcons
#Open the file dialog to select an image file.
self.file_chosen, _ = QFileDialog.getOpenFileName(self, "QFileDialog.getOpenFileName()", "",
"JPEG (*.JPEG *.jpeg *.JPG *.jpg *.JPE *.jpe *JFIF *.jfif);; PNG (*.PNG *.png);; GIF (*.GIF *.gif);; Bitmap Files (*.BMP *.bmp *.DIB *.dib);; TIFF (*.TIF *.tif *.TIFF *.tiff);; ICO (*.ICO *.ico)", options=dialog_style)
#Show the path of the file chosen.
if self.file_chosen:
main_window.label_file_name.setText(self.file_chosen)
#Change the text on the label to display the file path chosen.
else:
main_window.label_file_name.setText("No file was selected. Please select an image.")
#Change the text on the label to say that "No file was selected. Please select an image."
#This 'else' statement is used to catch the case where the user presses 'Cancel' after opening the file dialog,
#which will close the file dialog without choosing any file, even if they had already previously chosen a file
#from previously opening the file dialog.
Upvotes: 2