title: Unable to initialize a window and wait for a process to end in Python 3 + GTK+ 3
body: <p>I'm new to object-oriented programming, Python and GTK+3, though I have a decent knowledge of procedural programming (mainly C).</p>
  <p>I'm trying to build a simple Python + GTK+ 3 script to run <code>pkexec apt-get update</code> under Linux.</p>
  <p>I have a <code>mainWindow</code> class (based on a <code>Gtk.Window</code> class) which contains a button object named <code>button</code> (based on a <code>Gtk.Button</code> class) which triggers a <code>new_update_window()</code> method defined in <code>mainWindow</code> upon a <code>clicked</code> event;</p>
  <p>The <code>new_update_window()</code> method initializes an <code>updateWindow</code> object from an <code>updateWindow</code> class (based on a <code>Gtk.Window</code> class) which contains a label object named <code>label</code> (based on a <code>Gtk.Label</code> class) and calls the methods <code>show_all()</code> and <code>update()</code> defined in <code>updateWindow</code>;</p>
  <p>The <code>update()</code> method is supposed to change <code>label</code>, run <code>pkexec apt-get update</code> and change <code>label</code> again.</p>
  <p>The problem is no matter what I do one of the following occurs:</p>
  <ul>
  <li>If I run <code>subprocess.Popen([&quot;/usr/bin/pkexec&quot;, &quot;/usr/bin/apt-get&quot;, &quot;update&quot;])</code> directly, <code>update.Window</code> is shown but <code>label</code> is set immediately to the value it should be set only after <code>pkexec apt-get update</code> has finished executing;</li>
  <li>If I run <code>subprocess.call([&quot;/usr/bin/pkexec&quot;, &quot;/usr/bin/apt-get&quot;, &quot;update&quot;])</code> directly, <code>update.Window</code> is not shown until <code>pkexec apt-get update</code> has finished executing;</li>
  <li>I tried <code>import</code>ing <code>threading</code>, defining a separate <code>run_update()</code> method in <code>updateWindow</code> and start the function in a separate thread using <code>thread = threading.Thread(target=self.run_update)</code>, <code>thread.start()</code>, <code>thread.join()</code>, but still depending on which method I call in <code>run_update()</code> (<code>subprocess.call()</code> or <code>subprocess.Popen</code>) the relative behavior described above exhibits.</li>
  </ul>
  <h1>Tl;dr</h1>
  <p>I'm at a loss to understand how to accomplish what I'm after, which is:</p>
  <ol>
  <li>Showing <code>updateWindow</code> (<code>Gtk.Window</code>)</li>
  <li>Updating <code>label</code> (<code>Gtk.Label</code>) in <code>updateWindow</code></li>
  <li>Running <code>pkexec apt-get update</code></li>
  <li>Updating <code>label</code> in <code>updateWindow</code></li>
  </ol>
  <ul>
  <li><code>subprocess.Popen()</code>: <code>update.Window</code> is shown but <code>label</code> is set immediately to the value it should be set only after <code>pkexec apt-get update</code> has finished executing;</li>
  <li><code>subprocess.call()</code>: <code>update.Window</code> is not shown until <code>pkexec apt-get update</code> has finished executing;</li>
  <li>Wrapping either of the two in function and run the function in a separate thread doesn't change anything.</li>
  </ul>
  <p>Here's the code;</p>
  <p>Not using a thread (case 1, in this case using <code>subprocess.Popen()</code>):</p>
  <pre class="lang-py prettyprint-override"><code>#!/usr/bin/python3
  from gi.repository import Gtk
  import subprocess
  
  class mainWindow(Gtk.Window):
  
      def __init__(self):
          Gtk.Window.__init__(self, title = &quot;Updater&quot;)
  
          button = Gtk.Button()
          button.set_label(&quot;Update&quot;)
          button.connect(&quot;clicked&quot;, self.new_update_window)
          self.add(button)
  
      def new_update_window(self, button):
          update = updateWindow()
          update.show_all()
          update.update()
  
  class updateWindow(Gtk.Window):
  
      def __init__(self):
          Gtk.Window.__init__(self, title = &quot;Updating...&quot;)
  
          self.label = Gtk.Label()
          self.label.set_text(&quot;Idling...&quot;)
          self.add(self.label)
  
      def update(self):
          self.label.set_text(&quot;Updating... Please wait.&quot;)
          subprocess.call([&quot;/usr/bin/pkexec&quot;, &quot;/usr/bin/apt-get&quot;, &quot;update&quot;])
          self.label.set_text(&quot;Updated.&quot;)
  
      def run_update(self):
  
  main = mainWindow()
  main.connect(&quot;delete-event&quot;, Gtk.main_quit)
  main.show_all()
  Gtk.main()
  </code></pre>
  <p>Using a thread (case 3, in this case using <code>subprocess.Popen()</code>):</p>
  <pre class="lang-py prettyprint-override"><code>#!/usr/bin/python3
  from gi.repository import Gtk
  import threading
  import subprocess
  
  class mainWindow(Gtk.Window):
  
      def __init__(self):
          Gtk.Window.__init__(self, title = &quot;Updater&quot;)
  
          button = Gtk.Button()
          button.set_label(&quot;Update&quot;)
          button.connect(&quot;clicked&quot;, self.new_update_window)
          self.add(button)
  
      def new_update_window(self, button):
          update = updateWindow()
          update.show_all()
          update.update()
  
  class updateWindow(Gtk.Window):
  
      def __init__(self):
          Gtk.Window.__init__(self, title = &quot;Updating...&quot;)
  
          self.label = Gtk.Label()
          self.label.set_text(&quot;Idling...&quot;)
          self.add(self.label)
  
      def update(self):
          self.label.set_text(&quot;Updating... Please wait.&quot;)
          thread = threading.Thread(target=self.run_update)
          thread.start()
          thread.join()
          self.label.set_text(&quot;Updated.&quot;)
  
      def run_update(self):
          subprocess.Popen([&quot;/usr/bin/pkexec&quot;, &quot;/usr/bin/apt-get&quot;, &quot;update&quot;])
  
  main = mainWindow()
  main.connect(&quot;delete-event&quot;, Gtk.main_quit)
  main.show_all()
  Gtk.main()
  </code></pre>