Using QT Designer to create TableView to Postgres Database - sql

I'm creating a plugin in Quantum GIS that is using Postgres as the back end and QT Designer to make the GUI. I'm using psycopg2 to run scripts in the database and even fetch results of queries to set the values of labels in the GUI. This stuff is working fine for me.
What I would like to do now after some queries are run by clicking a 'calculate' button is for the resulting table to be shown in the plugin as a TableView. I know there widget exists expressly for the purpose of viewing tables but I can't quite figure out how to go about it. I'm not sure if I should be using psycopg2 or PySide, since most examples I have seen online use the latter.
I am wondering if someone can tell me which between psycopg2 and PySide should be used to create the TableView. Second, I am wondering what the 'signal' should be to the TableView widget to display the results of a query in Postgres. Lastly, is anyone can offer some instruction as to how to set up the code it would be hugely appreciated!
Cheers,
Roman
I've gone ahead and tried following the PyQt documentation, but as it's provided in C++ and I'm only a beginner programmer using Python I'm not sure if I've caught all the necessary amendments to the code syntax. Anyways, this is what I have so far:
db = QSqlDatabase.addDatabase("database")
db.setHostName("localhost")
db.setUserName("postgres")
db.setPassword("password")
#Not sure what to do to set the connection. The C++ documentation says to put "bool ok = db.open();"
model = QSqlQueryModel()
model.setQuery("SELECT name, density, deveff FROM public." +str(filename)+ "_rezoning ORDER BY gid;")
model.setHeaderData(0, Qt.Horizontal, "Name")
model.setHeaderData(1, Qt.Horizontal, "Density")
model.setHeaderData(2, Qt.Horizontal, "DevEff")
view = QTableView()
view.setModel(model)
view.show()
What happens when I click the button in my GUI to run the calculations, a small blank QGIS window briefly flashes and goes away. At least I'm not getting an error, but it's obviously not complete. I assume part of the issue is the connection to the database that is missing and that I do not know how to set. The other issue is that I would like this to show in the tableView widget in the GUI, but I'm not sure how to specify this...
Any further tips? I really appreciate it.
Roman

If you're planning to use Qt widgets and models, PySide (PyQt, or plain Qt/C++) is the way to go.
With bare psycopg2 you'll have a lot more work to do, and you'll need to implement your own model in order to leverage Qt's model/view classes. This is simply not the Qt way of doing things. PySide (and PyQt) has it own means to connect to a supported database, there's no need for pure Python database adapters like psycopg2. It uses the underlying libqt4-sql library (C++) and the installed plugins (QPSQL, QMYSQL, QSQLITE, etc).
Essentially you need to:
Connect to a database.
Instantiate a model (QSqlQueryModel, QSqlTableModel or a custom QAbstractTableModel derived class)
Attach that model to a view (ie. QTableView).
Take a look at the PySide QtSql Documentation and the PyQt documentation to get an idea. They're mostly compatible/interchangeable, but at a glance I see that the PyQt documentation looks more complete.
EDIT (after your edit):
A Qt GUI application requires an event loop to run, and that's provided by a QApplication instance. Before going any further with the specifics of your app, take the time to understand a few basic concepts first. Here's a nice Getting Started with PyQt Guide.

Related

Get the results of an (existing) code inspection

