def conductTrial(label, items):
    samples = 128
    n = len(items)
    rt = RTree(m=2, M=4)
    for r in items:
        rt.add(r)

    box = rt.root.region
    width = box.x_max - box.x_min
    height = box.y_max - box.y_min

    # can compute density for any tree, samples at 128 random spots
    ct = 0
    for _ in range(samples):
        x = box.x_min + random.random() * width
        y = box.y_min + random.random() * height
        for triple in rt.range(Region(x, y, x, y)):
            assert triple[2] == False
            ct += 1

    print("Density", n, "{:.2f}%".format(100 * ct / (n * samples)), "intersect random point in ", str(box))

    trials(n, items, BUILD, "Build")
    trials(n, items, SEARCH, "Search")
    trials(n, items, DELETE, "Delete")
Exemple #2
0
def conductTrial(label, items):
    samples = 128
    n = len(items)
    rt = RTree(m=2, M=4)
    for r in items:
        rt.add(r)

    box = rt.root.region
    width = box.x_max - box.x_min
    height = box.y_max - box.y_min

    # can compute density for any tree, samples at 128 random spots
    ct = 0
    for _ in range(samples):
        x = box.x_min + random.random() * width
        y = box.y_min + random.random() * height
        for triple in rt.range(Region(x, y, x, y)):
            assert (triple[2] == False)
            ct += 1

    print("Density", n, "{:.2f}%".format(100 * ct / (n * samples)),
          "intersect random point in ", str(box))

    trials(n, items, BUILD, "Build")
    trials(n, items, SEARCH, "Search")
    trials(n, items, DELETE, "Delete")
    def __init__(self):
        """App for creating R tree dynamically and executing range queries"""

        self.tree = RTree(m=2, M=4)
        self.ready = False

        # for range query
        self.selectedRegion = None
        self.newRegionStart = None
        self.newRegion = None

        # for identifiers
        self.counter = 0

        self.master = tkinter.Tk()
        self.master.title('R Tree Range Query Application')
        self.w = tkinter.Frame(self.master, width=512, height=512)
        self.canvas = tkinter.Canvas(self.w, width=512, height=512)

        self.paint()

        self.canvas.bind("<Button-1>", self.startAdd)
        self.canvas.bind("<B1-Motion>",
                         self.extendAdd)  # only when right mouse dragged
        self.canvas.bind("<ButtonRelease-1>", self.endAdd)

        self.canvas.bind("<Button-3>", self.range)  # when right mouse clicked
        self.canvas.bind("<ButtonRelease-3>", self.clear)
        self.canvas.bind("<B3-Motion>",
                         self.range)  # only when right mouse dragged
        self.w.pack()
    def __init__(self):
        """App for creating R tree dynamically and executing range queries"""
        
        self.tree = RTree(m=2, M=4)
        self.ready = False
        
        # for range query
        self.selectedRegion = None
        self.newRegionStart = None
        self.newRegion      = None
        
        # for identifiers
        self.counter = 0
        
        self.master = tkinter.Tk()
        self.master.title('R Tree Range Query Application')
        self.w = tkinter.Frame(self.master, width=512, height=512)
        self.canvas = tkinter.Canvas(self.w, width=512, height=512)        
                        
        self.paint()

        self.canvas.bind("<Button-1>", self.startAdd)
        self.canvas.bind("<B1-Motion>", self.extendAdd)  # only when right mouse dragged
        self.canvas.bind("<ButtonRelease-1>", self.endAdd)
        
        self.canvas.bind("<Button-3>", self.range)   # when right mouse clicked
        self.canvas.bind("<ButtonRelease-3>", self.clear)
        self.canvas.bind("<B3-Motion>", self.range)  # only when right mouse dragged
        self.w.pack()
Exemple #5
0
 def test_multipleM(self):
     # check multiple m,M values
     
     for m,M in zip([3, 4, 5, 6], [7, 8, 10, 13]):
         self.tree = RTree(m,M)
         regions = []
         for ctr in range(500):
             r = Region(2*random.randint(2,250), 2*random.randint(2,250), 2*random.randint(2,250), 2*random.randint(2,250))
             regions.append((r, ctr))
             self.tree.add(r,ctr)
             
         # make sure all can be individually found
         for ctr in range(len(regions)):
             match = [m for m in self.tree.search(regions[ctr][0])][0]
             self.assertEquals(match, regions[ctr][0])
             
         # make sure that all are contained within the 
         self.ensure_maxBounding(self.tree.root)
