Skip to content
Advertisement

Combining a file dialog with buttons in PyQt

I’m struggling with making the transition from Tkinter to the more object-oriented approach of PyQt. My particular question focuses on combining file dialogs with buttons. In the example below, having lines of code I admittedly don’t completely understand, I use a file dialog to load a time series, stored as a .csv file, into a dataframe and then plot it:

import sys
import pandas as pd
from matplotlib import pyplot as plt
from PyQt5.QtWidgets import QApplication, QWidget, QFileDialog,

class App(QWidget):

    def __init__(self):
        super().__init__()
        self.title = 'Series Plotter'
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 480
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.openFileNameDialog()
        self.show()

    def openFileNameDialog(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(self,"Choose File", "","csv (*.csv)", 
        options=options)
        df=pd.read_csv(fileName)
        df.plot()
        plt.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

This works insofar as it automatically launches a file dialog and plots the chosen time series. However, I’d prefer to do the following:

  1. Have an “open file” button in my window to launch the file dialog.
  2. Have a “plot series” button in my window to plot the selected series. I imagine this button would need to be disabled until the series is actually chosen.

Despite looking at various tutorials, I’m struggling to find the pythonic way of doing this, a fact I attribute to my limited knowledge of the objected-oriented approach.

Advertisement

Answer

You can try to create a main window and add button there, and connect button click event to a function where you initialize the class you have created, something like this:

from PyQt5 import QtWidgets
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.resize(300,300)
        frame =QtWidgets.QFrame()
        self.setCentralWidget(frame)
        layout = QtWidgets.QHBoxLayout()
        frame.setLayout(layout)
        self.fileOpenButton = QtWidgets.QPushButton('Click to open File Dialog',self)
        layout.addWidget(self.fileOpenButton)
        self.fileOpenButton.clicked.connect(self.buttonClicked)

    def buttonClicked(self):
        wig = App()

def main():
    app = QApplication([])
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

The output:

enter image description here

After clicking the button:

enter image description here

After selecting a file:

enter image description here

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement