<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="generator" content="Hugo 0.15" />
    <link rel="shortcut icon" href="/images/favicon.ico">
    
    <link href="/index.xml" rel="alternate" type="application/rss+xml" title="Superfluous Comments" />
    <link href="/index.xml" rel="feed" type="application/rss+xml" title="Superfluous Comments" />
    
    <meta name="viewport" content="width=device-width,initial-scale=1">
    
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">
    
    <script src="https://apis.google.com/js/platform.js" async defer>{lang: 'ja'}</script>
    
    <link rel="stylesheet" href="https://yandex.st/highlightjs/8.0/styles/default.min.css">
    <script src="https://yandex.st/highlightjs/8.0/highlight.min.js"></script>
    <script>hljs.initHighlightingOnLoad();</script>
    <link rel="stylesheet" type="text/css" href="/css/style.css">
    <title>ClojureScript in PyQt4 QWebView - False start | Superfluous Comments</title>
    <meta name="Description" content="Life is hard when you don&#39;t follow directions.
">
  </head>
  <body>
    <div id="wrap">
      
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-77704589-1', 'auto');
ga('send', 'pageview');
</script>

      <header class="site-header">
        <div class="site-header-left">
          <a class="site-header-title" href="http://kitsu.github.io/">Superfluous Comments</a>
        </div>
      </header>
      <div class="container">
        <div id="main">

<div class="article">
  <header>
    <div class="article-header">
      <h1>ClojureScript in PyQt4 QWebView - False start</h1>
      <div class="article-meta">
        <span class="posttime">2016/05/19</span>
        
<div class="tags">
  <ul>
    
    <li>
      <a href="/tags/clojurescript"><span></span>clojurescript</a>
    </li>
    
    <li>
      <a href="/tags/pyqt4"><span></span>pyqt4</a>
    </li>
    
    <li>
      <a href="/tags/lister"><span></span>lister</a>
    </li>
    
    <li>
      <a href="/tags/fail"><span></span>fail</a>
    </li>
    
  </ul>
</div>


      </div>
    </div>
  </header>
      
      <div class="adsense">
        <span class="sponsor-label">Sponsored link</span>
        <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>

<ins class="adsbygoogle"
     style="display:block"
     data-ad-client="ca-pub-3013534986949508"
     data-ad-slot="2442045076"
     data-ad-format="auto"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
      </div>
      
  <div class="content">
    <p>Life is hard when you don't follow directions.</p>

<p><hr/><br/>
I've started working on a testbed for CLJS embedded in a QWebView, creatively
named &quot;Testbed&quot;. I actually made quite a bit of progress, but I've decided to
scrap most of it. First though I'll break down what worked, my stupid mistakes,
and what I'm going to do instead.</p>

<p>The first step of the process was relatively easy. I just grabbed the most of
the Lister table widget and slapped it in a generic QMainWindow, and copied the
build script and spec file. Formatting the dummy data and stubbing out config
values were probably the hardest part.</p>

<p>Getting the ClojureScript build setup correctly on the other hand was much
harder than I expected. A lot has changed over the past months of ClojureScript
development. Creating a minimal ClojureScript build is actually much simpler
than when I last played with it. Several dumb mistakes, and the weird container
I'm shoe-horning it into, really tripped me up though.</p>

<p>I've always used <a href="http://leiningen.org/">Leiningen</a> for Clojure, and when I
first tried ClojureScript
<a href="https://github.com/emezeske/lein-cljsbuild">lein-cljsbuild</a> was the only
practical choice. ClojureScript recently had its version synced with Clojure
though, and grew the ability to eval and compile its own code. With all the
recent changes I figured I should start fresh with the new
<a href="https://github.com/clojure/clojurescript/wiki/Quick-Start">Quick Start Guide</a>.
If (unlike me) you manage to follow the directions everything works as
advertised BTW.</p>

<p>So Clojure is hosted on the JVM, and it has inherited some traits from its host,
and ClojureScript kept many of them. Due to mandates Java file structure Clojure
expects the shape of your file-system to match your namespace hierarchy. I
forgot this at first though and just threw my CLJS file in with all my Python
code. Using the Quick Start build instructions raised no errors, and produced an
output Javascript file. All the output was just boiler plate though, and no
executable code was produced. It wasn't until I tried advanced compilation that
I got an error message.</p>

<p>Even after making sub-folders and renaming my file the build still didn't
work. The other peculiarity of the file to namespace parity is that Clojure
prefers hyphens in code, while requiring <em>under scores</em> in the
file-system. Which I knew, and which was clearly stated in the Quick Start.</p>

