Issue #27477: Convert IDLE search dialogs to using ttk widgets.

This commit is contained in:
Terry Jan Reedy 2016-07-10 20:21:31 -04:00
parent a748032653
commit 6f7b0f577e
6 changed files with 50 additions and 36 deletions

View File

@ -1,7 +1,8 @@
import os import os
import fnmatch import fnmatch
import sys import sys
from tkinter import StringVar, BooleanVar, Checkbutton # for GrepDialog from tkinter import StringVar, BooleanVar
from tkinter.ttk import Checkbutton
from idlelib import searchengine from idlelib import searchengine
from idlelib.searchbase import SearchDialogBase from idlelib.searchbase import SearchDialogBase
# Importing OutputWindow fails due to import loop # Importing OutputWindow fails due to import loop
@ -45,13 +46,10 @@ class GrepDialog(SearchDialogBase):
self.globent = self.make_entry("In files:", self.globvar)[0] self.globent = self.make_entry("In files:", self.globvar)[0]
def create_other_buttons(self): def create_other_buttons(self):
f = self.make_frame()[0] btn = Checkbutton(
self.make_frame()[0], variable=self.recvar,
btn = Checkbutton(f, anchor="w",
variable=self.recvar,
text="Recurse down subdirectories") text="Recurse down subdirectories")
btn.pack(side="top", fill="both") btn.pack(side="top", fill="both")
btn.select()
def create_command_buttons(self): def create_command_buttons(self):
SearchDialogBase.create_command_buttons(self) SearchDialogBase.create_command_buttons(self)
@ -130,7 +128,8 @@ class GrepDialog(SearchDialogBase):
def _grep_dialog(parent): # htest # def _grep_dialog(parent): # htest #
from idlelib.pyshell import PyShellFileList from idlelib.pyshell import PyShellFileList
from tkinter import Toplevel, Text, Button, SEL, END from tkinter import Toplevel, Text, SEL, END
from tkinter.ttk import Button
top = Toplevel(parent) top = Toplevel(parent)
top.title("Test GrepDialog") top.title("Test GrepDialog")
x, y = map(int, parent.geometry().split('+')[1:]) x, y = map(int, parent.geometry().split('+')[1:])

View File

