<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>John&#039;s Blog &#187; python</title>
	<atom:link href="http://john.nachtimwald.com/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://john.nachtimwald.com</link>
	<description>My little blog</description>
	<lastBuildDate>Sun, 29 Jan 2012 21:31:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Cybook t4b Format Specification</title>
		<link>http://john.nachtimwald.com/2010/01/13/cybook-t4b-format-specification/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cybook-t4b-format-specification</link>
		<comments>http://john.nachtimwald.com/2010/01/13/cybook-t4b-format-specification/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 02:09:23 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[hardware]]></category>
		<category><![CDATA[cybook]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[pgm]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[t2b]]></category>
		<category><![CDATA[t4b]]></category>
		<category><![CDATA[thumbnail]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=349</guid>
		<description><![CDATA[The new epub thumbnail files (.epub.thn) are what Bookeen calls t4b files. They are very similar to the older t2b thumbnail files they were using in earlier versions of the Cybook firmware. As the name suggests instead of using 2 bits to represent color values 4 bits are now used. This increases the number of [...]]]></description>
			<content:encoded><![CDATA[<p>The new epub thumbnail files (.epub.thn) are what Bookeen calls t4b files. They are very similar to the older <a href="http://john.nachtimwald.com/2009/01/19/cybook-t2b-format-specification/">t2b</a> thumbnail files they were using in earlier versions of the Cybook firmware. As the name suggests instead of using 2 bits to represent color values 4 bits are now used. This increases the number of colors from 4 to 16. In addition to the increased color range the t4b files now require a header of &#8220;t4bp&#8221; without the quotes.</p>
<p>The image’s dimensions are 96×144. The bits representing 0, 1, 2, 3&#8230; are written directly to the file. it is very similar to a pgm file in this regard. Each 4 bit sequence represents a pixel color. Only black, white and shades of gray are supported.</p>
<p>Every t4b file will have 13,824 pixels. The file size will always be 6,916 bytes. The formula to determine this is: (height x width x 2 bits per pixel) / 8 bits per byte. ((96 * 144 * 4) / 8 ) + 4 = 6,916. The + 4 is the header.</p>
<p>Following are two python scripts for converting an image to a t4b file and for converting a t4b file into a <a href="http://netpbm.sourceforge.net/doc/pgm.html">pgm image</a>.</p>
<p>image2t4b.py</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>, Image
&nbsp;
REDUCE_MARKS = <span style="color: black;">&#91;</span><span style="color: #ff4500;">16</span>, <span style="color: #ff4500;">32</span>, <span style="color: #ff4500;">48</span>, <span style="color: #ff4500;">64</span>, <span style="color: #ff4500;">80</span>, <span style="color: #ff4500;">96</span>, <span style="color: #ff4500;">112</span>, <span style="color: #ff4500;">128</span>, <span style="color: #ff4500;">144</span>, <span style="color: #ff4500;">160</span>, <span style="color: #ff4500;">176</span>, <span style="color: #ff4500;">192</span>, <span style="color: #ff4500;">208</span>, <span style="color: #ff4500;">224</span>, <span style="color: #ff4500;">240</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> reduce_color<span style="color: black;">&#40;</span>c<span style="color: black;">&#41;</span>:
    val = <span style="color: #ff4500;">0</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> mark <span style="color: #ff7700;font-weight:bold;">in</span> REDUCE_MARKS:
        <span style="color: #ff7700;font-weight:bold;">if</span> c <span style="color: #66cc66;">&amp;</span>gt<span style="color: #66cc66;">;</span> mark:
            val += <span style="color: #ff4500;">1</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #ff7700;font-weight:bold;">break</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> val
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= <span style="color: #ff4500;">3</span>:
        <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">Exception</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Must have 2 arguments. %s input.image output.epub.thn'</span> <span style="color: #66cc66;">%</span> <span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
    outf = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>, <span style="color: #483d8b;">'wb'</span><span style="color: black;">&#41;</span>
&nbsp;
    im = Image.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>.<span style="color: black;">convert</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;L&quot;</span><span style="color: black;">&#41;</span>
    im.<span style="color: black;">thumbnail</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">96</span>, <span style="color: #ff4500;">144</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    newim = Image.<span style="color: #dc143c;">new</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'L'</span>, <span style="color: black;">&#40;</span><span style="color: #ff4500;">96</span>, <span style="color: #ff4500;">144</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">'white'</span><span style="color: black;">&#41;</span>
&nbsp;
    x,y = im.<span style="color: black;">size</span>
    newim.<span style="color: black;">paste</span><span style="color: black;">&#40;</span>im, <span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">96</span>-x<span style="color: black;">&#41;</span>/<span style="color: #ff4500;">2</span>, <span style="color: black;">&#40;</span><span style="color: #ff4500;">144</span>-y<span style="color: black;">&#41;</span>/<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    outf.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'t4bp'</span><span style="color: black;">&#41;</span>
&nbsp;
    px = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> p <span style="color: #ff7700;font-weight:bold;">in</span> newim.<span style="color: black;">getdata</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        px.<span style="color: black;">append</span><span style="color: black;">&#40;</span>p<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>px<span style="color: black;">&#41;</span> == <span style="color: #ff4500;">2</span>:
            byte_val = bin<span style="color: black;">&#40;</span>reduce_color<span style="color: black;">&#40;</span>px<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span>:<span style="color: black;">&#93;</span>.<span style="color: black;">zfill</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span> + bin<span style="color: black;">&#40;</span>reduce_color<span style="color: black;">&#40;</span>px<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span>:<span style="color: black;">&#93;</span>.<span style="color: black;">zfill</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>
            outf.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #008000;">chr</span><span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span>byte_val, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            px = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>px<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span>gt<span style="color: #66cc66;">;</span> <span style="color: #ff4500;">2</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">Exception</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Fatal error px length increased past 2.'</span><span style="color: black;">&#41;</span>
&nbsp;
    outf.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>t4b2pgm.py</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>, <span style="color: #dc143c;">os</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> get_greys<span style="color: black;">&#40;</span>b<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> b:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span>
&nbsp;
    b = bin<span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>b<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    b = b<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span>:<span style="color: black;">&#93;</span>.<span style="color: black;">zfill</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">8</span><span style="color: black;">&#41;</span>
&nbsp;
    w = <span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span>b<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span>:<span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    x = <span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span>b<span style="color: black;">&#91;</span><span style="color: #ff4500;">4</span>:<span style="color: #ff4500;">8</span><span style="color: black;">&#93;</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> w, x
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= <span style="color: #ff4500;">3</span>:
        <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">Exception</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Must have 2 arguments. %s input.epub.thm output.pgm'</span> <span style="color: #66cc66;">%</span> <span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
    t4bfile = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>, <span style="color: #483d8b;">'rb'</span><span style="color: black;">&#41;</span>
    pgmfile = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>, <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
&nbsp;
    pgmfile.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'P2<span style="color: #000099; font-weight: bold;">\n</span>96 144<span style="color: #000099; font-weight: bold;">\n</span>15<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Read past the t4b header</span>
    t4bfile.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">144</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">for</span> j <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">48</span><span style="color: black;">&#41;</span>:
            b = t4bfile.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
            vals = get_greys<span style="color: black;">&#40;</span>b<span style="color: black;">&#41;</span>
            pgmfile.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s %s '</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>vals<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, vals<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        pgmfile.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
&nbsp;
    pgmfile.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    t4bfile.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2010/01/13/cybook-t4b-format-specification/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unidecoder</title>
		<link>http://john.nachtimwald.com/2009/10/31/unidecoder/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=unidecoder</link>
		<comments>http://john.nachtimwald.com/2009/10/31/unidecoder/#comments</comments>
		<pubDate>Sat, 31 Oct 2009 13:36:40 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[ebook]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[txt]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=249</guid>
		<description><![CDATA[A while back I made a post about ASCIIizing Text. With it was a simple python application that would convert Unicode characters to ASCII equivalents. It doesn&#8217;t do a basic conversion but also Latinizes the characters when they are outside of the ASCII range. The uni2ascii package I made has a few short comings I&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<p>A while back I made a post about <a href="http://john.nachtimwald.com/2009/07/24/asciiize-text/">ASCIIizing Text</a>. With it was a simple python application that would convert Unicode characters to ASCII equivalents. It doesn&#8217;t do a basic conversion but also Latinizes the characters when they are outside of the ASCII range.</p>
</p>
<p>The <a href="http://john.nachtimwald.com/2009/07/24/asciiize-text/">uni2ascii</a> package I made has a few short comings I&#8217;ve decided to fix. The three major problems with it are: 1) Very basic permission checking, 2) Only accepts one file, 3) Required all input to be UTF8 encoded, 4) The decoder was a very literal port of a the ruby version.</p>
<p>To fix these issues I&#8217;ve written an entirely new script. Problems 1, 2 and 3 are fixed. It has robust error checking, can handle an arbitrary number of files, and the file encoding can be specified. Number 4 is fixed by using the Python port created by <a href="http://www.tablix.org/~avian/blog/archives/2009/01/unicode_transliteration_in_python/">Tomaz Solc</a>.</p>
<p>I&#8217;ve put the source code for the new decoder into a Launchpad branch:</p>
<pre>$ bzr branch lp:~user-none/+junk/unidecoder</pre>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2009/10/31/unidecoder/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Niw Markdown Editor</title>
		<link>http://john.nachtimwald.com/2009/08/30/niw-markdown-editor/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=niw-markdown-editor</link>
		<comments>http://john.nachtimwald.com/2009/08/30/niw-markdown-editor/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 00:34:40 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[niwmarkdowneditor]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[markdown]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[qt]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=210</guid>
		<description><![CDATA[For the past three weeks I&#8217;ve been working on an editor for working with plain text files and making it easy to add markdown syntax to them. My main goal is to make it easier to format the large number of ebooks I have. Almost all of them are plain text files. It&#8217;s a python [...]]]></description>
			<content:encoded><![CDATA[<p>For the past three weeks I&#8217;ve been working on an editor for working with plain text files and making it easy to add markdown syntax to them. My main goal is to make it easier to format the large number of ebooks I have. Almost all of them are plain text files.</p>
<p>It&#8217;s a python project using PyQt4 and I&#8217;m hosting it on Launchpad. <a href="https://launchpad.net/niwmarkdowneditor">here</a> is the project page and you can find some screen shots <a href="http://john.nachtimwald.com/2009/08/30/niwmarkdowneditor-screen-shots/">here</a>.</p>
<p>The features of this application and what makes it more useful that a generic text editor are the tool box and the tools. The toolbox allows for a number of markdown syntax changes to be made with one click. The tools menu supports a number of options that make formatting text a bit easier.</p>
<p>The current tools are:</p>
<ul>
<li>Heading list which shows a listing of all headings in the document</li>
<li>Link list which shows a listing of all links in the document</li>
<li>Image list which shows a listing of all images in the document</li>
<li>ASCIIize which will turn all unicode characters into an ASCII equivalent</li>
<li>Remove leading spaces</li>
<li>Remove trailing spaces</li>
<li>Replace tabs with spaces</li>
<li>Separate paragraphs</li>
<li>Double line breaks</li>
<li>Remove excessive line beaks</li>
</ul>
<p>There are a number of other options such as line numbering, highlighting of the line and syntax, and inline spell check.</p>
<p>There is still a lot I would like to do with the project. For one thing I needs and icon. As well as build targets for Windows and OS X. Include image previews in the Image listing. Take a look at the TODO file to get a feel of what I have in mind in the near future.</p>
<p>For those of you who what to test it out you can find a tarball <a href="http://launchpad.net/niwmarkdowneditor/trunk/1.0/+download/niwmarkdowneditor-1.0.tar.gz">here</a>. The dependencies are:</p>
<ul>
<li>Python 2.6</li>
<li>Qt &gt;= 4.5</li>
<li>PyQt &gt;=4.5</li>
<li>python-markdown</li>
<li>python-enchant (optional for spell check)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2009/08/30/niw-markdown-editor/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>QPlainTextEdit With In Line Spell Check</title>
		<link>http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=qplaintextedit-with-in-line-spell-check</link>
		<comments>http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check/#comments</comments>
		<pubDate>Sat, 22 Aug 2009 21:06:33 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[pyqt]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[qt]]></category>
		<category><![CDATA[spell check]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=197</guid>
		<description><![CDATA[***Update: Simplified Highlighter.highlightBlock function One thing Qt lacks is an integrated spell check in the text entry components. For a project I&#8217;m working on this is necessary. Using python-enchant and the QSyntaxHighlighter I was able to implement this functionality. Here is how to add an in line spell check support to a QPlainTextEdit. #!/usr/bin/env python [...]]]></description>
			<content:encoded><![CDATA[<p>***Update: Simplified Highlighter.highlightBlock function</p>
<p>One thing Qt lacks is an integrated spell check in the text entry components. For a project I&#8217;m working on this is necessary. Using python-enchant and the QSyntaxHighlighter I was able to implement this functionality. Here is how to add an in line spell check support to a QPlainTextEdit.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
__license__ = <span style="color: #483d8b;">'MIT'</span>
__copyright__ = <span style="color: #483d8b;">'2009, John Schember '</span>
__docformat__ = <span style="color: #483d8b;">'restructuredtext en'</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> enchant
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QAction
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QApplication
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QEvent
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QMenu
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QMouseEvent
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QPlainTextEdit
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QSyntaxHighlighter
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QTextCharFormat
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QTextCursor
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> Qt
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">QtCore</span> <span style="color: #ff7700;font-weight:bold;">import</span> pyqtSignal
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> SpellTextEdit<span style="color: black;">&#40;</span>QPlainTextEdit<span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>:
        QPlainTextEdit.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Default dictionary based on the current locale.</span>
        <span style="color: #008000;">self</span>.<span style="color: #008000;">dict</span> = enchant.<span style="color: black;">Dict</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">highlighter</span> = Highlighter<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">document</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">highlighter</span>.<span style="color: black;">setDict</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: #008000;">dict</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> mousePressEvent<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> event.<span style="color: black;">button</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == Qt.<span style="color: black;">RightButton</span>:
            <span style="color: #808080; font-style: italic;"># Rewrite the mouse event to a left button event so the cursor is</span>
            <span style="color: #808080; font-style: italic;"># moved to the location of the pointer.</span>
            event = QMouseEvent<span style="color: black;">&#40;</span>QEvent.<span style="color: black;">MouseButtonPress</span>, event.<span style="color: black;">pos</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>,
                Qt.<span style="color: black;">LeftButton</span>, Qt.<span style="color: black;">LeftButton</span>, Qt.<span style="color: black;">NoModifier</span><span style="color: black;">&#41;</span>
        QPlainTextEdit.<span style="color: black;">mousePressEvent</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> contextMenuEvent<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>:
        popup_menu = <span style="color: #008000;">self</span>.<span style="color: black;">createStandardContextMenu</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Select the word under the cursor.</span>
        cursor = <span style="color: #008000;">self</span>.<span style="color: black;">textCursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        cursor.<span style="color: #dc143c;">select</span><span style="color: black;">&#40;</span>QTextCursor.<span style="color: black;">WordUnderCursor</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">setTextCursor</span><span style="color: black;">&#40;</span>cursor<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Check if the selected word is misspelled and offer spelling</span>
        <span style="color: #808080; font-style: italic;"># suggestions if it is.</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">textCursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">hasSelection</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
            text = <span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">textCursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">selectedText</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: #008000;">dict</span>.<span style="color: black;">check</span><span style="color: black;">&#40;</span>text<span style="color: black;">&#41;</span>:
                spell_menu = QMenu<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Spelling Suggestions'</span><span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">for</span> word <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>.<span style="color: #008000;">dict</span>.<span style="color: black;">suggest</span><span style="color: black;">&#40;</span>text<span style="color: black;">&#41;</span>:
                    action = SpellAction<span style="color: black;">&#40;</span>word, spell_menu<span style="color: black;">&#41;</span>
                    action.<span style="color: black;">correct</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">correctWord</span><span style="color: black;">&#41;</span>
                    spell_menu.<span style="color: black;">addAction</span><span style="color: black;">&#40;</span>action<span style="color: black;">&#41;</span>
                <span style="color: #808080; font-style: italic;"># Only add the spelling suggests to the menu if there are</span>
                <span style="color: #808080; font-style: italic;"># suggestions.</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>spell_menu.<span style="color: black;">actions</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= <span style="color: #ff4500;">0</span>:
                    popup_menu.<span style="color: black;">insertSeparator</span><span style="color: black;">&#40;</span>popup_menu.<span style="color: black;">actions</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
                    popup_menu.<span style="color: black;">insertMenu</span><span style="color: black;">&#40;</span>popup_menu.<span style="color: black;">actions</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, spell_menu<span style="color: black;">&#41;</span>
&nbsp;
        popup_menu.<span style="color: black;">exec_</span><span style="color: black;">&#40;</span>event.<span style="color: black;">globalPos</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> correctWord<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, word<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'
        Replaces the selected text with word.
        '</span><span style="color: #483d8b;">''</span>
        cursor = <span style="color: #008000;">self</span>.<span style="color: black;">textCursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        cursor.<span style="color: black;">beginEditBlock</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        cursor.<span style="color: black;">removeSelectedText</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        cursor.<span style="color: black;">insertText</span><span style="color: black;">&#40;</span>word<span style="color: black;">&#41;</span>
&nbsp;
        cursor.<span style="color: black;">endEditBlock</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Highlighter<span style="color: black;">&#40;</span>QSyntaxHighlighter<span style="color: black;">&#41;</span>:
&nbsp;
    WORDS = u<span style="color: #483d8b;">'(?iu)[<span style="color: #000099; font-weight: bold;">\w</span><span style="color: #000099; font-weight: bold;">\'</span>]+'</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>:
        QSyntaxHighlighter.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: #008000;">dict</span> = <span style="color: #008000;">None</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> setDict<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #008000;">dict</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: #008000;">dict</span> = <span style="color: #008000;">dict</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> highlightBlock<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, text<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: #008000;">dict</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span>
&nbsp;
        text = <span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span>text<span style="color: black;">&#41;</span>
&nbsp;
        format = QTextCharFormat<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        format.<span style="color: black;">setUnderlineColor</span><span style="color: black;">&#40;</span>Qt.<span style="color: black;">red</span><span style="color: black;">&#41;</span>
        format.<span style="color: black;">setUnderlineStyle</span><span style="color: black;">&#40;</span>QTextCharFormat.<span style="color: black;">SpellCheckUnderline</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">for</span> word_object <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">finditer</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">WORDS</span>, text<span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: #008000;">dict</span>.<span style="color: black;">check</span><span style="color: black;">&#40;</span>word_object.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
                <span style="color: #008000;">self</span>.<span style="color: black;">setFormat</span><span style="color: black;">&#40;</span>word_object.<span style="color: black;">start</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>,
                    word_object.<span style="color: black;">end</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - word_object.<span style="color: black;">start</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, format<span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> SpellAction<span style="color: black;">&#40;</span>QAction<span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'
    A special QAction that returns the text in a signal.
    '</span><span style="color: #483d8b;">''</span>
&nbsp;
    correct = pyqtSignal<span style="color: black;">&#40;</span><span style="color: #008000;">unicode</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>:
        QAction.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">triggered</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x: <span style="color: #008000;">self</span>.<span style="color: black;">correct</span>.<span style="color: black;">emit</span><span style="color: black;">&#40;</span>
            <span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">text</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span>args=<span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span>:
    app = QApplication<span style="color: black;">&#40;</span>args<span style="color: black;">&#41;</span>
&nbsp;
    spellEdit = SpellTextEdit<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    spellEdit.<span style="color: black;">show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> app.<span style="color: black;">exec_</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span>main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>The SpellTextEdit&#8217;s purpose is straightforward. It will mark misspelled words. Right clicking on a word in the SpellTextEdit will cause the word to become selected and display a context menu. If the word is misspelled and there are spelling suggestions the context menu will include a sub menu of those suggestions. Selecting a suggestion will replace the misspelled text with the selection.</p>
<p>The Highlighter class takes text, breaks it into words, checks if they are spelled correctly and if not underlines the misspelled ones with a red squiggle. I&#8217;m using a regular expression to split the words instead of using str.split because str.split will only split on whitespace and include punctuation (e.g. &#8220;.!*) as part of the words.</p>
<p>SpellAction is a simple class that allows for the action&#8217;s text to be sent with the signal. This is necessary for dynamically creating the list of possible correction words in the right click menu. The SpellAction is connected to a function that replaces the selected text with the signal text.</p>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Better QPlainTextEdit With Line Numbers</title>
		<link>http://john.nachtimwald.com/2009/08/19/better-qplaintextedit-with-line-numbers/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=better-qplaintextedit-with-line-numbers</link>
		<comments>http://john.nachtimwald.com/2009/08/19/better-qplaintextedit-with-line-numbers/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 23:50:52 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[qt]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=195</guid>
		<description><![CDATA[My last post was an implementation of a Qt widget which displays text with line numbers. I found that it has a few limitations. The biggest was a performance penalty when dealing with large documents. I&#8217;ve since re-factored and rewritten the class to make the performance acceptable. I&#8217;ve also cleaned up the code a bit [...]]]></description>
			<content:encoded><![CDATA[<p>My last post was an implementation of a Qt widget which displays text with line numbers. I found that it has a few limitations. The biggest was a performance penalty when dealing with large documents. I&#8217;ve since re-factored and rewritten the class to make the performance acceptable. I&#8217;ve also cleaned up the code a bit and added a highlight to the current line.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">&nbsp;
<span style="color: #483d8b;">''</span><span style="color: #483d8b;">'
Text widget with support for line numbers
'</span><span style="color: #483d8b;">''</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QFrame
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QHBoxLayout
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QPainter
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QPlainTextEdit
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QRect
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QTextEdit
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QTextFormat
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QVariant
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QWidget
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> Qt
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> LNTextEdit<span style="color: black;">&#40;</span>QFrame<span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">class</span> NumberBar<span style="color: black;">&#40;</span>QWidget<span style="color: black;">&#41;</span>:
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, edit<span style="color: black;">&#41;</span>:
            QWidget.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, edit<span style="color: black;">&#41;</span>
&nbsp;
            <span style="color: #008000;">self</span>.<span style="color: black;">edit</span> = edit
            <span style="color: #008000;">self</span>.<span style="color: black;">adjustWidth</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">def</span> paintEvent<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">numberbarPaint</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>
            QWidget.<span style="color: black;">paintEvent</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">def</span> adjustWidth<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, count<span style="color: black;">&#41;</span>:
            width = <span style="color: #008000;">self</span>.<span style="color: black;">fontMetrics</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">width</span><span style="color: black;">&#40;</span><span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span>count<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">width</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= width:
                <span style="color: #008000;">self</span>.<span style="color: black;">setFixedWidth</span><span style="color: black;">&#40;</span>width<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">def</span> updateContents<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, rect, scroll<span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">if</span> scroll:
                <span style="color: #008000;">self</span>.<span style="color: black;">scroll</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, scroll<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #808080; font-style: italic;"># It would be nice to do</span>
                <span style="color: #808080; font-style: italic;"># self.update(0, rect.y(), self.width(), rect.height())</span>
                <span style="color: #808080; font-style: italic;"># But we can't because it will not remove the bold on the</span>
                <span style="color: #808080; font-style: italic;"># current line if word wrap is enabled and a new block is</span>
                <span style="color: #808080; font-style: italic;"># selected.</span>
                <span style="color: #008000;">self</span>.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">class</span> PlainTextEdit<span style="color: black;">&#40;</span>QPlainTextEdit<span style="color: black;">&#41;</span>:
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>:
            QPlainTextEdit.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>
&nbsp;
            <span style="color: #808080; font-style: italic;">#self.setFrameStyle(QFrame.NoFrame)</span>
&nbsp;
            <span style="color: #008000;">self</span>.<span style="color: black;">setFrameStyle</span><span style="color: black;">&#40;</span>QFrame.<span style="color: black;">NoFrame</span><span style="color: black;">&#41;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">highlight</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            <span style="color: #808080; font-style: italic;">#self.setLineWrapMode(QPlainTextEdit.NoWrap)</span>
&nbsp;
            <span style="color: #008000;">self</span>.<span style="color: black;">cursorPositionChanged</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">highlight</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">def</span> highlight<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
            hi_selection = QTextEdit.<span style="color: black;">ExtraSelection</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
            hi_selection.<span style="color: black;">format</span>.<span style="color: black;">setBackground</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">palette</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">alternateBase</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            hi_selection.<span style="color: black;">format</span>.<span style="color: black;">setProperty</span><span style="color: black;">&#40;</span>QTextFormat.<span style="color: black;">FullWidthSelection</span>, QVariant<span style="color: black;">&#40;</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            hi_selection.<span style="color: black;">cursor</span> = <span style="color: #008000;">self</span>.<span style="color: black;">textCursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            hi_selection.<span style="color: black;">cursor</span>.<span style="color: black;">clearSelection</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
            <span style="color: #008000;">self</span>.<span style="color: black;">setExtraSelections</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>hi_selection<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">def</span> numberbarPaint<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, number_bar, event<span style="color: black;">&#41;</span>:
            font_metrics = <span style="color: #008000;">self</span>.<span style="color: black;">fontMetrics</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            current_line = <span style="color: #008000;">self</span>.<span style="color: black;">document</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">findBlock</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">textCursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">position</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">blockNumber</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> + <span style="color: #ff4500;">1</span>
&nbsp;
            block = <span style="color: #008000;">self</span>.<span style="color: black;">firstVisibleBlock</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            line_count = block.<span style="color: black;">blockNumber</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            painter = QPainter<span style="color: black;">&#40;</span>number_bar<span style="color: black;">&#41;</span>
            painter.<span style="color: black;">fillRect</span><span style="color: black;">&#40;</span>event.<span style="color: black;">rect</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, <span style="color: #008000;">self</span>.<span style="color: black;">palette</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">base</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
            <span style="color: #808080; font-style: italic;"># Iterate over all visible text blocks in the document.</span>
            <span style="color: #ff7700;font-weight:bold;">while</span> block.<span style="color: black;">isValid</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
                line_count += <span style="color: #ff4500;">1</span>
                block_top = <span style="color: #008000;">self</span>.<span style="color: black;">blockBoundingGeometry</span><span style="color: black;">&#40;</span>block<span style="color: black;">&#41;</span>.<span style="color: black;">translated</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">contentOffset</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">top</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
                <span style="color: #808080; font-style: italic;"># Check if the position of the block is out side of the visible</span>
                <span style="color: #808080; font-style: italic;"># area.</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> block.<span style="color: black;">isVisible</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">or</span> block_top <span style="color: #66cc66;">&amp;</span>gt<span style="color: #66cc66;">;</span>= event.<span style="color: black;">rect</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">bottom</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
                    <span style="color: #ff7700;font-weight:bold;">break</span>
&nbsp;
                <span style="color: #808080; font-style: italic;"># We want the line number for the selected line to be bold.</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> line_count == current_line:
                    font = painter.<span style="color: black;">font</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                    font.<span style="color: black;">setBold</span><span style="color: black;">&#40;</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
                    painter.<span style="color: black;">setFont</span><span style="color: black;">&#40;</span>font<span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">else</span>:
                    font = painter.<span style="color: black;">font</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                    font.<span style="color: black;">setBold</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
                    painter.<span style="color: black;">setFont</span><span style="color: black;">&#40;</span>font<span style="color: black;">&#41;</span>
&nbsp;
                <span style="color: #808080; font-style: italic;"># Draw the line number right justified at the position of the line.</span>
                paint_rect = QRect<span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, block_top, number_bar.<span style="color: black;">width</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, font_metrics.<span style="color: black;">height</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
                painter.<span style="color: black;">drawText</span><span style="color: black;">&#40;</span>paint_rect, Qt.<span style="color: black;">AlignRight</span>, <span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span>line_count<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
                block = block.<span style="color: black;">next</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
            painter.<span style="color: black;">end</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>:
        QFrame.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">setFrameStyle</span><span style="color: black;">&#40;</span>QFrame.<span style="color: black;">StyledPanel</span> | QFrame.<span style="color: black;">Sunken</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">edit</span> = <span style="color: #008000;">self</span>.<span style="color: black;">PlainTextEdit</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">number_bar</span> = <span style="color: #008000;">self</span>.<span style="color: black;">NumberBar</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">edit</span><span style="color: black;">&#41;</span>
&nbsp;
        hbox = QHBoxLayout<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        hbox.<span style="color: black;">setSpacing</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
        hbox.<span style="color: black;">setMargin</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
        hbox.<span style="color: black;">addWidget</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">number_bar</span><span style="color: black;">&#41;</span>
        hbox.<span style="color: black;">addWidget</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">edit</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">blockCountChanged</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">number_bar</span>.<span style="color: black;">adjustWidth</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">updateRequest</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">number_bar</span>.<span style="color: black;">updateContents</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> getText<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">toPlainText</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> setText<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, text<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">setPlainText</span><span style="color: black;">&#40;</span>text<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> isModified<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">document</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">isModified</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> setModified<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, modified<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">document</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">setModified</span><span style="color: black;">&#40;</span>modified<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> setLineWrapMode<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, mode<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">setLineWrapMode</span><span style="color: black;">&#40;</span>mode<span style="color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2009/08/19/better-qplaintextedit-with-line-numbers/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>QTextEdit With Line Numbers</title>
		<link>http://john.nachtimwald.com/2009/08/15/qtextedit-with-line-numbers/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=qtextedit-with-line-numbers</link>
		<comments>http://john.nachtimwald.com/2009/08/15/qtextedit-with-line-numbers/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 18:52:01 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[qt]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=190</guid>
		<description><![CDATA[Here is a Qt4 widget written in Python that allows for line numbers next to a QTextEdit. Similar to what is seen in a number of text editors such as gedit and kate. from PyQt4.Qt import QFrame, QWidget, QTextEdit, QHBoxLayout, QPainter &#160; class LineTextWidget&#40;QFrame&#41;: &#160; class NumberBar&#40;QWidget&#41;: &#160; def __init__&#40;self, *args&#41;: QWidget.__init__&#40;self, *args&#41; self.edit = [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a Qt4 widget written in Python that allows for line numbers next to a QTextEdit. Similar to what is seen in a number of text editors such as gedit and kate.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> QFrame, QWidget, QTextEdit, QHBoxLayout, QPainter
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> LineTextWidget<span style="color: black;">&#40;</span>QFrame<span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">class</span> NumberBar<span style="color: black;">&#40;</span>QWidget<span style="color: black;">&#41;</span>:
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>:
            QWidget.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">edit</span> = <span style="color: #008000;">None</span>
            <span style="color: #808080; font-style: italic;"># This is used to update the width of the control.</span>
            <span style="color: #808080; font-style: italic;"># It is the highest line that is currently visibile.</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">highest_line</span> = <span style="color: #ff4500;">0</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">def</span> setTextEdit<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, edit<span style="color: black;">&#41;</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">edit</span> = edit
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">def</span> update<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>:
            <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'
            Updates the number bar to display the current set of numbers.
            Also, adjusts the width of the number bar if necessary.
            '</span><span style="color: #483d8b;">''</span>
            <span style="color: #808080; font-style: italic;"># The + 4 is used to compensate for the current line being bold.</span>
            width = <span style="color: #008000;">self</span>.<span style="color: black;">fontMetrics</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">width</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">highest_line</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> + <span style="color: #ff4500;">4</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">width</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= width:
                <span style="color: #008000;">self</span>.<span style="color: black;">setFixedWidth</span><span style="color: black;">&#40;</span>width<span style="color: black;">&#41;</span>
            QWidget.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">def</span> paintEvent<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>:
            contents_y = <span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">verticalScrollBar</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">value</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            page_bottom = contents_y + <span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">viewport</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">height</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            font_metrics = <span style="color: #008000;">self</span>.<span style="color: black;">fontMetrics</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            current_block = <span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">document</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">findBlock</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">textCursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">position</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
            painter = QPainter<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
&nbsp;
            line_count = <span style="color: #ff4500;">0</span>
            <span style="color: #808080; font-style: italic;"># Iterate over all text blocks in the document.</span>
            block = <span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">document</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">begin</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">while</span> block.<span style="color: black;">isValid</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
                line_count += <span style="color: #ff4500;">1</span>
&nbsp;
                <span style="color: #808080; font-style: italic;"># The top left position of the block in the document</span>
                position = <span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">document</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">documentLayout</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">blockBoundingRect</span><span style="color: black;">&#40;</span>block<span style="color: black;">&#41;</span>.<span style="color: black;">topLeft</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
                <span style="color: #808080; font-style: italic;"># Check if the position of the block is out side of the visible</span>
                <span style="color: #808080; font-style: italic;"># area.</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> position.<span style="color: black;">y</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span>gt<span style="color: #66cc66;">;</span> page_bottom:
                    <span style="color: #ff7700;font-weight:bold;">break</span>
&nbsp;
                <span style="color: #808080; font-style: italic;"># We want the line number for the selected line to be bold.</span>
                bold = <span style="color: #008000;">False</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> block == current_block:
                    bold = <span style="color: #008000;">True</span>
                    font = painter.<span style="color: black;">font</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                    font.<span style="color: black;">setBold</span><span style="color: black;">&#40;</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
                    painter.<span style="color: black;">setFont</span><span style="color: black;">&#40;</span>font<span style="color: black;">&#41;</span>
&nbsp;
                <span style="color: #808080; font-style: italic;"># Draw the line number right justified at the y position of the</span>
                <span style="color: #808080; font-style: italic;"># line. 3 is a magic padding number. drawText(x, y, text).</span>
                painter.<span style="color: black;">drawText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">width</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - font_metrics.<span style="color: black;">width</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span>line_count<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> - <span style="color: #ff4500;">3</span>, <span style="color: #008000;">round</span><span style="color: black;">&#40;</span>position.<span style="color: black;">y</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> - contents_y + font_metrics.<span style="color: black;">ascent</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>line_count<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
                <span style="color: #808080; font-style: italic;"># Remove the bold style if it was set previously.</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> bold:
                    font = painter.<span style="color: black;">font</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                    font.<span style="color: black;">setBold</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
                    painter.<span style="color: black;">setFont</span><span style="color: black;">&#40;</span>font<span style="color: black;">&#41;</span>
&nbsp;
                block = block.<span style="color: black;">next</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
            <span style="color: #008000;">self</span>.<span style="color: black;">highest_line</span> = line_count
            painter.<span style="color: black;">end</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
            QWidget.<span style="color: black;">paintEvent</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, event<span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>:
        QFrame.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">setFrameStyle</span><span style="color: black;">&#40;</span>QFrame.<span style="color: black;">StyledPanel</span> | QFrame.<span style="color: black;">Sunken</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">edit</span> = QTextEdit<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">setFrameStyle</span><span style="color: black;">&#40;</span>QFrame.<span style="color: black;">NoFrame</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">setAcceptRichText</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">number_bar</span> = <span style="color: #008000;">self</span>.<span style="color: black;">NumberBar</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">number_bar</span>.<span style="color: black;">setTextEdit</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">edit</span><span style="color: black;">&#41;</span>
&nbsp;
        hbox = QHBoxLayout<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        hbox.<span style="color: black;">setSpacing</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
        hbox.<span style="color: black;">setMargin</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
        hbox.<span style="color: black;">addWidget</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">number_bar</span><span style="color: black;">&#41;</span>
        hbox.<span style="color: black;">addWidget</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">edit</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">installEventFilter</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">viewport</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">installEventFilter</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> eventFilter<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #008000;">object</span>, event<span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># Update the line numbers for all events on the text edit and the viewport.</span>
        <span style="color: #808080; font-style: italic;"># This is easier than connecting all necessary singals.</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">object</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">edit</span>, <span style="color: #008000;">self</span>.<span style="color: black;">edit</span>.<span style="color: black;">viewport</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">number_bar</span>.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">False</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> QFrame.<span style="color: black;">eventFilter</span><span style="color: black;">&#40;</span><span style="color: #008000;">object</span>, event<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> getTextEdit<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">edit</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2009/08/15/qtextedit-with-line-numbers/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>ASCIIize Text</title>
		<link>http://john.nachtimwald.com/2009/07/24/asciiize-text/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=asciiize-text</link>
		<comments>http://john.nachtimwald.com/2009/07/24/asciiize-text/#comments</comments>
		<pubDate>Sat, 25 Jul 2009 02:44:56 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[ebook]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=179</guid>
		<description><![CDATA[One pet peeve of I have with my Cybook Gen 3 is its inability to properly display unicode characters in plain text files. I don&#8217;t need anything fancy like Japanese characters just simple things like “ and ” (as opposed to &#8221; and &#8220;). To solve this problem I&#8217;ve been thinking about adding an &#8211;asciize [...]]]></description>
			<content:encoded><![CDATA[<p>One pet peeve of I have with my Cybook Gen 3 is its inability to properly display unicode characters in plain text files. I don&#8217;t need anything fancy like Japanese characters just simple things like “ and ” (as opposed to &#8221; and &#8220;). To solve this problem I&#8217;ve been thinking about adding an &#8211;asciize option to calibre. I say thinking because I didn&#8217;t really know where to start. Thankfully a user recently requested this very functionality in bug <a href="http://calibre.kovidgoyal.net/ticket/2846">#2846</a>. He even included a link to work to accomplish this very task.</p>
<p>I will be integrating transliteration of unicode to ascii into calibre soon. However, in the mean time here is a script and classes, see <a href="http://john.nachtimwald.com/2009/10/31/unidecoder/">unidecoder</a> for a better method, to accomplish this task outside of calibre. This is my python port of the <a href="http://rubyforge.org/projects/unidecode/">ruby unidecode gem</a>. Which is a port of the original perl <a href="http://search.cpan.org/~sburke/Text-Unidecode-0.04/">Text::Unidecode</a>.</p>
<p>The major differences between my implementation and the others is it&#8217;s written in python and it uses a single dictionary instead of loading the code group files as needed.</p>
<p>You can find out more on how this all works at <a href="http://interglacial.com/~sburke/tpj/as_html/tpj22.html">http://interglacial.com/~sburke/tpj/as_html/tpj22.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2009/07/24/asciiize-text/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>History Drop Down With Model</title>
		<link>http://john.nachtimwald.com/2009/07/23/history-drop-down-with-model/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=history-drop-down-with-model</link>
		<comments>http://john.nachtimwald.com/2009/07/23/history-drop-down-with-model/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 22:05:01 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[qt]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=176</guid>
		<description><![CDATA[Following is a bit of python code that illustrates how to create a QComboBox that attaches to a model for listing history items. The main features of this code are items entered in the text area of the combo are added to the history. Selected items and items entered that already appear in the combo [...]]]></description>
			<content:encoded><![CDATA[<p>Following is a bit of python code that illustrates how to create a QComboBox that attaches to a model for listing history items. The main features of this code are items entered in the text area of the combo are added to the history. Selected items and items entered that already appear in the combo are moved to the top. When MAX_ITEMS is exceeded older items (items at the bottom of the drop down) are removed.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">QtGui</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> ComboModel<span style="color: black;">&#40;</span>QAbstractListModel<span style="color: black;">&#41;</span>:
&nbsp;
    MAX_ITEMS = <span style="color: #ff4500;">5</span>
    items = <span style="color: black;">&#91;</span>u<span style="color: #483d8b;">'123'</span>, u<span style="color: #483d8b;">'456'</span>, u<span style="color: #483d8b;">'789'</span><span style="color: black;">&#93;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Required to get a working model.</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> rowCount<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent=QModelIndex<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># This is a List model meaning all elements are root elements.</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> parent <span style="color: #ff7700;font-weight:bold;">and</span> parent.<span style="color: black;">isValid</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">0</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">items</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Required to get a working model.</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> insertRows<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, row, count, parent=QModelIndex<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">beginInsertRows</span><span style="color: black;">&#40;</span>parent, <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">endInsertRows</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">True</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> data<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, index, role<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> role <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#40;</span>Qt.<span style="color: black;">DisplayRole</span>, Qt.<span style="color: black;">EditRole</span><span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span> QVariant<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">items</span><span style="color: black;">&#91;</span>index.<span style="color: black;">row</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> QVariant<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> setData<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, index, value, role<span style="color: black;">&#41;</span>:
        value = <span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span>value.<span style="color: black;">toString</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> value <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>.<span style="color: black;">items</span>:
            <span style="color: #808080; font-style: italic;"># Move the item to the top of the list.</span>
            <span style="color: #ff7700;font-weight:bold;">del</span> <span style="color: #008000;">self</span>.<span style="color: black;">items</span><span style="color: black;">&#91;</span><span style="color: #008000;">self</span>.<span style="color: black;">items</span>.<span style="color: black;">index</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">items</span>.<span style="color: black;">insert</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, value<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #808080; font-style: italic;"># Add the new item to the top of the list.</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">items</span>.<span style="color: black;">insert</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, value<span style="color: black;">&#41;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">remove_items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">emit</span><span style="color: black;">&#40;</span>SIGNAL<span style="color: black;">&#40;</span><span style="color: #483d8b;">'dataChanged(QModelIndex, QModelIndex)'</span><span style="color: black;">&#41;</span>,
            <span style="color: #008000;">self</span>.<span style="color: black;">createIndex</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>, <span style="color: #008000;">self</span>.<span style="color: black;">createIndex</span><span style="color: black;">&#40;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">items</span><span style="color: black;">&#41;</span> - <span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">True</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> remove_items<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'
        Checks the number of items in the list and if it has been exceeded
        removes extra items.
        '</span><span style="color: #483d8b;">''</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">items</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span>gt<span style="color: #66cc66;">;</span> <span style="color: #008000;">self</span>.<span style="color: black;">MAX_ITEMS</span>:
            count = <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">items</span><span style="color: black;">&#41;</span> - <span style="color: #008000;">self</span>.<span style="color: black;">MAX_ITEMS</span>
            <span style="color: #ff7700;font-weight:bold;">del</span> <span style="color: #008000;">self</span>.<span style="color: black;">items</span><span style="color: black;">&#91;</span>-count:<span style="color: black;">&#93;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> order_items<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, index<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'
        Move the selected item tot he top of the list.
        '</span><span style="color: #483d8b;">''</span>
        <span style="color: #808080; font-style: italic;"># We only need to move the item to the top if it is not the first item.</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> index <span style="color: #66cc66;">&amp;</span>gt<span style="color: #66cc66;">;</span> <span style="color: #ff4500;">0</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">emit</span><span style="color: black;">&#40;</span>SIGNAL<span style="color: black;">&#40;</span><span style="color: #483d8b;">'layoutAboutToBeChanged()'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            value = <span style="color: #008000;">self</span>.<span style="color: black;">items</span><span style="color: black;">&#91;</span>index<span style="color: black;">&#93;</span>
            <span style="color: #ff7700;font-weight:bold;">del</span> <span style="color: #008000;">self</span>.<span style="color: black;">items</span><span style="color: black;">&#91;</span>index<span style="color: black;">&#93;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">items</span>.<span style="color: black;">insert</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, value<span style="color: black;">&#41;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">emit</span><span style="color: black;">&#40;</span>SIGNAL<span style="color: black;">&#40;</span><span style="color: #483d8b;">'layoutChanged()'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> MComboBox<span style="color: black;">&#40;</span>QComboBox<span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        QComboBox.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">setEditable</span><span style="color: black;">&#40;</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
        <span style="color: #808080; font-style: italic;"># The default policy is InsertAtBottom. InsertAtTop must be set</span>
        <span style="color: #808080; font-style: italic;"># otherwise the model will move the item to the top and the QComboBox</span>
        <span style="color: #808080; font-style: italic;"># will select the last index. In the case of reaching max items the</span>
        <span style="color: #808080; font-style: italic;"># index will be invalid because the removal is after the QComboBox has</span>
        <span style="color: #808080; font-style: italic;"># stored the value of the last index.</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">setInsertPolicy</span><span style="color: black;">&#40;</span>QComboBox.<span style="color: black;">InsertAtTop</span><span style="color: black;">&#41;</span>
        <span style="color: #808080; font-style: italic;"># Without this the QComboBox will not call set data for us to check</span>
        <span style="color: #808080; font-style: italic;"># for items already in the model if the item is a duplicate.</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">setDuplicatesEnabled</span><span style="color: black;">&#40;</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>._model = ComboModel<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">setModel</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>._model<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># We need to tell the model when an item is selected so it can be moved</span>
        <span style="color: #808080; font-style: italic;"># to the top of the history list.</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, SIGNAL<span style="color: black;">&#40;</span><span style="color: #483d8b;">'activated(int)'</span><span style="color: black;">&#41;</span>, <span style="color: #008000;">self</span>._model.<span style="color: black;">order_items</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    app = QApplication<span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
    bx = MComboBox<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    bx.<span style="color: black;">show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    app.<span style="color: black;">exec_</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>One thing to note is that in this example the model stores the items in a list called items. This can be replaced with some other way to retrieve the history items. For example with a connection to an SQLite DB.</p>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2009/07/23/history-drop-down-with-model/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>QCompleter and Comma-Separated Tags</title>
		<link>http://john.nachtimwald.com/2009/07/04/qcompleter-and-comma-separated-tags/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=qcompleter-and-comma-separated-tags</link>
		<comments>http://john.nachtimwald.com/2009/07/04/qcompleter-and-comma-separated-tags/#comments</comments>
		<pubDate>Sun, 05 Jul 2009 02:03:33 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[qt]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=161</guid>
		<description><![CDATA[Here is a python script demonstrating how to use QCompleter to complete multiple tags in a QLineEdit. A few features of this script are: removing tags from the drop down that already appear in the QLineEdit, caching the tags, and inserting a , after completion to ease adding more tags. There are a few parts [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a python script demonstrating how to use QCompleter to complete multiple tags in a QLineEdit. A few features of this script are: removing tags from the drop down that already appear in the QLineEdit, caching the tags, and inserting a , after completion to ease adding more tags. There are a few parts of this script that I&#8217;m going to go into detail about.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
&nbsp;
<span style="color: #483d8b;">''</span><span style="color: #483d8b;">'
Copyright (c) 2009 John Schember 
&nbsp;
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the &quot;Software&quot;), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
&nbsp;
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
&nbsp;
THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
'</span><span style="color: #483d8b;">''</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> PyQt4.<span style="color: black;">Qt</span> <span style="color: #ff7700;font-weight:bold;">import</span> Qt, QObject, QApplication, QLineEdit, QCompleter, \
    QStringListModel, SIGNAL
&nbsp;
TAGS = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'Nature'</span>, <span style="color: #483d8b;">'buildings'</span>, <span style="color: #483d8b;">'home'</span>, <span style="color: #483d8b;">'City'</span>, <span style="color: #483d8b;">'country'</span>, <span style="color: #483d8b;">'Berlin'</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> CompleterLineEdit<span style="color: black;">&#40;</span>QLineEdit<span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>:
        QLineEdit.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args<span style="color: black;">&#41;</span>
&nbsp;
        QObject.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, SIGNAL<span style="color: black;">&#40;</span><span style="color: #483d8b;">'textChanged(QString)'</span><span style="color: black;">&#41;</span>, <span style="color: #008000;">self</span>.<span style="color: black;">text_changed</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> text_changed<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, text<span style="color: black;">&#41;</span>:
        all_text = <span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span>text<span style="color: black;">&#41;</span>
        text = all_text<span style="color: black;">&#91;</span>:<span style="color: #008000;">self</span>.<span style="color: black;">cursorPosition</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
        prefix = text.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">','</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        text_tags = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> t <span style="color: #ff7700;font-weight:bold;">in</span> all_text.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">','</span><span style="color: black;">&#41;</span>:
            t1 = <span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span>t<span style="color: black;">&#41;</span>.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> t1 <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">''</span>:
                text_tags.<span style="color: black;">append</span><span style="color: black;">&#40;</span>t<span style="color: black;">&#41;</span>
        text_tags = <span style="color: #008000;">list</span><span style="color: black;">&#40;</span><span style="color: #008000;">set</span><span style="color: black;">&#40;</span>text_tags<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">emit</span><span style="color: black;">&#40;</span>SIGNAL<span style="color: black;">&#40;</span><span style="color: #483d8b;">'text_changed(PyQt_PyObject, PyQt_PyObject)'</span><span style="color: black;">&#41;</span>,
            text_tags, prefix<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> complete_text<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, text<span style="color: black;">&#41;</span>:
        cursor_pos = <span style="color: #008000;">self</span>.<span style="color: black;">cursorPosition</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        before_text = <span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">text</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>:cursor_pos<span style="color: black;">&#93;</span>
        after_text = <span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">text</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>cursor_pos:<span style="color: black;">&#93;</span>
        prefix_len = <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>before_text.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">','</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">setText</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s%s, %s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>before_text<span style="color: black;">&#91;</span>:cursor_pos - prefix_len<span style="color: black;">&#93;</span>, text,
            after_text<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">setCursorPosition</span><span style="color: black;">&#40;</span>cursor_pos - prefix_len + <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>text<span style="color: black;">&#41;</span> + <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> TagsCompleter<span style="color: black;">&#40;</span>QCompleter<span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent, all_tags<span style="color: black;">&#41;</span>:
        QCompleter.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, all_tags, parent<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">all_tags</span> = <span style="color: #008000;">set</span><span style="color: black;">&#40;</span>all_tags<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> update<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, text_tags, completion_prefix<span style="color: black;">&#41;</span>:
        tags = <span style="color: #008000;">list</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">all_tags</span>.<span style="color: black;">difference</span><span style="color: black;">&#40;</span>text_tags<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        model = QStringListModel<span style="color: black;">&#40;</span>tags, <span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">setModel</span><span style="color: black;">&#40;</span>model<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">setCompletionPrefix</span><span style="color: black;">&#40;</span>completion_prefix<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> completion_prefix.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">''</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">complete</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    app = QApplication<span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span>
&nbsp;
    editor = CompleterLineEdit<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    completer = TagsCompleter<span style="color: black;">&#40;</span>editor, TAGS<span style="color: black;">&#41;</span>
    completer.<span style="color: black;">setCaseSensitivity</span><span style="color: black;">&#40;</span>Qt.<span style="color: black;">CaseInsensitive</span><span style="color: black;">&#41;</span>
&nbsp;
    QObject.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>editor,
        SIGNAL<span style="color: black;">&#40;</span><span style="color: #483d8b;">'text_changed(PyQt_PyObject, PyQt_PyObject)'</span><span style="color: black;">&#41;</span>,
        completer.<span style="color: black;">update</span><span style="color: black;">&#41;</span>
    QObject.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>completer, SIGNAL<span style="color: black;">&#40;</span><span style="color: #483d8b;">'activated(QString)'</span><span style="color: black;">&#41;</span>,
        editor.<span style="color: black;">complete_text</span><span style="color: black;">&#41;</span>
&nbsp;
    completer.<span style="color: black;">setWidget</span><span style="color: black;">&#40;</span>editor<span style="color: black;">&#41;</span>
&nbsp;
    editor.<span style="color: black;">show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> app.<span style="color: black;">exec_</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Looking at the main() function the editor widget&#8217;s text_changed signal is connected to the completer&#8217;s update slot. This serves two purposes. It provides the completer with all tags that are in the editor. Also, it provides the completer with the prefix of the current text that is being entered. The prefix is used for listing matching tags that are stored in the completer&#8217;s cache.</p>
<p>editor&#8217;s complete_text function takes the text in the editor before the cursor and subtracts the length of the prefix from that position because the prefix will be included in the completed text. The text before, the completed text, a comma, a space, and the text after the cursor are combined. This becomes the text in the QLineEdit. The cursor is advanced the position it was at minus the length of the prefix and plus 2 characters (, ) so that typing can immediately continue.</p>
<p>TAGS can be replaced with a function that gets all relevant tags if caching is not wanted.</p>
<p>Also, note that completer.setWidget(editor) was used not QLineEdit&#8217;s setCompleter() function. If setCompleter is used completion will only take place at the beginning of the QLineEdit. Meaning it will match everything before as one string and ignore the , delimiter separating the tags.</p>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2009/07/04/qcompleter-and-comma-separated-tags/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Calibre Week in Review</title>
		<link>http://john.nachtimwald.com/2009/05/31/calibre-week-in-review-7/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=calibre-week-in-review-7</link>
		<comments>http://john.nachtimwald.com/2009/05/31/calibre-week-in-review-7/#comments</comments>
		<pubDate>Sun, 31 May 2009 23:45:49 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[calibre]]></category>
		<category><![CDATA[pyqt]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[qt]]></category>
		<category><![CDATA[rtf]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=128</guid>
		<description><![CDATA[Not much happened this week. A few bug fixes and a new output format, RTF. It produces acceptable results. It also embeds images into the file. The output could use some tweaking, but this will come with time. The only caveat is the output is ascii only. This is to keep compatibility with Cailbre&#8217;s RTF [...]]]></description>
			<content:encoded><![CDATA[<p>Not much happened this week. A few bug fixes and a new output format, RTF. It produces acceptable results. It also embeds images into the file. The output could use some tweaking, but this will come with time. The only caveat is the output is ascii only. This is to keep compatibility with Cailbre&#8217;s RTF intput which can only accept ascii rtf files.</p>
<p>Pluginize has been merged back into trunk. Once a bit of testing is done by Kovid, he will be rolling out a beta for the 0.6 release. For those of you, like me, who use Ubuntu and build Calibre from source, there is a little change you will need to make in order to have it build. Open the file /usr/lib/python2.6/dist-packages/PyQt4/uic/Compiler/qtproxies.py and modify _qwidgets on line 238 to include &#8220;QWizardPage&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2009/05/31/calibre-week-in-review-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

