2

I'm developing a QGIS plugin to search class methods in the different classes of PyQGIS. I used three widgets: 2 objects of type QLineEdit (for classes and class methods) and one QTextBrowser (for results). The snipped code is below:

.
.
.
    def run(self):
        """Run method that performs all the real work"""

        text_search_class = self.dlg.lineEdit.text()
        text_search_line = self.dlg.lineEdit2.text()

        dict = {'QgsVectorLayer' : dir(QgsVectorLayer) 
                'QgsRasterLayer' : dir(QgsRasterLayer),
                'QLineEdit'      : dir(QLineEdit)}

        if ( text_search_class in dict.keys() ) == True:

            idx = dict.keys().index(text_search_class)

            elements = getPat2(text_search_line, dict.values()[idx])

            n = len(elements)
            message = str(n) + " elements of '" + text_search_line + "' in " + text_search_class + "\n\n" 

            for i in range(n - 1):
                message += elements[i] + ', '

            if n != 0:
                message += elements[n - 1]

            txtBox = self.dlg.textFeedback
            txtBox.setText(message)
        else:
            message = "The chosen class does not exist"
            txtBox = self.dlg.textFeedback
            txtBox.setText(message)

        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:
            # Do something useful here - delete the line containing pass and
            # substitute with your code.
            pass

My issue is that I had to use a dictionary to get the list of methods from dir(class) (in my code I only use QgsVectorLayer, QgsRasterLayer and QLineEdit; but they are more than 1200) because, for example, the true list is for dir(QgsVectorLayer); not for dir('QgsVectorLayer') when I don't use the dictionary. My question is how can I access to elements in dir(some_class) of PyQGIS without a dictionary.

The next pictures show the execution of the plugin.

Without any text to search:

enter image description here

Searching by pending, set y max, respectively, in QgsVectorLayer, QgsRasterLayer and QLineEdit:

enter image description here

2 Answers 2

2

This looks like an interesting plugin, and one I would have a lot of use for.

You can use the inspect module to peek inside objects without using dictionaries. Better still, you can peek at the code, comments, argument lists and so on. The latter would be useful for a plugin like this ;-)

Here's a quick example to get you started.. in this case, I'm opening a file in GDAL and inspecting the datasource object returned, and listing any methods I find.

from osgeo import ogr
from osgeo import osr
from osgeo import gdal
from gdalconst import GA_ReadOnly

ds = gdal.Open("/tmp/hmap.tif",GA_ReadOnly)

import inspect
object = ds
for item in inspect.getmembers(object):
    # returns tuple (name,object)
    if inspect.ismethod(item[1]):
        print item

and the end result...

('AddBand', <bound method Dataset.AddBand of <osgeo.gdal.Dataset; proxy of <Swig Object of type 'GDALDatasetShadow *' at 0xb15aea70> >>)
('BeginAsyncReader', <bound method Dataset.BeginAsyncReader of <osgeo.gdal.Dataset; proxy of <Swig Object of type 'GDALDatasetShadow *' at 0xb15aea70> >>)
('BuildOverviews', <bound method Dataset.BuildOverviews of <osgeo.gdal.Dataset; proxy of <Swig Object of type 'GDALDatasetShadow *' at 0xb15aea70> >>)
('CreateMaskBand', <bound method Dataset.CreateMaskBand of <osgeo.gdal.Dataset; proxy of <Swig Object of type 'GDALDatasetShadow *' at 0xb15aea70> >>)
('EndAsyncReader', <bound method Dataset.EndAsyncReader of <osgeo.gdal.Dataset; proxy of <Swig Object of type 'GDALDatasetShadow *' at 0xb15aea70> >>)
('FlushCache', <bound method Dataset.FlushCache of <osgeo.gdal.Dataset; proxy of <Swig Object of type 'GDALDatasetShadow *' at 0xb15aea70> >>)
('GetDescription', <bound method Dataset.GetDescription of <osgeo.gdal.Dataset; proxy of <Swig Object of type 'GDALDatasetShadow *' at 0xb15aea70> >>)
('GetDriver', <bound method Dataset.GetDriver of <osgeo.gdal.Dataset; proxy of <Swig Object of type 'GDALDatasetShadow *' at 0xb15aea70> >>)
... and lots more
2
0

The solution to this issue was here:

https://stackoverflow.com/questions/295058/convert-a-string-to-preexisting-variable-names/295113#295113

The keys words were in the title: "Convert a string to preexisting variable names".

My new code is now:

.
.
.
    def run(self):
        """Run method that performs all the real work"""

        text_search_class = self.dlg.lineEdit.text()
        text_search_line = self.dlg.lineEdit2.text()

        try:

            elements = getPat2(text_search_line, dir(globals()[text_search_class]))

            n = len(elements)

            message = str(n) + " elements of '" + text_search_line + "' in " + text_search_class + "\n\n" 

            for i in range(n - 1):
                message += elements[i] + ', '

            if n != 0:
                message += elements[n - 1]

            txtBox = self.dlg.textFeedback
            txtBox.setText(message)

        except KeyError:
            message = "The chosen class does not exist"
            txtBox = self.dlg.textFeedback
            txtBox.setText(message)

        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:
            # Do something useful here - delete the line containing pass and
            # substitute with your code.
            pass

The next pictures show the execution of the plugin with the new classes extracted with globals() (without a dictionary):

enter image description here

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.