2

I am trying to input a file path in a line edit box within a PyQt GUI and then perform functions on that file. I'm hoping this can be done all within the same GUI. Is this even possible?

SepticReVo
  • 45
  • 9

2 Answers2

0

Sure, you can do it within the same GUI. If you want to prevent user from clicking the pbutton1 buton before loading the file you can set its attribute disabled to True and enable the button after the file is loaded (for example when calling button2Pressed function). I don't see any file loading instruction in your code, so the first thing to do for you will be saving the file content in your object, so in your button2Pressed you need something like:

with open(self.lineedit1.text(), 'r') as my_file:
    self.file_content = my_file.readlines()

Now when you have your file loaded you need to count the words. readlines splits the file into separate lines so you will also have to perform a loop to count all the words, so in button1Pressed you can write for example:

self.word_counter = 0
for line in self.file_content:
    for word in line.split(' ')
        if word == self.lineedit2.text():
            counter +=1

Note that the above code only splits your lines into words on a whitespace (' '). If you want commas and other symbols to be removed consider using regex. I hope this will give you an idea. Cheers!

Nhor
  • 3,860
  • 6
  • 28
  • 41
  • How do I then take button2Pressed and input it into my function wordcount? In the past I've used raw_input to name the file, then concatenate that to the designated file path on my computer (see variables g and f in code above). Am I supposed to move my defined functions from the top and insert them into the buttonpressed functions? – SepticReVo Nov 07 '15 at 16:36
0

You code needs some rearrangement to work properly. The main thing to think about is dividing the job up into parts, with each part doing one thing. So one method reads the file, one counts the words, one outputs the results, etc.

Here is a basic re-write of your example with some comments where changes have been made:

import sys, os, string
from PyQt4.QtCore import *
from PyQt4.QtGui import *

# move wordcount function into the class

class Form( QDialog):

    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.setWindowTitle("Word Count GUI")
        # use placeholder text
        self.lineedit2 = QLineEdit()
        self.lineedit2.setPlaceholderText('Enter Filename Here')
        self.pbutton2 = QPushButton('Press to Load File')
        # use placeholder text
        self.lineedit1 = QLineEdit()
        self.lineedit1.setPlaceholderText("Enter Word Here")
        self.pbutton1 = QPushButton("Press for Count")
        self.pbuttonQuit = QPushButton("Exit")
        # don't forget the layout...
        layout = QVBoxLayout()
        layout.addWidget(self.lineedit2)
        layout.addWidget(self.pbutton2)
        layout.addWidget(self.lineedit1)
        layout.addWidget(self.pbutton1)
        layout.addWidget(self.pbuttonQuit)
        self.setLayout(layout)
        self.pbutton2.setFocus()
        # use new-style connections
        self.pbutton1.clicked.connect(self.button1Pressed)
        self.pbutton2.clicked.connect(self.button2Pressed)
        # connect to self.close to quit
        self.pbuttonQuit.clicked.connect(self.close)
        # keep a list of lines
        self.lines = []

    def wordcount(self, word):
        total = 0
        # iterate over stored lines
        for line in self.lines:
            line = line.translate(None, string.punctuation)
            line = line.lower()
            words = line.split()
            if word in words:
                total += 1
        return total

    def button1Pressed(self):
        x1 = self.lineedit1.text()
        x1 = str(x1).lower()
        # use the wordcount method
        x2 = self.wordcount(x1)
        outtext =  str(x1) + " appears " + str(x2) + " times in the file."
        self.lineedit1.setText(outtext)

    def button2Pressed(self):
        # this reads the file and stores the lines
        g = str(self.lineedit2.text())
        g = os.path.join('/Users/xxx/Documents/Python', g)
        try:
            with open(g) as stream:
                self.lines = stream.readlines()
        except EnvironmentError as exception:
            print('ERROR: could not read file:')
            print('  : %s' % exception)
            self.lines = []

app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • Can you explain the os.path.join in button2Pressed? I've never encountered this before. Also, does storing the text as a list, in self.lines = [ ], allow the program to run? self.lines = [ ] in button2Pressed overwrites the self.lines = [ ] in the method __init__ and is the same/new method used in the wordcount method, right? – SepticReVo Nov 07 '15 at 16:57
  • (1) Python docs: [os.path.join](http://docs.python.org/2/library/os.path.html#os.path.join). (2) I fully tested my code before posting it, so why don't you just run it and see what happens? The point of using `self.lines`, and having everything in the class, is so that all the methods can access the same data. It also allows you to run several word counts on the same file without reloading it. – ekhumoro Nov 07 '15 at 17:33
  • I did test out your code and was just looking for confirmation on the process. Thanks for the link on os.path.join. – SepticReVo Nov 07 '15 at 17:43
  • @SepticReVo. So I take it you don't feel your question was answered. If so, can you explain why? – ekhumoro Nov 07 '15 at 18:12
  • The code does what I was looking to do, so yes. Just looking for clarification as to how it works. self.lines = [ ] in button2Pressed overwrites the self.lines = [ ] in the defined method init and is the same/new method used in the defined wordcount method, correct? Setting my file to self.lines allows it to be used in the class, right? – SepticReVo Nov 07 '15 at 19:01
  • @SepticReVo. Yes, `self.lines = []` in `__init__` just sets a default value. This means the other methods can always safely access the `self.lines` attribute. Without that, you could get an `AttributeError`, because the other methods might try to read an attribute that wasn't there yet. Any attribute that is assigned to `self` can be accessed by all other methods of the class, and they will all see the same value. – ekhumoro Nov 07 '15 at 19:19