some PyQt5 ..

(0 comments)

So i wanted a (very simple) GUI for my python program .. and i want it to run on Linux but also windows..

Looking at the choices (Kivy, PyQt, pygtk) I found PyQt to be the most complete toolkit (I want a treeview with more columns later on which is something that kivy doesn'T seem to have). - PyGTK has that too but under windows that is a bit more of a pain to get running (from prior experience).

So I went and tried PyQt5 for the first time (last time I used PyQt it was Version 4 still so been a while ..)

It's fairly easy to get running with PYCharm (Community Edition) just go to the project settings and install the PyQt5 module -- don'T forget the stubs (for some reason installing from the popup hint did not work for me so I did it manually).

I installed qtdesigner too, but couldn'T figure out how to best use it with pycharm immediately so I just put together my (very simple) GUI the old way for now.

The purpose is simple:

  1. pick a base directory
  2. pick a text file with a list of filenames [also picks the file'S directory as source)
  3. verify it makes  sense (the text file and source directory need to be within the base directory
  4. [[ This is in a seperate module and has been used from the command line before ]] find all files from the text file in the base directory, compare to the source one and then save the result (and output it to a textfile and / or QPlainTextEdit later .. maybe will add TreeView at some point but not right now)

so just for anyone wanting to just get a basic idea of how to do this here some source code without much explaination (fairly self explainatory if you are familiar with python and GUI toolkits imho):

import sys
# from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QApplication, QLabel, QWidget, QPushButton, QGridLayout, QLineEdit, QFileDialog,
                             QPlainTextEdit, QTreeWidget)  # QErrorMessage)
from file_find_compare import FileFindCompare

DEBUG = False


class PyFindFileCompare(QWidget):
    # widgets
    base_dir = None
    inp_file = None
    out_text = None
    btn_base_dir = None
    btn_inp_file = None
    btn_start = None
    tv_out = None
    _out_file = None

    def __init__(self):
        super().__init__()

        self.init_ui()

    def init_ui(self):
        layout = QGridLayout()

        layout.addWidget(QLabel(text='Basisordner: '), 0, 0)
        self.base_dir = QLineEdit()
        self.base_dir.setReadOnly(True)
        self.base_dir.setText('//server/Daten')
        layout.addWidget(self.base_dir, 0, 1)
        self.btn_base_dir = QPushButton('Basisordner auswählen: ')
        layout.addWidget(self.btn_base_dir, 0, 2)
        self.btn_base_dir.clicked.connect(self.get_basedir)

        layout.addWidget(QLabel(text='Eingabedatei: '), 1, 0)
        self.inp_file = QLineEdit()
        self.inp_file.setReadOnly(True)
        self.inp_file.setText('//server/Daten')
        layout.addWidget(self.inp_file, 1, 1)
        self.btn_inp_file = QPushButton('Eingabedatei auswählen')
        self.btn_inp_file.setDisabled(True)
        layout.addWidget(self.btn_inp_file, 1, 2)
        self.btn_inp_file.clicked.connect(self.get_inp_file)

        self.btn_start = QPushButton('Start')
        self.btn_start.setDisabled(True)
        layout.addWidget(self.btn_start, 2, 2)
        self.btn_start.clicked.connect(self.start_search)

        self.out_text = QPlainTextEdit()
        self.out_text.setReadOnly(True)
        layout.addWidget(self.out_text, 3, 0, 1, 3)

        self.tv_out = QTreeWidget()
        self.tv_out.hide()
        layout.addWidget(self.tv_out, 4, 0, 1, 3)

        self.setLayout(layout)
        self.setFixedWidth(900)
        self.setMinimumHeight(500)
        self.show()

    def get_basedir(self):
        bdir = str(QFileDialog.getExistingDirectory(self,
                                                    "Basisordner auswählen",
                                                    self.base_dir.text()
                                                    ))
        if bdir:
            self.base_dir.setText(bdir)
            # we got a valid input path so enable the input file button
            self.btn_inp_file.setDisabled(False)
            if DEBUG:
                self.out_text.appendPlainText('got base dir: %s' % self.base_dir.text())
            if self.inp_file.text() != '':
                self.inp_file.setText(self.base_dir.text())

    def get_inp_file(self):
        # stop the user from changing the base dir to avoid weird issues
        # TODO: make it more user friendly later
        self.btn_base_dir.setDisabled(True)
        infile = str(QFileDialog.getOpenFileName(self,
                                                "Eingabedatei auswählen",
                                                self.inp_file.text(),
                                                '*.txt'
                                                )[0]
                     )
        if infile:
            if infile.find(self.base_dir.text()) != 0:
                self.out_text.appendPlainText('Fehler: Die Eingabedatei muß im Basisverzeichnis oder unterordner liegen!')
                return
            else:
                self.btn_start.setDisabled(False)
            self.inp_file.setText(infile)
            self._out_file = self.inp_file.text().replace('.txt', '_output.txt')
            if DEBUG:
                self.out_text.appendPlainText('got input file: %s' % self.inp_file.text())
                self.out_text.appendPlainText('output filename: %s' % self._out_file)

    def start_search(self):
        # just to be save disable both other buttons
        self.btn_inp_file.setDisabled(True)
        self.btn_inp_file.setDisabled(True)

        ffc = FileFindCompare(self.inp_file.text(), self._out_file, self.base_dir.text())
        self.out_text.appendPlainText('Liste der Dateien: %s' % self.inp_file.text())
        self.out_text.appendPlainText('Basisordner: %s' % self.base_dir.text())
        ffc.find_compare()
        self.out_text.appendPlainText('Ausgabe wird gespeichert als %s' % self._out_file)

        self.out_text.appendPlainText('Ausgabe als text:')
        self.out_text.appendPlainText(ffc.generate_output())

        ffc.save_output()

    def populate_tv(self):
        # TODO: populate the treeview
        self.tv_out.show()


if __name__ == '__main__':
    app = QApplication([])
    win = PyFindFileCompare()
    sys.exit(app.exec_())

I made some assumptions / simpilifications for the sake of usability / userfriendliness for now since I was in a rush .. so I am aware there are some issues / not very pretty things but it works and for now that was what mattered -- and to be honest it is such a short / simple program that I am going to be using myself for like 80% of the time if not 100% so whatever ^^

Currently unrated

Comments

There are currently no comments

New Comment

required

required (not published)

optional

required