Skip to content

Instantly share code, notes, and snippets.

Created April 24, 2012 07:15
Show Gist options
  • Save 3kwa/2477361 to your computer and use it in GitHub Desktop.
Save 3kwa/2477361 to your computer and use it in GitHub Desktop.
PyQT + WebKit application
#!/usr/bin/env python
If you use landslide to create slideshows using markdown, you may have found
yourself repeating endlessly:
+ save source document
+ switch to the terminal to run landslide
+ reload the generated html in your browser
This QT (using webkit) based "application" monitor changes to the source file
and automatically regenerates the HTML and refreshes the "browser".
$ ./ --help
usage: [-h] --landslide LANDSLIDE [--port PORT] [--html HTML] file
landslide text to html viewer
positional arguments:
file text file (md or rst)
optional arguments:
-h, --help show this help message and exit
--landslide LANDSLIDE
path to the landslide binary
--port PORT simple http server port (default 8000)
--html HTML html filename (default presentation.html)
To quit close the QT window or press ctrl + c in the terminal.
import sys
import os
import signal
import subprocess
import SimpleHTTPServer
import SocketServer
from multiprocessing import Process
import argparse
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
class FullHelpArgumentParser(argparse.ArgumentParser):
""" argument parser displaying the complete help on error """
def error(self, message):
sys.stderr.write('error: %s\n' % message)
def parse_arguments():
""" argparse wrapper """
parser = FullHelpArgumentParser(description='landslide text to html viewer')
parser.add_argument('file', help='text file (md or rst)', action='store')
parser.add_argument('--landslide', help='path to the landslide binary',
action='store', required=True)
parser.add_argument('--port', type=int, help='simple http server port (default 8000)',
default=8000, action='store')
parser.add_argument('--html', help='html filename (default presentation.html)',
default='presentation.html', action='store')
return parser.parse_args()
def http_server(path, port):
""" start a simple http server listening on port serving files from path """
handler = SimpleHTTPServer.SimpleHTTPRequestHandler
SocketServer.TCPServer.allow_reuse_address = True
http = SocketServer.TCPServer(('', port), handler)
# handling a ctrl-c termination
except KeyboardInterrupt:
def landslide(args):
""" run args.landslide on args.file to create args.html """
html_file = os.path.join(os.path.dirname(args.file), args.html)[args.landslide, '--embed', args.file, '-d', html_file])
def start_fs_watcher(web, args):
""" create a watcher on args.file, calling landslide and reloading web """
def file_changed(path):
fs_watcher = QFileSystemWatcher([args.file])
fs_watcher.connect(fs_watcher, SIGNAL('fileChanged(QString)'), file_changed)
return fs_watcher
def main():
args = parse_arguments()
# using multiprocessing to start the http server in its own process
http = Process(target=http_server, args=(os.path.dirname(args.file), args.port))
app = QApplication([])
web = QWebView()
fs_watcher = start_fs_watcher(web, args)
# compare html and text file last modified dates to only process if necessary
mtime_text_file = os.path.getmtime(args.file)
mtime_html_file = os.path.getmtime(os.path.join(os.path.dirname(args.file), args.html))
except OSError:
mtime_html_file = 0
if mtime_text_file > mtime_html_file:
web.load(QUrl('http://localhost:%i/%s' % (args.port, args.html)))
# exiting from the command line (ctrl+c)
signal.signal(signal.SIGINT, signal.SIG_DFL)
# starting the QT event loop
# del fs_watcher in a cleanup slot connected to the aboutToQuit signal doesn't work
del fs_watcher
if __name__ == '__main__':
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment