Forum Archive

Inserting text in a text field from a .txt file

techteej

Currently having trouble putting text in a ui.texfield from a .txt file. Any help?

def get_username():
    global player_name
    p_name = root_view['namefield'].text

    file_name = 'name.txt'
    if p_name == '':
        player_name = 'Player 1'
    else:
        player_name = root_view['namefield'].text

    if path.isfile(file_name):
        with open(file_name) as f:
            for line in f.readlines():
                if line.istitle():
                    player_name = line
                    root_view['namefield'].text = line
    if not player_name:
        player_name = root_view['namefield'].text
        if player_name:
            with open(file_name, 'w') as f:  
                f.write(player_name)
    return player_name or 'Player 1'
briarfox

The first file you open should be:

with open(file_name, 'r') as f:

Look into plistlib or ConfigParser for handling config and setting data..

techteej

Unfortunately, this does not help. The text still does not show up.

ccc

https://gist.github.com/cclauss/5997f9c653c0c4bf1521

techteej

See my fork. This isn't working implementing it into the next update of Cacti Killer.

JonB

Why are you checking istitle? If you don't use Title Case in name.txt, nothing will show up...

techteej

@JonB Used code from previous project, forgot to take out. Taking it out doesn't fix my issue either.

ccc

My recommendation is that you get rid of all lines which contain global player_name which is making the interactions very difficult to follow. get_player_name() / read_player_name() should return the player name so the global statement will not be required. write_player_name() should take player name as an input parameter so the global statement will not be required. Either Game.player_name or Game.player.name should be used so the global statement will not be required. Eliminating the globals will help to minimize the complexity of dealing with this variable across multiple functions.

techteej

Taking out the globals gives me errors saying that player_name is not defined. I do realize how return works..

JonB

Tech, why don't you put a pdb.settrace() at the start of this function, and the. You can step through to see what is happening. I think you will find some errors in your logic. For instance, your if p_name block is not doing what you think it is doing, since you never actually set the textfield to p_name, so if name.txt is empty you'll never get your Player 1 populated as you seem to want.

Likewise I see problems that could happen if you have a blank line (say , only whitepace, but nonzero length) as the last line in your textfield. Adding debugging print statements or using pdb would show you if, for example, the file exists, whether you are actually getting into the readline loop, and what you are actually reading each time through the loop.

techteej

@JonB I set the text field to p_name the line above.

p_name = root_view['namefield'].text
JonB

You need to step through in debugger, or put prints on each line, or think through each scenario.

You are first checking if the textbox is empty.
If so, you set a variable to Player 1, but that variable is never written to the textbox.

Next, you try to read a file. The last line in that file is written to the variable and the textbox. But if the last line contains only white space, you will write whitespace to the text box. You also overwrite whatever used to be in the textbox... Thus once name.txt exists, you will never be able to change the username. Not what you want I think.

Finally, you check if the player name variable is not empty. ... Since you checked and set that In the first step, this if statment is redundant, there is no path through your code where it will end up empty. But then you overwrite whatever was in that variable with the value from the text box... Which could be still empty at this point, if the name.txt didn't contain a name.

I suspect the logic you really want is:
If the textbox is not empty, write the name to a file, then return
If it was empty, check if name.txt exists, fill in the textbox from that file.
You probably want to trim whitespace or check for no whitespace characters.
If the textbox is still empty, then fill in 'Player 1'
return whatever is left. Note the only case where you should write to the file is when the user entered something, hence the return after the first case.

ccc

I updated https://gist.github.com/cclauss/5997f9c653c0c4bf1521 to remove istitle() and to add strip() and to more closely track the logic that @JonB's proposes above.

techteej

@ccc Is there any way you could put this in one function?

ccc

I edited the gist to have a single get_username() function that includes dialog creation, reading and writing.

Two separate read and write functions properly encapsulates the logic of preprocessing and postprocessing a text editing dialog.

The problem with combining them into a single function is that you need to read_username() before you show the TextView to the user and you need to give the user the ability to write_username() only after they have had a chance to change the contents of the TextView.

techteej

@ccc The problem is, I just have a textfield in a menu for Cacti Killer when the menu is presented. No button or anything. I just save whatever the user input is when Play game is pressed or a character is selected.

Larry_Mondello

Ahh... In that case, your View needs a will_close() method.

techteej

@Larry_Mondello could you please explain instead of just telling me that I need a will_close() method?

ccc

https://github.com/cclauss/Pythonista_ui/blob/master/ui_textview_save_on_close.py

Removes the save button and instead does the save on will_close().

techteej

@ccc See here. It still does not work for me. Quite frustrating.

ccc

Five changes proposed on the gist.

500 lines of code... It is time to split this codebase into more than one .py file.

techteej

@ccc Thanks for your help with this. Not exactly 500 yet ;P. Is there any way I can change it so the first time the script is run (and there's no name.txt file yet) that there isn't any text in the textfield?

ccc

Two changes proposed on the gist.

techteej

@Thanks again!