<p>The next problem I ran into was getting the generated file and all the library
output to load correctly. I played around with my working directory and the
build function's <code>:output-dir</code> and <code>:asset-path</code> settings, but nothing worked.
I'm pretty sure it had to do with how the embedded WebKit browser was resolving
resource paths. <del>Judging from a
<a href="http://stackoverflow.com/search?q=%5Bqwebview%5D+resources">StackOverflow search</a>
it seems like it is a common problem with QWebKit (Note <a href="http://doc.qt.io/qt-5/portingguide.html">QWebKit is being
replaced in Qt5</a>).</del>
Edit: <a href="http://doc.qt.io/qt-4.8/qwebview.html#setHtml">looks like</a> I needed to
provide a second argument to <code>setHtml</code> of <code>baseUrl=QUrl(&quot;File://&quot;)</code> so local
resources resolve. Regardless, advanced compilation to the rescue again - when
the only output is the file you're already including manually it is pretty easy
to get right.</p>

<p>And with that it all worked, even when complied to an Windows exe. After
overcoming all that trouble though it just took one small thing to send me
running back to Lein. At the very bottom of the Quick Start is a short section
on <em>Dependencies</em>, and after a short preamble about
<a href="http://cljsjs.github.io/">CLJSJS</a> (which is awesome)
and how to require another namespace in your code, they reveal the default
stand-alone solution for ClojureScript dependency management: String
concatenation onto the build command...</p>

<p>Seriously? Lein, Clojars, Maven, the deps management story in Clojure was one of
my favorite features. I totally expected this magic stand-alone <code>CLJS.jar</code> to
just have that stuff baked in. Just one more vector in the build map. Not to
diminish the current state of the magic jar - Getting started with ClojureScript
is so much easier and better now. But, unless you have very limited goals, Lein
(or Boot) should be your first stop after hello world.</p>

<p>So that is my plan for tomorrow. Setup a Lein project using some template
(Figwheel?), and then integrate my Python code into a Lein project instead. I
bet I can make a pretty cool PyInstaller task for Lein too.</p>

  </div>
  <footer>
    <div class="article-footer">
      
<div class="tags">
  <ul>
    
    <li>
      <a href="/tags/clojurescript"><span></span>clojurescript</a>
    </li>
    
    <li>
      <a href="/tags/pyqt4"><span></span>pyqt4</a>
    </li>
    
    <li>
      <a href="/tags/lister"><span></span>lister</a>
    </li>
    
    <li>
      <a href="/tags/fail"><span></span>fail</a>
    </li>
    
  </ul>
</div>


      
      <div class="adsense">
        <span class="sponsor-label">Sponsored link</span>
        <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>

<ins class="adsbygoogle"
     style="display:block"
     data-ad-client="ca-pub-3013534986949508"
     data-ad-slot="2442045076"
     data-ad-format="auto"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
      </div>
      
      
<div id="share-buttons">
  <ul>
    
    
    
    
    <li>
      <div class="g-plusone" data-size="medium"></div>
    </li>
    
    
  </ul>
</div>


      <div id="disqus_thread"></div>
<script type="text/javascript">
    var disqus_shortname = 'SuperfComs';
    var disqus_identifier = 'http:\/\/kitsu.github.io\/2016\/05\/19\/pyqt_cljs_01\/';
    var disqus_title = 'ClojureScript in PyQt4 QWebView - False start';
    var disqus_url = 'http:\/\/kitsu.github.io\/2016\/05\/19\/pyqt_cljs_01\/';

    (function() {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
      
      <div id="pagenavigation-next-prev">
        
        <div id="pagenavigation-next">
          <span class="pagenav-label">Previous</span>
          <a href="http://kitsu.github.io/2016/05/18/functional-html/">Generating HTML on the fly in Python</a>
        </div>
        
        
        <div id="pagenavigation-prev">
          <span class="pagenav-label">Next</span>
          <a href="http://kitsu.github.io/2016/05/20/pyqt4_cljs_02/">ClojureScript in PyQt4 QWebView - Success</a>
        </div>
        
      </div>
      
    </div>
  </footer>
</div>
        </div>
        <div class="sidebar">
  
  <div class="sidebar-content">
    <div class="sidebar-header">
      <span>Author</span>
    </div>
    <div id="author">
      <span>Ed Blake</span>
      <div>
        
        
        <a href="https://plus.google.com/118323029386640613972"><i class="fa fa-google-plus-square fa-2x" aria-hidden="true"></i></a>
        
        
        <a href="https://github.com/kitsu"><i class="fa fa-github-square fa-2x" aria-hidden="true"></i></a>
        
        
        <a href="https://www.linkedin.com/in/edward-blake-b3601411b"><i class="fa fa-linkedin-square fa-2x" aria-hidden="true"></i></a>
        
        
        <a href="https://stackoverflow.com/users/770443"><i class="fa fa-stack-overflow fa-2x" aria-hidden="true"></i></a>
        
      </div>
    </div>
  </div>
  
  
  <div class="sidebar-content">
    <div class="sidebar-header">
      <span>Categories</span>
    </div>
    <div class="categories">
      <ul>
        
        <li>
          <a href="/categories/blog"><span></span>blog (3)</a>
        </li>
        
        <li>
          <a href="/categories/development"><span></span>development (34)</a>
        </li>
        
        <li>
          <a href="/categories/hacks"><span></span>hacks (5)</a>
        </li>
        
        <li>
          <a href="/categories/personal"><span></span>personal (3)</a>
        </li>
        
      </ul>
    </div>
  </div>
  
  <div class="sidebar-content">
    <div class="sidebar-header">
      <span>RSS</span>
    </div>
    <div id="rss">
      <a href="/index.xml" type="application/rss+xml" target="_blank">
        <i class="fa fa-rss-square fa-2x" aria-hidden="true"></i>
      </a>
    </div>
  </div>
  
  <div class="sidebar-content">
    <div class="sidebar-header">
      <span>Sponsored link</span>
    </div>
    <div class="adsense">
      <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>

<ins class="adsbygoogle"
     style="display:inline-block;width:300px;height:600px"
     data-ad-client="ca-pub-3013534986949508"
     data-ad-slot="9965311870"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
    </div>
  </div>
  
</div>

      </div>
      <footer>
        <div id="site-footer-wrap">
          <div id="site-footer">
            <span>Powered by <a href="https://gohugo.io/">Hugo</a>.</span>
            <span>
              
              © 2015 Ed Blake
              
           </span>
           <span id="copyleft">
              <a rel="license"
                 href="http://creativecommons.org/licenses/by-sa/4.0/">
                <img alt="Creative Commons License" style="border-width:0"
                     src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" />
              </a>
            </span>
          </div>
        </div>
      </footer>
    </div>
  </body>
</html>