I am new to writing intellij plugins, so I apologize in advance if my question might be a bit unclear.
I know that (live) code inspections are achieved via Annotators or LocalInspectionTools. I also know there is an API to write a custom Annotator or Inspection tool and I have seen several examples.
What I do not know (my question): is there a manager/helper/"global inspector" that can provide me with the results of an existing code annotator/inspection process (done by the IDE's plugins or by some 3rd party plugin)?
For instance: I do not want to write a custom Lint annotator/inspection plugin for WebStorm. One can configure JSLint/JSHint inside WebStorm settings. The results of the live inspection can be seen over the current file/current open editor.
I would like to get the results of this live inspection, that occurs in the current open editor (inside my own custom code). For this I am interested in the API to get this annotator/inspector and/or the results it provides.
(I apologize for maybe using annotator and inspection terms in a confusing manner)
If there is another question (which I could not find) that duplicates what I have asked above, please re-direct me.
Thank you in advance!
Andrei.
Unfortunately regular annotating process for the linters is asynchronous so you cannot get the annotation results directly (by calling 'Manager' method).
You can create instances of JSLintInspection, JSHintInspection, etc. and call #createVisitor().visit(File) method but the operation is very slow and you must call it outside of AWT thread.
Also you can try to run the method com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerEx#processHighlights but as I mentioned above the annotation results for linters can be not available (or outdated)

Labview diagram creation API

I need to drive a testbench with labview.
The test scenarios are written in a languages that can be automaticaly translated into labview diagrams.
Is this an API that allow to create "labview diagrams" from another software ? or with labview itself ?
I agree that LabVIEW scripting is one approach, but let me throw out another option.
If you are planning to do a one time migration from your test code to LabVIEW than scripting is great, but if you plan to regularly update your test code (because it's easier to use the "test" language than LabVIEW) than it could become quite painful to constantly perform the migration every time your test code has changed.
I've had great success with simply putting my state machine inside of a for loop and then reading in "commands" from a text file that was generated using my "test" language (see pic).
For example, to do an IV sweep my text file might say something like:
SourceV, 5
ReadI
Wait, 1
SourceV, 6
ReadI
This image is greatly simplified - I'm not using a state machine and I don't show how to use "parameters," but I can provide a more comprehensive example if needed. Again, I've had great success doing this with around 30 "commands" controlling multiple instruments and then I generated the text input using VBA or Python.
It's called LabVIEW scripting. You will need to enable an option in the VI Server page in the options dialog to see the relevant features.
A few things to note:
Scripting isn't complicated, but you do need to be aware of how LV code is built.
While scripting is public, it was initially created as an internal tool. There are still corners of it which are incomplete.
Scripting code can be tedious. If you can get away with it, try creating templates of code.
NI has something called CodeGen, which I believe are a series of functions which make some scripting easier, although I never really looked into it.

passing options to a matplotlib backend in a clean way

For my personal use, several times I have modified the matplotlib gtk backend (also the tk and wx) , replacing the window with a notebook. This is because I use too many plots at the same time.
This time around I feel I can take the challenge to do a pull-request for my changes. But I want to do it as clean as possible. That is where I need advice (clean is the key).
I would like to place my class TabbedFigureManagerGTK3 inside
backend_gtk3.py
The problem is that using
matplotlib.use('gtk3cairo')
or
matplotlib.use('gtk3agg')
Directs the specified backend (gtk3cairo or gtk3agg) to use backend_gtk3.FigureManagerGTK3
I do not want to replicate backend_gtk3agg.py and backend_gtk3cairo.py just to change the call to backend_gtk3.FigureManagerGTK3
I would like to implement a solution that allows the user to pass an option to the backend, and from there it choses the traditional FigureManagerGTK3 or my TabbedFigureManagerGTK3
I am looking for a recomendation on how to do it that has more chances to be accepted upstream (after pull-request and the whole shebang).
Do I modify matplotlib.use to add something like **kwargs?
Do I just recreate the whole backend_gtk3agg.py and backend_gtk3cairo.py (subclassing of course)
Do I forget about trying to get this accepted and do it breaking the Coding guide
Thanks
Federico
This does sound like a nifty feature.
I would do it by modifying the existing manager and following how the PySide vs PyQt issue is handled (by using a secondary rcParams which controls which one the backend imports). In your case, I would add backend.gtk3.tabbed, or something similarly named, which controls how the manager behaves.
Write your modifications so that changes as little of the existing api as possible (breaking backwards compatibility is a no-go) and make it so a user that doesn't explicitly enable your changes won't even know they are there.
Also email the dev list, they are all pretty friendly. Or just open a PR, that is the most effective way to get feed back.

Using JFace ProjectionViewer in Standalone App

I've been trying to use the JFace ProjectionViewer to implement folding in a standalone Java app. I got the idea from this article:
http://www.eclipse.org/articles/Article-Folding-in-Eclipse-Text-Editors/folding.html
However the source code provided with the article is for an Eclipse plug-in, not for a standalone.
The particular problem I'm having is that I can't get the VerticalRuler to respond and cause folding/unfolding.
Since I get the expected results, i.e. line numbers in the ruler, when I change from using a VerticalRuler to a LineNumberRuler while leaving everything else the same, I think my problem is specific to the implementation of the relationship among the ProjectionViewer, the VerticalRuler, and the Annotations.
My exact question is whether anyone has gotten this to work in a stand-alone code and, if so, how?

Is it possible to access custom properties from QT Designer after converting to python?

I am new to PyQt and Qt Designer and I'm trying to create an easy method for relating qWidgets with the tables and columns in an SQLite database. My idea was to tag each qWidget in designer with two custom properties, one with the table name and one with the column name. Later, I would use the info provided by designer to build my own class which creates a relationship between the qwidets and SQLite database.
Adding the custom properties in Designer seems to work fine however, the code for these custom properties do not get generated when converting the xml of designer into python (using UIC). Has anyone done this successfully? Perhaps there is a better way to do this?
Thanks,
Eric
If you added a property in Designer called "myproperty", fetch it with...
mywidget.property("myproperty")
This works fine in pyqt 4.8.3, perhaps it did not work in previous versions.
Check out this article Eric. Particularly look at the section titled "Producing a Plugin." River Bank Computing has another great PyQt reference.
EDIT:
I've been doing some more reading and I can't find a way to have this done automatically for you. If you are ok with with adding dynamic properties at run-time instead of design time you could accomplish the same end result. Here is an explanation of the setProperty() method in QObject, from which QWidget inherits.
If that doesn't work for you then it seems you might be better off going with a less generic approach. Instead of using a generic QWidget, you might be able to use a custom class derived from QSqlTableModel to keep track of your connection info. Another way would be to just use a QTableView and do the queries yourself to populate the data. Here and here are articles on databases in Qt. You might some inspiration for a new design from one of them.
I have not had great luck with using the Designer tool -- usually I end up doing a few rough layout, using pyuic and then editing and adding other stuff by hand.
It sounds like you could easily accomplish your task by creating your own custom class that inherits from QWidget and has the additional properties that you described. With my experiences trying to use custom widgets in the designer, I think the 'easier' way is to just write the class yourself and then set the layout by hand.
I know this doesn't exactly answer your question, but maybe you will try some of my suggestions.