<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Recent changes to PyQt</title><link>https://sourceforge.net/p/blur-dev/wiki/PyQt/</link><description>Recent changes to PyQt</description><atom:link href="https://sourceforge.net/p/blur-dev/wiki/PyQt/feed" rel="self"/><language>en</language><lastBuildDate>Sat, 08 Feb 2014 00:16:57 -0000</lastBuildDate><atom:link href="https://sourceforge.net/p/blur-dev/wiki/PyQt/feed" rel="self" type="application/rss+xml"/><item><title>PyQt modified by Anonymous</title><link>https://sourceforge.net/p/blur-dev/wiki/PyQt/</link><description>&lt;div class="markdown_content"&gt;&lt;h1 id="introduction-to-pyqt"&gt;Introduction to &lt;a class="" href="/p/blur-dev/wiki/PyQt/"&gt;PyQt&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;If you are completely new to Python and/or &lt;a class="" href="/p/blur-dev/wiki/PyQt/"&gt;PyQt&lt;/a&gt;, then I would recommend working through some online tutorials - there are a TON of them out there. &lt;/p&gt;
&lt;p&gt;This tutorial is about working with &lt;a class="" href="/p/blur-dev/wiki/PyQt/"&gt;PyQt&lt;/a&gt; as it relates to the Blur systems, not a basic introduction to &lt;a class="" href="/p/blur-dev/wiki/PyQt/"&gt;PyQt&lt;/a&gt; in general. &lt;/p&gt;
&lt;p&gt;The tutorials on this page are for generic development - everything in these docs can and does apply to code for 3dsMax and Softimage - as the system we developed is application agnostic. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Introduction to&lt;ul&gt;
&lt;li&gt;Pre-requistes&lt;/li&gt;
&lt;li&gt;Hello, World&lt;/li&gt;
&lt;li&gt;Dialog vs. QDialog&lt;/li&gt;
&lt;li&gt;blurdev.launch&lt;/li&gt;
&lt;li&gt;Running the Example&lt;/li&gt;
&lt;li&gt;Building Tools&lt;/li&gt;
&lt;li&gt;Creating Categories&lt;/li&gt;
&lt;li&gt;Creating Tools&lt;/li&gt;
&lt;li&gt;IDE Tool Wizard&lt;/li&gt;
&lt;li&gt;Running the Tool&lt;/li&gt;
&lt;li&gt;Modifying the Interface&lt;/li&gt;
&lt;li&gt;Running through Treegrunt&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2 id="pre-requistes"&gt;Pre-requistes&lt;/h2&gt;
&lt;p&gt;I'm assuming that you've read through the &lt;a class="" href="/p/blur-dev/wiki/BlurIDE/"&gt;BlurIDE&lt;/a&gt; documentation and are setup with the BlurOffline code project. &lt;/p&gt;
&lt;h2 id="hello-world"&gt;Hello, World&lt;/h2&gt;
&lt;p&gt;Everyone's favorite - Hello World. &lt;/p&gt;
&lt;p&gt;For this example, we'll go into a couple of differences between the basics of &lt;a class="" href="/p/blur-dev/wiki/PyQt/"&gt;PyQt&lt;/a&gt; and the system that we have in place. &lt;/p&gt;
&lt;p&gt;First up, fire open your IDE Editor (can be standalone, or in an application of choice) and make sure we are in the BlurOffline project. &lt;/p&gt;
&lt;p&gt;Click &lt;code&gt;Ctrl+N&lt;/code&gt; or &lt;code&gt;File &amp;gt;&amp;gt; New&lt;/code&gt; and type: &lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;blurdev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gui&lt;/span&gt; &lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Dialog&lt;/span&gt;