def performanceR():
    """Demonstrate RTree stores all rectangles."""
    n = 1024
    while n <= 131072:
        rt = RTree()
        added = []
        for _ in range(n):
            new = randomRectangle()
            if rt.search(new) is None:
                rt.add(new)
                added.append(new)

        random.shuffle(added)
        
        for r in added:
            if rt.search(r) is None:
                print ("Cannot find:" + r)
                assert False
            
        print ("pass " + str(n))

        n *= 2
def performanceR():
    """Demonstrate RTree stores all rectangles."""
    n = 1024
    while n <= 131072:
        rt = RTree()
        added = []
        for _ in range(n):
            new = randomRectangle()
            if rt.search(new) is None:
                rt.add(new)
                added.append(new)

        random.shuffle(added)

        for r in added:
            if rt.search(r) is None:
                print("Cannot find:" + r)
                assert False

        print("pass " + str(n))

        n *= 2
class RTreeApp:
    
    def __init__(self):
        """App for creating R tree dynamically and executing range queries"""
        
        self.tree = RTree(m=2, M=4)
        self.ready = False
        
        # for range query
        self.selectedRegion = None
        self.newRegionStart = None
        self.newRegion      = None
        
        # for identifiers
        self.counter = 0
        
        self.master = tkinter.Tk()
        self.master.title('R Tree Range Query Application')
        self.w = tkinter.Frame(self.master, width=512, height=512)
        self.canvas = tkinter.Canvas(self.w, width=512, height=512)        
                        
        self.paint()

        self.canvas.bind("<Button-1>", self.startAdd)
        self.canvas.bind("<B1-Motion>", self.extendAdd)  # only when right mouse dragged
        self.canvas.bind("<ButtonRelease-1>", self.endAdd)
        
        self.canvas.bind("<Button-3>", self.range)   # when right mouse clicked
        self.canvas.bind("<ButtonRelease-3>", self.clear)
        self.canvas.bind("<B3-Motion>", self.range)  # only when right mouse dragged
        self.w.pack()
        
    def startAdd(self, event):
        """End of range search."""
        x = event.x
        y = self.toCartesian(event.y)
        self.newRegionStart = (x,y)
        
    def extendAdd(self, event):
        """End of range search."""
        if self.newRegionStart:
            x = event.x
            y = self.toCartesian(event.y)
            
            self.newRegion = Region (x,y,x,y).unionPoint(self.newRegionStart) 
            
            self.paint()
        
    def endAdd(self, event):
        """End of range search."""
        if self.newRegionStart:
            self.newRegionStart = None
            self.counter += 1
            
            if self.newRegion:
                self.tree.add(self.newRegion, str(self.counter))
                
            self.newRegion = None
            self.paint()

    def toCartesian(self, y):
        """Convert tkinter point into Cartesian."""
        return self.w.winfo_height() - y

    def toTk(self,y):
        """Convert Cartesian into tkinter point."""
        if y == maxValue: return 0
        tk_y = self.w.winfo_height()
        if y != minValue:
            tk_y -= y
        return tk_y
         
    def clear(self, event):
        """End of range search."""
        self.selectedRegion = None
        self.paint()
        
    def range(self, event):
        """Initiate a range search using a selected rectangular region."""
        
        p = (event.x, self.toCartesian(event.y))
         
        if self.selectedRegion is None:
            self.selectedStart = Region(p[X],p[Y],  p[X],p[Y])
        self.selectedRegion = self.selectedStart.unionPoint(p)
        
        self.paint()
        
        # return (node,0,True) where status is True if draining entire tree rooted at node. If False,
        # then (rect,id,False). Draw these
        # as shaded red rectangle to identify whole sub-tree is selected.
        for triple in self.tree.range(self.selectedRegion):
            if triple[2]:
                r = triple[0].region
                self.canvas.create_rectangle(r.x_min, self.toTk(r.y_min), r.x_max, self.toTk(r.y_max),
                                             fill='Red', stipple='gray12')
            else:
                r = triple[0]
                self.canvas.create_rectangle(r.x_min, self.toTk(r.y_min), r.x_max, self.toTk(r.y_max), 
                                             fill='Red')
        
    def click(self, event):
        """Add point to KDtree."""
        p = (event.x, self.toCartesian(event.y))
        
        self.tree.add(p)
             
        self.paint()

    def visit (self, n):
        """ Visit node to paint properly."""
        if n == None: return

        if n.level == 0:
            for idx in range(n.count):
                r = n.children[idx].region
                self.canvas.create_rectangle(r.x_min, self.toTk(r.y_min), r.x_max, self.toTk(r.y_max),
                                     fill='Gray')    
            
        for idx in range(n.count):
            self.visit(n.children[idx])

        # Do after all children so we can see interior nodes, too.
        r = n.region
        self.canvas.create_rectangle(r.x_min, self.toTk(r.y_min), r.x_max, self.toTk(r.y_max),
                                     outline='Black', dash=(2, 4))
        color = 'Gray'
        if n.level == 0:
            color='Black'  
        self.canvas.create_text(r.x_max - 16*len(n.id), self.toTk(r.y_max) + 16, anchor = tkinter.W, 
                                font = "Times 16 bold", fill=color, text=n.id)

    def prepare(self, event):
        """prepare to add points."""
        if self.label:
            self.label.destroy()
            self.label = None
            self.canvas.pack()
        
    def paint(self):
        """Paint R tree by visiting all nodes, or show introductory message."""
        if self.ready:
            self.canvas.delete(tkinter.ALL)
            self.visit(self.tree.root)
            
            if self.newRegion:
                self.canvas.create_rectangle(self.newRegion.x_min, self.toTk(self.newRegion.y_min),
                                         self.newRegion.x_max, self.toTk(self.newRegion.y_max), 
                                         outline='Black', dash=(2, 4))
                
            if self.selectedRegion:
                self.canvas.create_rectangle(self.selectedRegion.x_min, self.toTk(self.selectedRegion.y_min),
                                         self.selectedRegion.x_max, self.toTk(self.selectedRegion.y_max), 
                                         outline='Red', dash=(2, 4))
        else:
            self.label = tkinter.Label(self.w, width=100, height = 40, text="Click To Add Points")
            self.label.bind("<Button-1>", self.prepare)
            self.label.pack()
            self.ready = True