@ -265,6 +265,13 @@ _search_dialog_spec = {
"Click [Close] or [X] to close the 'Search Dialog'." "Click [Close] or [X] to close the 'Search Dialog'."
} }
_searchbase_spec = {
'file': 'searchbase',
'kwds': {},
'msg': "Check the appearance of the base search dialog\n"
"Its only action is to close."
}
_scrolled_list_spec = { _scrolled_list_spec = {
'file': 'scrolledlist', 'file': 'scrolledlist',
'kwds': {}, 'kwds': {},

View File

@ -1,8 +1,7 @@
'''Unittests for idlelib/searchbase.py '''tests idlelib.searchbase.
Coverage: 99%. The only thing not covered is inconsequential -- Coverage: 99%. The only thing not covered is inconsequential --
testing skipping of suite when self.needwrapbutton is false. testing skipping of suite when self.needwrapbutton is false.
''' '''
import unittest import unittest
from test.support import requires from test.support import requires
@ -120,11 +119,6 @@ class SearchDialogBaseTest(unittest.TestCase):
var, label = spec var, label = spec
self.assertEqual(button['text'], label) self.assertEqual(button['text'], label)
self.assertEqual(var.get(), state) self.assertEqual(var.get(), state)
if state == 1:
button.deselect()
else:
button.select()
self.assertEqual(var.get(), 1 - state)
def test_create_other_buttons(self): def test_create_other_buttons(self):
for state in (False, True): for state in (False, True):
@ -140,10 +134,6 @@ class SearchDialogBaseTest(unittest.TestCase):
# hit other button, then this one # hit other button, then this one
# indexes depend on button order # indexes depend on button order
self.assertEqual(var.get(), state) self.assertEqual(var.get(), state)
buttons[val].select()
self.assertEqual(var.get(), 1 - state)
buttons[1-val].select()
self.assertEqual(var.get(), state)
def test_make_button(self): def test_make_button(self):
self.dialog.top = self.root self.dialog.top = self.root
@ -162,6 +152,5 @@ class SearchDialogBaseTest(unittest.TestCase):
self.assertIn('close', closebuttoncommand) self.assertIn('close', closebuttoncommand)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main(verbosity=2, exit=2) unittest.main(verbosity=2, exit=2)

View File

@ -3,7 +3,7 @@ Uses idlelib.SearchEngine for search capability.
Defines various replace related functions like replace, replace all, Defines various replace related functions like replace, replace all,
replace+find. replace+find.
""" """
from tkinter import * from tkinter import StringVar, TclError
from idlelib import searchengine from idlelib import searchengine
from idlelib.searchbase import SearchDialogBase from idlelib.searchbase import SearchDialogBase
@ -204,7 +204,9 @@ class ReplaceDialog(SearchDialogBase):
def _replace_dialog(parent): # htest # def _replace_dialog(parent): # htest #
"""htest wrapper function""" from tkinter import Toplevel, Text
from tkiter.ttk import Button
box = Toplevel(parent) box = Toplevel(parent)
box.title("Test ReplaceDialog") box.title("Test ReplaceDialog")
x, y = map(int, parent.geometry().split('+')[1:]) x, y = map(int, parent.geometry().split('+')[1:])

View File

@ -1,4 +1,4 @@
from tkinter import * from tkinter import TclError
from idlelib import searchengine from idlelib import searchengine
from idlelib.searchbase import SearchDialogBase from idlelib.searchbase import SearchDialogBase
@ -72,7 +72,10 @@ class SearchDialog(SearchDialogBase):
def _search_dialog(parent): # htest # def _search_dialog(parent): # htest #
'''Display search test box.''' "Display search test box."
from tkinter import Toplevel, Text
from tkinter.ttk import Button
box = Toplevel(parent) box = Toplevel(parent)
box.title("Test SearchDialog") box.title("Test SearchDialog")
x, y = map(int, parent.geometry().split('+')[1:]) x, y = map(int, parent.geometry().split('+')[1:])
@ -82,9 +85,9 @@ def _search_dialog(parent): # htest #
text.insert("insert","This is a sample string.\n"*5) text.insert("insert","This is a sample string.\n"*5)
def show_find(): def show_find():
text.tag_add(SEL, "1.0", END) text.tag_add('sel', '1.0', 'end')
_setup(text).open(text) _setup(text).open(text)
text.tag_remove(SEL, "1.0", END) text.tag_remove('sel', '1.0', 'end')
button = Button(box, text="Search (selection ignored)", command=show_find) button = Button(box, text="Search (selection ignored)", command=show_find)
button.pack() button.pack()

View File

@ -1,7 +1,7 @@
'''Define SearchDialogBase used by Search, Replace, and Grep dialogs.''' '''Define SearchDialogBase used by Search, Replace, and Grep dialogs.'''
from tkinter import (Toplevel, Frame, Entry, Label, Button, from tkinter import Toplevel, Frame
Checkbutton, Radiobutton) from tkinter.ttk import Entry, Label, Button, Checkbutton, Radiobutton
class SearchDialogBase: class SearchDialogBase:
'''Create most of a 3 or 4 row, 3 column search dialog. '''Create most of a 3 or 4 row, 3 column search dialog.
@ -137,10 +137,8 @@ class SearchDialogBase:
if self.needwrapbutton: if self.needwrapbutton:
options.append((engine.wrapvar, "Wrap around")) options.append((engine.wrapvar, "Wrap around"))
for var, label in options: for var, label in options:
btn = Checkbutton(frame, anchor="w", variable=var, text=label) btn = Checkbutton(frame, variable=var, text=label)
btn.pack(side="left", fill="both") btn.pack(side="left", fill="both")
if var.get():
btn.select()
return frame, options return frame, options
def create_other_buttons(self): def create_other_buttons(self):
@ -153,11 +151,8 @@ class SearchDialogBase:
var = self.engine.backvar var = self.engine.backvar
others = [(1, 'Up'), (0, 'Down')] others = [(1, 'Up'), (0, 'Down')]
for val, label in others: for val, label in others:
btn = Radiobutton(frame, anchor="w", btn = Radiobutton(frame, variable=var, value=val, text=label)
variable=var, value=val, text=label)
btn.pack(side="left", fill="both") btn.pack(side="left", fill="both")
if var.get() == val:
btn.select()
return frame, others return frame, others
def make_button(self, label, command, isdef=0): def make_button(self, label, command, isdef=0):
@ -178,7 +173,26 @@ class SearchDialogBase:
b = self.make_button("close", self.close) b = self.make_button("close", self.close)
b.lower() b.lower()
class _searchbase(SearchDialogBase): # htest #
"Create auto-opening dialog with no text connection."
def __init__(self, parent):
import re
from idlelib import searchengine
self.root = parent
self.engine = searchengine.get(parent)
self.create_widgets()
print(parent.geometry())
width,height, x,y = list(map(int, re.split('[x+]', parent.geometry())))
self.top.geometry("+%d+%d" % (x + 40, y + 175))
def default_command(self): pass
if __name__ == '__main__': if __name__ == '__main__':
import unittest import unittest
unittest.main( unittest.main('idlelib.idle_test.test_searchbase', verbosity=2, exit=False)
'idlelib.idle_test.test_searchdialogbase', verbosity=2)
from idlelib.idle_test.htest import run
run(_searchbase)