[PySide] PySide plus Django: How can I make the PySide application auto-start the server?

Zak pyside at m.allo.ws
Thu Sep 6 19:18:54 CEST 2012


To see my full solution, look at the code below. Here it is described in 
English:

Use the Windows command 'tasklist' to get a list of all running 
processes. Unfortunately, several processes are named simply 
'python.exe', and I could not find a way to figure out which one 
corresponded to manage.py. If you kill the wrong 'python.exe' process, a 
process may essentially kill itself. If the process kills itself before 
it kills manage.py, then manage.py will not be killed at all.

To solve this problem, I ran 'tasklist' several times and kept track of 
when new processes appeared and which PID they had. It turns out that 
three 'python.exe' processes are created, and you need to kill the third 
one.

I eventually kill the process using 'taskkill /F /pid %s' % (pid_to_kill).

Here is the code, simplified and merged into a single file:

import re
import subprocess

pyPat = re.compile("(?m)^python\.exe\s+(?P<pid>\d+)")
# pyPat matches if "python.exe" occurs at the start of a new line (not in
# the middle), followed by one or more spaces, followed by one or more
# digits. The digits are stored in the 'pid' group of the match object.

def get_python_pids():
     tasklist = subprocess.check_output(["tasklist"])
     pids = []
     for mtch in pyPat.finditer(tasklist):
         pids.append(mtch.group('pid'))
     return pids


import sys
import subprocess
from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtWebKit import *


# Create a Qt application
app = QApplication(sys.argv)
# Create a browser window and show it
browser = QWebView(None)
browser.load(QUrl("http://127.0.0.1:8000/"))
browser.show()

# pids = pm.get_python_pids()
# print "PID list 1:"
# print pids
## Assuming no other Python things are running,
## this prints a list of one PID, e.g. ['1']

# Start the Django server
manage_path = local_settings.root_dir + 'manage.py'
server = subprocess.Popen(["python", manage_path, "runserver"])

pids_1 = pm.get_python_pids()
# print "PID list 2:"
# print pids_1
## Prints a list of two PIDs, e.g. ['1', '2']

# Enter Qt application main loop
app.exec_()

# If execution reaches this point, then the GUI window was closed

# To kill the Django server, we must first figure out what
# its Windows PID is

pids_2 = pm.get_python_pids()
# print "PID list 3:"
# print pids_2
## Prints a list of three PIDs, e.g. ['1', '2', '3']
## The proper process to kill is whichever one is new in pids_2. That is to
## say, we should kill the process which is listed in pids_2 but is not
## present in pids_1. In this example, it would be PID '3'.

# max_kill is the maximum number of processes named 'python.exe' to kill
max_kill = 1
for pid in pids_2:
     if pid in pids_1:
         continue
     else:
         subprocess.call(["taskkill", "/F", "/pid", pid])
         max_kill -= 1
     if max_kill == 0:
         break

# Now exit Python entirely
sys.exit()

Zak F.



More information about the PySide mailing list