Exemple #9
0
class TestRMethods(unittest.TestCase):

    def setUp(self):
        self.tree = RTree()
        
    def tearDown(self):
        self.tree = None
        
    def test_basic(self):
        r = Region(10,20,50,60)
        
        self.tree.add(r, 99)
                         
        for node,_,status in self.tree.range(r):
            self.assertTrue(status)
            for rect, ident in node.leafOrder():
                self.assertEquals(99, ident)
                self.assertEquals(r, rect)

    # Expanded region for node with multiple insertions.
    def test_expand(self):
        r = Region(10,20,50,60)
        r2 = Region(30,60,70,80)
                
        self.tree.add(r, 99)
        self.tree.add(r2, 101)
                         
        self.assertEquals(Region(10,20,70,80), self.tree.root.region)
        
    # Add five regions and watch split.
    def test_split(self):
        r1 = Region(10,20,50,60)
        r2 = Region(30,60,70,80)
        r3 = Region(-30,60,70,80)
        r4 = Region(40,70,60,100)
           
        self.tree.add(r1, 99)
        self.tree.add(r2, 101)
        self.tree.add(r3, 103)
        self.tree.add(r4, 105)
        
        self.assertEquals(Region(-30,20,70,100), self.tree.root.region)
        
        r5 = Region(10,60,0,90)
        
        self.tree.add(r5, 107)

        self.assertEquals(Region(-30,20,70,100), self.tree.root.region)
        
        # finds all rectangles.
        r_ids = []
        for triple in self.tree.range(Region(-100, -100, 200, 200)):
            if triple[2]:
                for d in triple[0].leafOrder():
                    r_ids.append(d[1])
            else:
                r_ids.append(triple[1])
        r_ids.sort()
        self.assertEquals ([99,101,103,105,107], r_ids)
     
    def expand(self, region):
        """When Full Sub-trees returned as nodes traverse to expand nodes."""
        result = [p for p in self.tree.range(region)]
        expanded = []
        for triple in result:
            if triple[2]:
                for d in triple[0].leafOrder():
                    expanded.append(d[0])
            else:
                expanded.append(triple[0])
                
        return expanded
       
    def test_iterator(self):
        # rectangles have all even numbered coordinates
        for _ in range(500):
            self.tree.add(Region(2*random.randint(2,250), 2*random.randint(2,250), 2*random.randint(2,250), 2*random.randint(2,250)))
        
        count = 0
        for _ in self.tree:
            count = count + 1
        self.assertEquals(500, count)
       
    def test_adding(self):
        # rectangles have all even numbered coordinates. Doesn't really matter since
        # range returns regions that intersect target, rather than being wholly contained
        for _ in range(500):
            self.tree.add(Region(2*random.randint(2,250), 2*random.randint(2,250), 2*random.randint(2,250), 2*random.randint(2,250)))
        
        # make sure not to overlap!
        q_ne = self.expand(Region(125, 125, 501, 501))
        q_nw = self.expand(Region(1, 125, 125, 501))
        q_sw = self.expand(Region(1, 1, 125, 125))
        q_se = self.expand(Region(125, 1, 511, 125))
        
        q_all = self.expand(Region(1,1, 501, 501))
        
        # quick check to see if any were missing
        combined = []
        for r in q_ne + q_nw + q_sw + q_se:
            if r not in combined:
                combined.append(r)

        for q in q_all:
            if q not in combined:
                print (q, " missing ")
                
        # check duplicates
        for i in range(len(combined)):
            for j in range(len(combined)):
                if j <= i:
                    pass
                else:
                    if combined[i] == combined[j]:
                        print ("Duplicate:", combined[i])
        
        self.assertEquals(len(q_all), len(combined))
                
    def ensure_maxBounding(self, node):
        """Ensures R-Node guarantees max bounding rectangle for all interior nodes covers descendants."""
        for i in range(node.count):
            n = node.children[i]
            self.assertTrue(node.region.containsRegion(n.region))
            self.ensure_maxBounding(n)
                
    def test_verticalSlices(self):
        # check case of vertical rectangles all in a row. This forces regular extensions.
        # Make sure bounding rectangles are computed properly.
        for x in range(1,50):
            self.tree.add(Region(x*6,10, x*6+3,100))
            
        # sliding window always grabs eight of them since there is one rect every 6 pixels and query width is 47
        for x in range(1, 40):
            s = Region(x*6, 2, x*6+47, 100)
            match = self.expand(s)
            
            self.assertEquals(8, len(match))
        
        self.ensure_maxBounding(self.tree.root)
        
    def test_tiling(self):
        # create evenly placed rectangles (s=16_ and validate queries
        for x in range(1,8):
            for y in range(1,8):
                self.tree.add(Region(x*64,y*64, x*64+32,y*64+32))
    
        for x in range(1,5):
            for y in range(1,5):
                s = Region(x*64, y*64, x*64+255, y*64+127)   # includes 2x4 selection or 8
                match = self.expand(s)
            
                self.assertEquals(8, len(match))
        
    def test_multipleM(self):
        # check multiple m,M values
        
        for m,M in zip([3, 4, 5, 6], [7, 8, 10, 13]):
            self.tree = RTree(m,M)
            regions = []
            for ctr in range(500):
                r = Region(2*random.randint(2,250), 2*random.randint(2,250), 2*random.randint(2,250), 2*random.randint(2,250))
                regions.append((r, ctr))
                self.tree.add(r,ctr)
                
            # make sure all can be individually found
            for ctr in range(len(regions)):
                match = [m for m in self.tree.search(regions[ctr][0])][0]
                self.assertEquals(match, regions[ctr][0])
                
            # make sure that all are contained within the 
            self.ensure_maxBounding(self.tree.root)
                
    # test deletions
    def test_deleteOnlyOne(self):
        r = Region(10,20,50,60)
                
        self.tree.add(r, 99)
                         
        self.assertTrue(self.tree.search(r))
        self.assertEquals(Region(10,20,50,60), self.tree.root.region)
        
        # not in tree.
        self.assertFalse(self.tree.remove(Region(2,4,22,50)))
        
        self.assertTrue(self.tree.remove(r))

        # Not present.
        self.assertTrue(self.tree.search(r) is None)
                
    # test deletions
    def test_delete(self):
        r = Region(10,20,50,60)
        r2 = Region(30,60,70,80)
                
        self.tree.add(r, 99)
        self.tree.add(r2, 101)
                         
        self.assertTrue(self.tree.search(r))
        self.assertTrue(self.tree.search(r2))
        self.assertEquals(Region(10,20,70,80), self.tree.root.region)
        
        # not in tree.
        self.assertFalse(self.tree.remove(Region(2,4,22,50)))
        
        self.assertTrue(self.tree.remove(r2))

        # one is in, other is out
        self.assertTrue(self.tree.search(r))
        self.assertTrue(self.tree.search(r2) is None)
        
    def test_deleteFive(self):
        r1 = Region(38,148  , 300,288)
        r2 = Region(164,384 , 432,428)
        r3 = Region(316,342 , 456,392)
        r4 = Region(12,242  , 172,484)
        r5 = Region(324,200 , 494,276)
        for r in [r1,r2,r3,r4,r5]:
            self.tree.add(r)
            
        for r in [r1,r2,r3,r4,r5]:
            self.assertTrue(self.tree.search(r))
            self.tree.remove(r)
            self.assertFalse(self.tree.search(r))
            
        self.assertTrue (self.tree.root == None)
        
    def test_deleteThirteen(self):
        r1 = Region(410,168 , 482,348)
        r2 = Region(136,236 , 250,266)
        r3 = Region(290,26 , 496,470)   ## FAILS when deleting 10
        r4 = Region(398,24 , 444,100)
        r5 = Region(160,388 , 462,480)
        r6 = Region(50,124 , 120,486)
        r7 = Region(22,258 , 144,322)
        r8 = Region(28,148 , 392,236)
        r9 = Region(78,190 , 174,370)   #  problem on this one
        r10 = Region(38,142 , 232,184)   
        r11 = Region(52,346 , 52,424)
        r12 = Region(70,120 , 248,400)
        r13 = Region(274,368 , 444,370)   
        for r in [r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13]:
            self.tree.add(r)
            
        for r in [r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13]:
            self.assertTrue(self.tree.search(r))
            self.tree.remove(r)
            self.assertFalse(self.tree.search(r))
            
        self.assertTrue (self.tree.root == None)
        
    def test_multipleDeletions(self):
        # rectangles have all even numbered coordinates
        added = []
        for _ in range(4096):
            r = Region(2*random.randint(2,250), 2*random.randint(2,250), 2*random.randint(2,250), 2*random.randint(2,250))
            self.tree.add(r)
            added.append(r)
        
        print (self.tree.root.level)
        random.shuffle(added)
        for r in added:
            self.assertTrue(self.tree.search(r))
            self.tree.remove(r)
            self.assertFalse(self.tree.search(r))
       
        # once done, R-Tree is empty once again
        ct = 0
        for _ in self.tree:
            ct += 1
        self.assertEquals (0, ct)
