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

Recent Posts

Archive

2023
2022
2021
2020
2019
2018
2014
2012
2011
2010
2009
2008
2007

Categories

Authors

Feeds

RSS / Atom