-1

I am trying to have a Tkinter gui with 4 boxes that will let me add users to Centos7.

If it was a dialog using raw input it works fine but when i try to get the input from the entry fields it doesnt.

I saw other related subprocess questions but none of them used Entry frields which confuse me.

I get an error of argument is not iterable but i am sure maybe the way i declare the variables is probably wrong and the way i input into the subprocess entry the oucu,name,group fields.

Any ideas ?

from tkinter import *

import subprocess


global oucu
global fname
global sname
global group

def add():
    subprocess.call(['adduser', '-N', '-g', group, '-c', fname, '-d','/home/oucu'])



root = Tk()
oucu = StringVar()
e2 = Entry(root, textvariable=oucu).grid(row=0, column=0)
fname = StringVar()
e3 = Entry(root, textvariable=fname).grid(row=1, column=0)
sname = StringVar()
e4 = Entry(root, textvariable=sname).grid(row=1, column=1)
group = StringVar()
e6 = Entry(root, textvariable=group).grid(row=0, column=1)
b1 = Button(root, text='Next', command=add).grid(row=2, column=1)

root.mainloop()
Geo
  • 21
  • 5
  • why are you defining global outside of the function? Try using `get()`. Example `group.get()` instead of just group in your `subprocess.call`. – Mike - SMT Mar 07 '18 at 15:42
  • if i define them inside the function will the main window pick up the globals? – Geo Mar 07 '18 at 15:46
  • The main GUI has been written inside of the global name space so you do not need to define them. Also global really is not needed here at all they can be removed. – Mike - SMT Mar 07 '18 at 15:47
  • @Geo Yes. Also it's redundant to declare them as globals in the global scope. – Nae Mar 07 '18 at 15:47
  • thank you will give it a go and come back in a bit. one more thing since i am new in python, the way i declare the variables oucu,fname,sname,group as StringVar()can it be done in another easier way or less lines if that makes sense? – Geo Mar 07 '18 at 15:50
  • 1
    Yes it can be reduced to just a `get()` method. I have provided an updated code as an answer. – Mike - SMT Mar 07 '18 at 15:56

2 Answers2

1

You will need to use the get() method here to get the value of the StringVar. You do not need to define global variables in this case at all but I would like to point out defining them in the global name space does nothing here. The variables already exist in the global space as written.

Try this instead.

from tkinter import *
import subprocess

def add():
    subprocess.call(['adduser', '-N', '-g', group.get(), '-c', fname.get(), '-d','/home/oucu'])

root = Tk()
oucu = StringVar()
e2 = Entry(root, textvariable=oucu).grid(row=0, column=0)
fname = StringVar()
e3 = Entry(root, textvariable=fname).grid(row=1, column=0)
sname = StringVar()
e4 = Entry(root, textvariable=sname).grid(row=1, column=1)
group = StringVar()
e6 = Entry(root, textvariable=group).grid(row=0, column=1)
b1 = Button(root, text='Next', command=add).grid(row=2, column=1)

root.mainloop()

However you do not really need StringVar() at all here. You can use get() directly on the Entry field itself. You will need to changed the grid() to be defined on a new row for each entry field but I think it is a cleaner option.

The reason for moving the grid() to a new line is to prevent the grid manager from returning None when using get() on that entry widget.

Try this.

from tkinter import *
import subprocess

def add():
    subprocess.call(['adduser', '-N', '-g', e6.get(), '-c', e3.get(), '-d','/home/oucu'])

root = Tk()
e2 = Entry(root)
e2.grid(row=0, column=0) # needs to be on new line so `get()` can return a value.
e3 = Entry(root)
e3.grid(row=1, column=0)
e4 = Entry(root)
e4.grid(row=1, column=1)
e6 = Entry(root)
e6.grid(row=0, column=1)
b1 = Button(root, text='Next', command=add).grid(row=2, column=1)

root.mainloop()

As Nae has pointed out in the comments StringVar is rarely needed and you may benifit from reading the Q/A on the matter here: When to use Variable Classes?

Mike - SMT
  • 14,784
  • 4
  • 35
  • 79
  • 1
    I was just preparing my own answer suggesting to lose `StringVar` objects. See [When to use Variable Classes?](https://stackoverflow.com/q/47334885/7032856). – Nae Mar 07 '18 at 16:03
  • 1
    @Nae good ol Bryan. His is one of the most active on Tkinter threads and very very helpful in the details. – Mike - SMT Mar 07 '18 at 16:05
  • I have done the edits thank you both, the script when run doesn't provide an error but doesn't create a user at the same time, am i missing something ? – Geo Mar 07 '18 at 16:44
  • @Geo I am not sure as I cannot run that subprocess on my work PC at the moment to test it. I will have to check when I get home. That being said the error you were getting is fixed now and you should probably ask a new question for your new problem. – Mike - SMT Mar 07 '18 at 16:51
  • True and thank you again Mike hope you will see the new Question - How do i close this topic :( Can't see the option or i might be the 10 hours staring at code :) – Geo Mar 07 '18 at 18:09
  • 1
    @Geo You don't "Close" once you have an answer. Instead you select the answer that best solved the problem related to your question by clicking the check box next to the answer. – Mike - SMT Mar 07 '18 at 18:18
  • thanks man i think i have done it and please if you get a minute to run the process and have any idea why it won't add a user let me know as i have to wait 2 days to post again. Appreciate the help – Geo Mar 07 '18 at 19:09
  • @Geo I will take a look tonight at the problem. If I can reproduce the issue I will work on it. – Mike - SMT Mar 07 '18 at 19:11
0

I have done as you said Mike thank you and Nae for your help so far.

The script doesn't error now but it doesn't create a user account to the specified directory, am i missing something important as to why it doesn't fail or add a user account on the system.

from tkinter import *
import subprocess

def add():
subprocess.call(['adduser', '-N', '-g', e6.get(), '-c', e3.get(), '-d','/home/e2.get()'])

root = Tk()
e2 = Entry(root)
e2.grid(row=1, column=1) 
e3 = Entry(root)
e3.grid(row=2, column=1)
e4 = Entry(root)
e4.grid(row=3, column=1)
e6 = Entry(root)
e6.grid(row=4, column=1)
b1 = Button(root, text='Next', command=add).grid(row=5, column=1)
l1 = Label(root, text="Oucu").grid(row=1, column=0)
l2 = Label(root, text="Name").grid(row=2, column=0)
l3 = Label(root, text="Surname").grid(row=3, column=0)
l4 = Label(root, text="Group").grid(row=4, column=0)

root.mainloop()
Geo
  • 21
  • 5