&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="n"&gt;HelloWorldDialog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Dialog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;def&lt;/span&gt; &lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;None&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;Dialog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setWindowTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;World&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;blurdev&lt;/span&gt;
&lt;span class="n"&gt;blurdev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HelloWorldDialog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Save this file to &lt;code&gt;c:/blur/dev/offline/code/python/scripts/test.py&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="dialog-vs-qdialog"&gt;Dialog vs. QDialog&lt;/h3&gt;
&lt;p&gt;The first thing to note, is our first line. &lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;blurdev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gui&lt;/span&gt; &lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Dialog&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We're importing our own &lt;code&gt;Dialog&lt;/code&gt; class, not a standard &lt;code&gt;PyQt4.QtGui.QDialog&lt;/code&gt; class. &lt;/p&gt;
&lt;p&gt;In fact, the &lt;code&gt;Dialog&lt;/code&gt; class inherits from the standard &lt;code&gt;QDialog&lt;/code&gt; class, but it also provides some important wrapper code around it. The wrapper code works with the blurdev/core logic to determine the proper parenting based on the application it's running in. &lt;/p&gt;
&lt;p&gt;When standalone, no parent is needed, but if running within 3dsMax for instance, a Dialog MUST be a child of a &lt;code&gt;QWinWidget&lt;/code&gt; class. Rather than making the developer check for the proper parenting, we just wrote our own base class to support it. &lt;/p&gt;
&lt;p&gt;We did this for the 3 base classes that we'll use when developing tools: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;blurdev.gui.Dialog&lt;/code&gt; vs. &lt;code&gt;PyQt4.QtGui.QDialog&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blurdev.gui.Window&lt;/code&gt; vs. &lt;code&gt;PyQt4.QtGui.QWindow&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blurdev.gui.Wizard&lt;/code&gt; vs. &lt;code&gt;PyQt4.QtGui.QWizard&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A couple of notes about the differences between the 3: &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A Dialog can be run modally &lt;/li&gt;
&lt;li&gt;A Window contains a menu bar by default, but cannot be run modally &lt;/li&gt;
&lt;li&gt;A Wizard will drive a multi-step process. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is obviously a dumbed down version of the differences between the 3, but is most often what drives our decision when to use each. &lt;/p&gt;
&lt;h3 id="blurdevlaunch"&gt;blurdev.launch&lt;/h3&gt;
&lt;p&gt;The next thing to note from this example is the way that we run the tool. &lt;/p&gt;
&lt;p&gt;The last line of code for this example calls &lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="n"&gt;blurdev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HelloWorldDialog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What the &lt;code&gt;blurdev.launch&lt;/code&gt; code is doing for us is managing the QApplication system. &lt;/p&gt;
&lt;p&gt;In a standard &lt;a class="" href="/p/blur-dev/wiki/PyQt/"&gt;PyQt&lt;/a&gt; application, a developer would have to maintain their application instance, however, there can only ever be 1 instance of a QApplication running per thread. &lt;/p&gt;
&lt;p&gt;In the case of 3dsMax and Softimage, we'll have 1 QApplication instance running for ALL tools that are created. When we're running standalone though, we're going to have 1 QApplication PER tool. &lt;/p&gt;
&lt;p&gt;Again, to abstract our code to be able to work in multiple applications, it was easiest to build the system into the core to maintain the application instancing. &lt;/p&gt;
&lt;p&gt;By calling &lt;code&gt;blurdev.launch&lt;/code&gt; on your dialog, this will allow you to develop a tool that can run both IN and OUT of another application. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note: You only need to do this for your root dialogs. If you have say, an About dialog that is a sub-dialog of your main Tool, you can just show it in a standard Qt way&lt;/strong&gt;. &lt;/p&gt;
&lt;h3 id="running-the-example"&gt;Running the Example&lt;/h3&gt;
&lt;p&gt;So, what does this all mean? Lets give it a test. &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Navigate to &lt;code&gt;python/scripts&lt;/code&gt; in your IDE &lt;/li&gt;
&lt;li&gt;Right-click on &lt;code&gt;test.py&lt;/code&gt; and choose &lt;code&gt;Run&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This will launch your dialog, and you'll notice that it is parented to the IDE Editor (if running standalone) or your application window (if running in 3dsMax or Softimage). &lt;/p&gt;
&lt;p&gt;This is because its running within the current thread, which already has a QApplication instance running, and so parents to the root window. &lt;/p&gt;
&lt;p&gt;Now try: &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Right-click on &lt;code&gt;test.py&lt;/code&gt; and choose &lt;code&gt;Run (Standalone)&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This will run your script as its own application - so it actually creates a full standalone application, creating its own QApplication and runs within its own thread. &lt;/p&gt;
&lt;p&gt;This now runs outside of the IDE editor and/or application. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note: if you are building tools that need to access information inside of an application like 3dsMax or Softimage, they CANNOT access the &lt;a class="" href="/p/blur-dev/wiki/Py3dsMax/"&gt;Py3dsMax&lt;/a&gt; or PySoftimage libraries, so you have to program accordingly.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note 2: if you choose &lt;code&gt;Run (Debug)&lt;/code&gt; it is the same as running standalone, except that you'll get the command prompt window as well.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="building-tools"&gt;Building Tools&lt;/h2&gt;
&lt;p&gt;Before we get into developing tools, you should read up on how the &lt;a class="" href="../ToolsEnvironments"&gt;a tool is structured&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Once you have a grasp of what a Tool &lt;em&gt;is&lt;/em&gt;, lets create a more advanced script than our Hello, World example from above - this time, lets create a new tool. &lt;/p&gt;
&lt;h3 id="creating-categories"&gt;Creating Categories&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Navigate to &lt;code&gt;BlurOffline/code/python/tools/General_Use_Tools&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Right-click on &lt;code&gt;General_Use_Tools&lt;/code&gt; and choose &lt;code&gt;New Folder&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Type in &lt;code&gt;_Examples&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This will create a new folder at: &lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="nl"&gt;c:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;blur&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;offline&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;General_Use_Tools&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;_Examples&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Thats all you have to do to create a new category - create a new folder within the &lt;code&gt;tools&lt;/code&gt; folder. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note: For readability, its recommended to start categories with an underscore.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="creating-tools"&gt;Creating Tools&lt;/h3&gt;
&lt;p&gt;You could create a folder the way you just did, and then create a &lt;code&gt;__meta__.xml&lt;/code&gt; file within it with the proper settings...but thats just not fun... &lt;/p&gt;
&lt;h3 id="ide-tool-wizard"&gt;IDE Tool Wizard&lt;/h3&gt;
&lt;p&gt;Instead of forcing a developer to remember everything that goes into a Tool, it was much easier to build a Wizard that we could reuse. &lt;/p&gt;
&lt;p&gt;With that in mind, we built a robust and extensible wizard system into the IDE Editor. &lt;/p&gt;
&lt;p&gt;We have wizards for creating more Wizards, creating tools Environments, gui components, and for Tools. &lt;/p&gt;
&lt;p&gt;This time, right click on your &lt;code&gt;_Examples&lt;/code&gt; folder and choose &lt;code&gt;New From Wizard&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This will bring up the Wizard chooser dialog. Since right now we're creating a new tool, lets choose: &lt;/p&gt;
&lt;p&gt;&lt;code&gt;User Interface&lt;/code&gt; and then &lt;code&gt;Tool&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The Wizard you'll see will give you a couple of options. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The button on the left will let you choose the icon for your tool &lt;/li&gt;
&lt;li&gt;Name field will be the name of your tool &lt;/li&gt;
&lt;li&gt;Choosing simple script will build the tool with no GUI, and just register code to run within your &lt;code&gt;main.pyw&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Base Class field lets you choose from the 3 basic Tools UI options (Dialog,Window,Wizard) &lt;/li&gt;
&lt;li&gt;Create Ui File will alter whether or not to create a Qt Designer file for you GUI, or if you want to define it programmatically &lt;/li&gt;
&lt;li&gt;Description is just the tooltip for your new tool &lt;/li&gt;
&lt;li&gt;ToolTypes registers where this tool can be run from. As we'll show, you can actually develop a single tool that can run in 3dsMax, Softimage and External applications. Extensions for Maya and Houdini are easily created, we just don't support them at Blur. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For now, lets set: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;name&lt;/strong&gt; SampleTool &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;toolTypes&lt;/strong&gt; External, Studiomax, Softimage &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;description&lt;/strong&gt; Sample tool for learning the IDE &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We'll leave the other settings as they are by default (if you want to choose an icon, go ahead and do so). &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Click &lt;code&gt;Continue&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The next page you'll see will outline the files and folders that will be created for your wizard. You'll see this as the last page for all IDE Wizards, so you can always preview your files before you create them. &lt;/p&gt;
&lt;p&gt;Only checked files will be created, so if for whatever reason you don't need or want certain files or folders, you can disable them through this view. &lt;/p&gt;
&lt;p&gt;If you want to see the difference between what gets created, you can click back and toggle the &lt;strong&gt;simple script&lt;/strong&gt; and/or &lt;strong&gt;create ui file&lt;/strong&gt; fields, and this will alter the template for the tool that gets created. &lt;/p&gt;
&lt;p&gt;For now, we'll just create with the standard settings, so click &lt;code&gt;Done&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;You'll then be prompted if you want to change projects - when a tool gets created, it actually makes a new IDE Project specifically for that tool. &lt;/p&gt;
&lt;p&gt;For now, click no - we'll just stay in the current project. &lt;/p&gt;
&lt;h3 id="running-the-tool"&gt;Running the Tool&lt;/h3&gt;
&lt;p&gt;If you expand the &lt;code&gt;_Examples&lt;/code&gt; folder, you'll now see your &lt;code&gt;SampleTool&lt;/code&gt; tool folder, and all the files from the Wizard are setup for you. &lt;/p&gt;
&lt;p&gt;If you right click on the &lt;code&gt;main.pyw&lt;/code&gt; file and choose any of the three: &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Run &lt;/li&gt;
&lt;li&gt;Run (Standalone) &lt;/li&gt;
&lt;li&gt;Run (Debug) &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can see your tool running as a child of the IDE Editor, and/or as a standalone application. &lt;/p&gt;
&lt;p&gt;All you'll see right now is a blank Dialog with the title &lt;code&gt;SampleTool&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="modifying-the-interface"&gt;Modifying the Interface&lt;/h3&gt;
&lt;p&gt;Pretty simple to get started, but also boring. &lt;/p&gt;
&lt;p&gt;Lets add a few GUI components. &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Navigate to &lt;code&gt;BlurOffline/python/tools/General_Use_Tools/_Examples/SampleTool/ui&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Double-click on `sampletooldialog.ui'&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This should open the Qt Designer with your UI file. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note: If you're not using the standard blur installed version of designer, you can register your version to the IDE by setting the &lt;code&gt;BDEV_QT_DESIGNER' value in&lt;/code&gt;PYTHON_PATH/lib/site-packages/blurdev/resource/settings.ini' to the path of your Designer.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Otherwise, you can drag &amp;amp; drop the file from the IDE Editor into an open instance of the Designer. &lt;/p&gt;
&lt;p&gt;We aren't going to go into Qt Designer tutorials - there are plenty of those online. &lt;/p&gt;
&lt;p&gt;Instead, I'll just say add 3 components: add a tree named "uiBrowserTREE", a button called "uiLoadBTN", and a button called "uiSaveBTN". &lt;/p&gt;
&lt;p&gt;It doesn't matter how its layed out for the sake of this tutorial, as long as the components are created and named properly. &lt;/p&gt;
&lt;p&gt;Save the UI, and rerun the code. You'll now see your tool with your components - without having to change any code! &lt;/p&gt;
&lt;h3 id="running-through-treegrunt"&gt;Running through Treegrunt&lt;/h3&gt;
&lt;p&gt;So now that you have your tool - you'll want to be able to register it to treegrunt. &lt;/p&gt;
&lt;p&gt;If you run Treegrunt, you'll notice that your Tool doesn't popup. Whenever you modify the tools structure (add a tool, move a tool, rename a tool) you'll actually have to rebuild your XML index file. &lt;/p&gt;
&lt;p&gt;Right-click on the Window and choose &lt;code&gt;Environments &amp;gt;&amp;gt; Rebuild Index&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now you'll find &lt;code&gt;General_Use_Tools &amp;gt;&amp;gt; Examples &amp;gt;&amp;gt; SampleTool&lt;/code&gt; and you can double-click on it to run it. &lt;/p&gt;
&lt;p&gt;Thats all you have to do to register the tool to the system, the wizard took care of the rest. &lt;/p&gt;&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Anonymous</dc:creator><pubDate>Sat, 08 Feb 2014 00:16:57 -0000</pubDate><guid>https://sourceforge.net16bf33ffc1801736d755868252224463a2c65dbf</guid></item></channel></rss>