Exemple #10
0
 def setUp(self):
     self.tree = RTree()
Exemple #11
0
class RTreeApp:
    def __init__(self):
        """App for creating R tree dynamically and executing range queries"""

        self.tree = RTree(m=2, M=4)
        self.ready = False

        # for range query
        self.selectedRegion = None
        self.newRegionStart = None
        self.newRegion = None

        # for identifiers
        self.counter = 0

        self.master = tkinter.Tk()
        self.master.title('R Tree Range Query Application')
        self.w = tkinter.Frame(self.master, width=512, height=512)
        self.canvas = tkinter.Canvas(self.w, width=512, height=512)

        self.paint()

        self.canvas.bind("<Button-1>", self.startAdd)
        self.canvas.bind("<B1-Motion>",
                         self.extendAdd)  # only when right mouse dragged
        self.canvas.bind("<ButtonRelease-1>", self.endAdd)

        self.canvas.bind("<Button-3>", self.range)  # when right mouse clicked
        self.canvas.bind("<ButtonRelease-3>", self.clear)
        self.canvas.bind("<B3-Motion>",
                         self.range)  # only when right mouse dragged
        self.w.pack()

    def startAdd(self, event):
        """End of range search."""
        x = event.x
        y = self.toCartesian(event.y)
        self.newRegionStart = (x, y)

    def extendAdd(self, event):
        """End of range search."""
        if self.newRegionStart:
            x = event.x
            y = self.toCartesian(event.y)

            self.newRegion = Region(x, y, x, y).unionPoint(self.newRegionStart)

            self.paint()

    def endAdd(self, event):
        """End of range search."""
        if self.newRegionStart:
            self.newRegionStart = None
            self.counter += 1

            if self.newRegion:
                self.tree.add(self.newRegion, str(self.counter))

            self.newRegion = None
            self.paint()

    def toCartesian(self, y):
        """Convert tkinter point into Cartesian."""
        return self.w.winfo_height() - y

    def toTk(self, y):
        """Convert Cartesian into tkinter point."""
        if y == maxValue: return 0
        tk_y = self.w.winfo_height()
        if y != minValue:
            tk_y -= y
        return tk_y

    def clear(self, event):
        """End of range search."""
        self.selectedRegion = None
        self.paint()

    def range(self, event):
        """Initiate a range search using a selected rectangular region."""

        p = (event.x, self.toCartesian(event.y))

        if self.selectedRegion is None:
            self.selectedStart = Region(p[X], p[Y], p[X], p[Y])
        self.selectedRegion = self.selectedStart.unionPoint(p)

        self.paint()

        # return (node,0,True) where status is True if draining entire tree rooted at node. If False,
        # then (rect,id,False). Draw these
        # as shaded red rectangle to identify whole sub-tree is selected.
        for triple in self.tree.range(self.selectedRegion):
            if triple[2]:
                r = triple[0].region
                self.canvas.create_rectangle(r.x_min,
                                             self.toTk(r.y_min),
                                             r.x_max,
                                             self.toTk(r.y_max),
                                             fill='Red',
                                             stipple='gray12')
            else:
                r = triple[0]
                self.canvas.create_rectangle(r.x_min,
                                             self.toTk(r.y_min),
                                             r.x_max,
                                             self.toTk(r.y_max),
                                             fill='Red')

    def click(self, event):
        """Add point to KDtree."""
        p = (event.x, self.toCartesian(event.y))

        self.tree.add(p)

        self.paint()

    def visit(self, n):
        """ Visit node to paint properly."""
        if n == None: return

        if n.level == 0:
            for idx in range(n.count):
                r = n.children[idx].region
                self.canvas.create_rectangle(r.x_min,
                                             self.toTk(r.y_min),
                                             r.x_max,
                                             self.toTk(r.y_max),
                                             fill='Gray')

        for idx in range(n.count):
            self.visit(n.children[idx])

        # Do after all children so we can see interior nodes, too.
        r = n.region
        self.canvas.create_rectangle(r.x_min,
                                     self.toTk(r.y_min),
                                     r.x_max,
                                     self.toTk(r.y_max),
                                     outline='Black',
                                     dash=(2, 4))
        color = 'Gray'
        if n.level == 0:
            color = 'Black'
        self.canvas.create_text(r.x_max - 16 * len(n.id),
                                self.toTk(r.y_max) + 16,
                                anchor=tkinter.W,
                                font="Times 16 bold",
                                fill=color,
                                text=n.id)

    def prepare(self, event):
        """prepare to add points."""
        if self.label:
            self.label.destroy()
            self.label = None
            self.canvas.pack()

    def paint(self):
        """Paint R tree by visiting all nodes, or show introductory message."""
        if self.ready:
            self.canvas.delete(tkinter.ALL)
            self.visit(self.tree.root)

            if self.newRegion:
                self.canvas.create_rectangle(self.newRegion.x_min,
                                             self.toTk(self.newRegion.y_min),
                                             self.newRegion.x_max,
                                             self.toTk(self.newRegion.y_max),
                                             outline='Black',
                                             dash=(2, 4))

            if self.selectedRegion:
                self.canvas.create_rectangle(
                    self.selectedRegion.x_min,
                    self.toTk(self.selectedRegion.y_min),
                    self.selectedRegion.x_max,
                    self.toTk(self.selectedRegion.y_max),
                    outline='Red',
                    dash=(2, 4))
        else:
            self.label = tkinter.Label(self.w,
                                       width=100,
                                       height=40,
                                       text="Click To Add Points")
            self.label.bind("<Button-1>", self.prepare)
            self.label.pack()
            self.ready = True