<?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; qt</title>
	<atom:link href="http://john.nachtimwald.com/tag/qt/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>Retrieve Formatting Set by QSyntaxHighlighter</title>
		<link>http://john.nachtimwald.com/2011/10/29/retrieve-formatting-set-by-qsyntaxhighlighter/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=retrieve-formatting-set-by-qsyntaxhighlighter</link>
		<comments>http://john.nachtimwald.com/2011/10/29/retrieve-formatting-set-by-qsyntaxhighlighter/#comments</comments>
		<pubDate>Sat, 29 Oct 2011 12:33:04 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[qt]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=977</guid>
		<description><![CDATA[I have been working on adding inline spell check to Sigil recently and ran into a quirk on Qt that isn&#8217;t immediately obvious. I ended up having to look though the Qt source code to understand exactly what was happening. When dealing with a QPlainTextEdit you can get the QTextCursor and use the charFormat() function [...]]]></description>
			<content:encoded><![CDATA[<p>I have been working on adding inline spell check to Sigil recently and ran into a quirk on Qt that isn&#8217;t immediately obvious. I ended up having to look though the Qt source code to understand exactly what was happening.</p>
<p>When dealing with a QPlainTextEdit you can get the QTextCursor and use the charFormat() function to retrieve the QTextCharFormat for the character before the cursor. This <b>does not work</b> when the formatting is set by a QSyntaxHighlighter!.</p>
<p>charFormat retrieves the character format that has explicitly been set on the QPlainTextEdit. QSyntaxHighlighter does not directly set the formatting on the QPlainTextEdit. Instead QSyntaxHighlighter sets the format in additionalFormats as part of the block layout. All formatting for the block the cursor is currently in can be accessed by using QPlainTextEdit::textCursor().block().layout()->additionalFormats().</p>
<p>QTextLayout::additionalFormats() returns a list of <a href="http://doc.qt.nokia.com/latest/qtextlayout-formatrange.html">FormatRange</a> objects. A FormatRange gives the start of the formatting (relative to the block not the full text in the QPlainTextEdit), the length and the formatting (as set by the QSyntaxHighlighter). Simply loop over all of the FormatRange objects and check if the cursor is within a range to determine what formatting is applied to a particular part of the block&#8217;s text. Use QTextCursor::positionInBlock() to determine the relative position of the cursor within the block.</p>
<p>Here is an example from Sigil that I use for spell checking. It determines if a particular segment of text has the misspelled word style applied to it. It then selects the text.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">QTextCursor c <span style="color: #000080;">=</span> textCursor<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">int</span> pos <span style="color: #000080;">=</span> c.<span style="color: #007788;">positionInBlock</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
foreach <span style="color: #008000;">&#40;</span>QTextLayout<span style="color: #008080;">::</span><span style="color: #007788;">FormatRange</span> r, textCursor<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">block</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">layout</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>additionalFormats<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>pos <span style="color: #000080;">&gt;=</span> r.<span style="color: #007788;">start</span> <span style="color: #000040;">&amp;&amp;</span> pos <span style="color: #000080;">&lt;=</span> r.<span style="color: #007788;">start</span> <span style="color: #000040;">+</span> r.<span style="color: #007788;">length</span> <span style="color: #000040;">&amp;&amp;</span> r.<span style="color: #007788;">format</span>.<span style="color: #007788;">underlineStyle</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">==</span> QTextCharFormat<span style="color: #008080;">::</span><span style="color: #007788;">SpellCheckUnderline</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        c.<span style="color: #007788;">setPosition</span><span style="color: #008000;">&#40;</span>c.<span style="color: #007788;">block</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">position</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">+</span> r.<span style="color: #007788;">start</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        c.<span style="color: #007788;">movePosition</span><span style="color: #008000;">&#40;</span>QTextCursor<span style="color: #008080;">::</span><span style="color: #007788;">Right</span>, QTextCursor<span style="color: #008080;">::</span><span style="color: #007788;">KeepAnchor</span>, r.<span style="color: #007788;">length</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        setTextCursor<span style="color: #008000;">&#40;</span>c<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p><b>*</b>Note: QTextEdit can be substituted any place QPlainTextEdit is used. This applies to both not just QPlainTextEdit.</p>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2011/10/29/retrieve-formatting-set-by-qsyntaxhighlighter/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sigil Now Supports Translations</title>
		<link>http://john.nachtimwald.com/2011/10/08/sigil-now-supports-translations/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sigil-now-supports-translations</link>
		<comments>http://john.nachtimwald.com/2011/10/08/sigil-now-supports-translations/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 22:37:22 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Sigil]]></category>
		<category><![CDATA[internationalization]]></category>
		<category><![CDATA[language]]></category>
		<category><![CDATA[qt]]></category>
		<category><![CDATA[translations]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=973</guid>
		<description><![CDATA[One of the the new features that has been implemented for 0.5 (release date yet to be determined) is support for Translations. For Sigil&#8217;s first supported language Grzegorz Wolszczak has provided a Polish translation. Currently translations are loaded based upon the current system locale. There no support for choosing the language via preferences. This may [...]]]></description>
			<content:encoded><![CDATA[<p>One of the the new features that has been implemented for 0.5 (release date yet to be determined) is support for Translations. For Sigil&#8217;s first supported language Grzegorz Wolszczak has provided a Polish translation. Currently translations are loaded based upon the current system locale. There no support for choosing the language via preferences. This may come at a later time but for now I believe that using the system locale will handle the majority of user needs.</p>
<p>I&#8217;ve put together a wiki page with <a href="http://code.google.com/p/sigil/wiki/Translating">instructions</a> for creating translations. This first revision is a bit basic but as people have questions I plan to update it to make it more robust.</p>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2011/10/08/sigil-now-supports-translations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Qt Remove Directory and Its Contents</title>
		<link>http://john.nachtimwald.com/2010/06/08/qt-remove-directory-and-its-contents/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=qt-remove-directory-and-its-contents</link>
		<comments>http://john.nachtimwald.com/2010/06/08/qt-remove-directory-and-its-contents/#comments</comments>
		<pubDate>Tue, 08 Jun 2010 12:47:28 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[qt]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=391</guid>
		<description><![CDATA[When dealing with directories, Qt has a large number of functions to make manipulating them easy. However, it does not include a way to delete a non-empty directory. This little omission is easily solved. Following is a recursive function that will delete a directory along with all of it&#8217;s contents. This will delete depth first. [...]]]></description>
			<content:encoded><![CDATA[<p>When dealing with directories, Qt has a large number of functions to make manipulating them easy. However, it does not include a way to delete a non-empty directory. This little omission is easily solved.</p>
<p>Following is a recursive function that will delete a directory along with all of it&#8217;s contents. This will delete depth first. Meaning it will recurse into sub-directories and only start deleting once the directory has no sub-directories. Changing QDir::DirsFirst to QDir::DirsLast will change this into a breadth first search.</p>
<p>fileutils.h</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#ifndef FILEUTILS_H</span>
<span style="color: #339900;">#define FILEUTILS_H</span>
&nbsp;
<span style="color: #339900;">#include &lt;QString&gt;</span>
&nbsp;
<span style="color: #0000ff;">class</span> FileUtils
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> removeDir<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> QString <span style="color: #000040;">&amp;</span>dirName<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#endif // FILEUTILS_H</span></pre></div></div>

<p>fileutils.cpp</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;QDir&gt;</span>
<span style="color: #339900;">#include &lt;QFile&gt;</span>
<span style="color: #339900;">#include &lt;QFileInfo&gt;</span>
<span style="color: #339900;">#include &lt;QFileInfoList&gt;</span>
&nbsp;
<span style="color: #339900;">#include &quot;fileutils.h&quot;</span>
&nbsp;
<span style="color: #ff0000; font-style: italic;">/*!
   Delete a directory along with all of its contents.
&nbsp;
   \param dirName Path of directory to remove.
   \return true on success; false on error.
*/</span>
<span style="color: #0000ff;">bool</span> FileUtils<span style="color: #008080;">::</span><span style="color: #007788;">removeDir</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> QString <span style="color: #000040;">&amp;</span>dirName<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">bool</span> result <span style="color: #000080;">=</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
    QDir dir<span style="color: #008000;">&#40;</span>dirName<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>dir.<span style="color: #007788;">exists</span><span style="color: #008000;">&#40;</span>dirName<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        Q_FOREACH<span style="color: #008000;">&#40;</span>QFileInfo info, dir.<span style="color: #007788;">entryInfoList</span><span style="color: #008000;">&#40;</span>QDir<span style="color: #008080;">::</span><span style="color: #007788;">NoDotAndDotDot</span> <span style="color: #000040;">|</span> QDir<span style="color: #008080;">::</span><span style="color: #007788;">System</span> <span style="color: #000040;">|</span> QDir<span style="color: #008080;">::</span><span style="color: #007788;">Hidden</span>  <span style="color: #000040;">|</span> QDir<span style="color: #008080;">::</span><span style="color: #007788;">AllDirs</span> <span style="color: #000040;">|</span> QDir<span style="color: #008080;">::</span><span style="color: #007788;">Files</span>, QDir<span style="color: #008080;">::</span><span style="color: #007788;">DirsFirst</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>info.<span style="color: #007788;">isDir</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
                result <span style="color: #000080;">=</span> removeDir<span style="color: #008000;">&#40;</span>info.<span style="color: #007788;">absoluteFilePath</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
            <span style="color: #008000;">&#125;</span>
            <span style="color: #0000ff;">else</span> <span style="color: #008000;">&#123;</span>
                result <span style="color: #000080;">=</span> QFile<span style="color: #008080;">::</span><span style="color: #0000dd;">remove</span><span style="color: #008000;">&#40;</span>info.<span style="color: #007788;">absoluteFilePath</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>result<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
                <span style="color: #0000ff;">return</span> result<span style="color: #008080;">;</span>
            <span style="color: #008000;">&#125;</span>
        <span style="color: #008000;">&#125;</span>
        result <span style="color: #000080;">=</span> dir.<span style="color: #007788;">rmdir</span><span style="color: #008000;">&#40;</span>dirName<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> result<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2010/06/08/qt-remove-directory-and-its-contents/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>lebookread</title>
		<link>http://john.nachtimwald.com/2010/05/16/lebookread/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lebookread</link>
		<comments>http://john.nachtimwald.com/2010/05/16/lebookread/#comments</comments>
		<pubDate>Mon, 17 May 2010 01:52:56 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[lebookread]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[epub]]></category>
		<category><![CDATA[palmdoc]]></category>
		<category><![CDATA[pdb]]></category>
		<category><![CDATA[qt]]></category>
		<category><![CDATA[rb]]></category>
		<category><![CDATA[ztxt]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=358</guid>
		<description><![CDATA[I have been taking a short break from blogging again. The pressure at work has only increased and is eating into a lot of my time. I haven&#8217;t been motivated to work on personal projects because well they are work. However, this has recently changed a bit. I&#8217;ve started a Qt based library for reading [...]]]></description>
			<content:encoded><![CDATA[<p>I have been taking a short break from blogging again. The pressure at work has only increased and is eating into a lot of my time. I haven&#8217;t been motivated to work on personal projects because well they are work. However, this has recently changed a bit.</p>
<p>I&#8217;ve started a Qt based library for reading ebooks in a generic manner. It is called <a href="https://launchpad.net/lebookread">lebookread</a>! It is it&#8217;s early stages. So far I have it supporting epub, palmdoc pdb, ztxt pdb, tcr, and rb files. I plan to support ereader pdb, mobi, and plucker files in the near future.</p>
<p>The main goal of this project is to make reading ebooks easy for Qt based projects. I&#8217;ve chose to write the library in C++. This is also my first attempt at writing a library and it shows. I hope that it will be used by <a href="http://code.google.com/p/sigil/">Sigil</a>.</p>
<p>The real motivation of writing lebook read is I really want a good light weight ebook reader. The current offering have issues. I want something that is a bit more advanced in it&#8217;s rendering than <a href="http://www.fbreader.org/">FBReader</a>. I also didn&#8217;t want anything with as large a dependency list as <a href="http://calibre-ebook.com/">calibre</a>. So, I plan on using lebookread to write my own ebook viewer.</p>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2010/05/16/lebookread/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>KDocker 4.2 released</title>
		<link>http://john.nachtimwald.com/2009/09/27/kdocker-4-2-released/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=kdocker-4-2-released</link>
		<comments>http://john.nachtimwald.com/2009/09/27/kdocker-4-2-released/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 14:13:30 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[KDocker]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[qt]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=228</guid>
		<description><![CDATA[This release includes bug fixes as usual. Some new features: bash completion, iconify on focus lost option and Italian translation thanks to Alessio Cassibba. There is also a small change to the behavior when activating the tray icon. If the window is not visible it will become active and if it is active it will [...]]]></description>
			<content:encoded><![CDATA[<p>This release includes bug fixes as usual. Some new features: bash completion, iconify on focus lost option and Italian translation thanks to Alessio Cassibba. There is also a small change to the behavior when activating the tray icon. If the window is not visible it will become active and if it is active it will iconify. You can get it at the <a href="https://launchpad.net/kdocker">launchpad page</a>.</p>
<p>Somehow I forget to mention the 4.1 release last week&#8230; I don&#8217;t think I&#8217;m going to be getting into the habit of making a release each week but there is still more I have planned. Mostly refactoring, and not to much in the way of new features.</p>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2009/09/27/kdocker-4-2-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>KDocker 4.0</title>
		<link>http://john.nachtimwald.com/2009/09/16/kdocker-4-0/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=kdocker-4-0</link>
		<comments>http://john.nachtimwald.com/2009/09/16/kdocker-4-0/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 11:43:12 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[KDocker]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[qt]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=224</guid>
		<description><![CDATA[Recently I&#8217;ve become the maintainer of the KDocker project. KDocker is a Qt application what allows you dock any application into the system tray. It currently supports any X Windows system. What I&#8217;ve done for the 4.0 release is, move the project to launchpad (Girish, the creator of the project is locked out of the [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I&#8217;ve become the maintainer of the KDocker project. KDocker is a Qt application what allows you dock any application into the system tray. It currently supports any X Windows system. What I&#8217;ve done for the 4.0 release is, move the project to launchpad (Girish, the creator of the project is locked out of the Source Forge page) and port/re-write the entire app to use Qt 4.</p>
<p>The port/re-write to Qt 4 is complete and I&#8217;ve released it. The version has jumped from 1.3 to 4.0 to better illustrate the the severity of this change. Also, it takes it to a similar version scheme to Qt and KDE.</p>
<p>There are a few things to note about this release and KDocker in general. For this release session management and auto starting have been removed. This is mainly because modern desktop environments support both of these very well. Also, I believe that environments that do not support this are better of using a dedicated application instead of having the functionality rolled into a docker. Another point to note is KDocker 4.0 as well as the older version are pure Qt and Xlib applications. They do not depend on KDE.</p>
<p>The new project location is at <a href="https://launchpad.net/kdocker">https://launchpad.net/kdocker</a> and you can download the 4.0 release at <a href="https://launchpad.net/kdocker/+download">https://launchpad.net/kdocker/+download</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2009/09/16/kdocker-4-0/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>
	</channel>
</rss>

