Что вам нужно знать:
"\r"
) line line (LF - в строковых литералах, представленных как "\n"
) System.in
, который читается Scanner
), также отправляет зависимые от ОС разделители строк (например, для Windows \r\n
) после этого. Поэтому, когда вы запрашиваете у пользователя значение типа age
, а пользовательские типы 42 и нажимаете enter, стандартный вход будет содержать "42\r\n"
. Scanner#nextInt
(и другие методы Scanner#nextType
) не позволяют сканеру потреблять эти разделители строк. Он прочитает их из System.in
(как еще Сканер узнает, что больше нет цифр от пользователя, которые представляют age
значение, чем перед пробелом?), Который удалит их со стандартного ввода, но он также будет кешем эти разделители строк внутри. Нам нужно помнить, что все методы Scanner всегда сканируются, начиная с кэшированного текста.
Теперь Scanner#nextLine()
просто собирает и возвращает все символы , пока не найдет разделители строк (или конец потока). Но поскольку разделители строк после прочтения номера из консоли сразу обнаруживаются в кеше сканера, он возвращает пустую строку, что означает, что сканер не смог найти символ до этих разделителей строк (или конца потока). BTW nextLine
также потребляет эти разделители строк.
Поэтому, когда вы хотите запросить номер, а затем для всей строки, избегая этой пустой строки в результате nextLine
, либо
nextInt
из кеша сканеров, вызывая nextLine
, или вызывая skip("\\R")
, чтобы позволить Scanner пропускать часть, сопоставляемую с \R
, которая представляет разделитель строк (подробнее о \R
: https : //stackoverflow.com/a/31060125 ) nextInt
(ни next
, ни какие-либо методы nextTYPE
). Вместо этого прочитайте целые строки данных по строке nextLine
и номера разбора из каждой строки (при условии, что одна строка содержит только одно число) для правильного типа, например int
, через Integer.parseInt
. BTW: Scanner#nextType
методы могут пропускать разделители (по умолчанию все пробелы, такие как вкладки, разделители строк), в том числе кэшированные сканером, пока они не найдут следующее значение без разделителя (токен). Благодаря этому для ввода типа "42\r\n\r\n321\r\n\r\n\r\nfoobar"
код
int num1 = sc.nextInt();
int num2 = sc.nextInt();
String name = sc.next();
сможет правильно назначить num1=42
num2=321
name=foobar
.
Функции grid
, pack
и place
объекта Entry
и всех других виджетов возвращают None
. В python, когда вы делаете a().b()
, результат выражения - это то, что возвращает b()
, поэтому Entry(...).grid(...)
вернет None
.
Вы должны разделить это на две строки следующим образом:
entryBox = Entry(root, width=60)
entryBox.grid(row=2, column=1, sticky=W)
Таким образом вы получите свою Entry
ссылку, сохраненную в entryBox
, и она выложена, как вы ожидаете. Это имеет бонусный побочный эффект, заключающийся в том, что ваш макет легче понять и поддерживать, если вы собираете все свои grid
и / или pack
операторы в блоках.
Измените эту строку:
entryBox=Entry(root,width=60).grid(row=2, column=1,sticky=W)
в эти две строки:
entryBox=Entry(root,width=60)
entryBox.grid(row=2, column=1,sticky=W)
То же самое касается label
, кстати, как вы уже правильно сделали для grabBtn
!