0

Best Practices: Extending RV with PyQt and/or PySide

This is something we (at Tweak) don't do much, but we know some of you out there are doing a lot of this, so this is just an open invitation to post what you've discovered in terms of best practices.

Our recommendations (we'll add to this as we learn - from you!) :

  • You can use QApplication::topLevelWidgets in your favorite Qt python bindings to identify the RV main window in memory, then add QDockWidgets, etc.



TopLevelQtWidgetPrintout-0.1.rvpkg

15 条评论

  • 0
    Avatar
    Chrystie, Adam

    This tip doesn't seem to work for me. I get an empty list as the return. I've tried a few ways. Anyone else had any luck getting the above tip to work?

    I'm using rv 3.12.17 and pyqt binding.

     

    Method 1:

    I have a shell which has rv running. in teh same shell i execute the above python code. The result is an empty list.

    Method 2

    I made an rv package and assigned the code to be executed when i pushed the z key. Again an empty list.

     

    Thanks for any input.

  • 0
    Avatar
    Jon Morley

    Hi Adski,

    I am not sure I fully understand Method 1 listed above, but I did have luck with Method 2, so I have included my package here. After you install this package when you launch RV from the shell you can press shift-x to see the list of top level widgets printed to the shell.

    This is what I see printed:

    [<PyQt4.QtGui.QDialog object at 0x110f95dd0>, <PyQt4.QtGui.QWidget object at 0x110f95e60>, <PyQt4.QtGui.QMenu object at 0x110f95ef0>, <PyQt4.QtGui.QMenu object at 0x110f95f80>, <PyQt4.QtGui.QMenu object at 0x1112f4050>, <PyQt4.QtGui.QMenu object at 0x1112f40e0>, <PyQt4.QtGui.QMenu object at 0x1112f4170>, <PyQt4.QtGui.QMenu object at 0x1112f4200>, <PyQt4.QtGui.QMenu object at 0x1112f4290>, <PyQt4.QtGui.QMenu object at 0x1112f4320>, <PyQt4.QtGui.QMenu object at 0x1112f43b0>, <PyQt4.QtGui.QMenu object at 0x1112f4440>, <PyQt4.QtGui.QMenu object at 0x1112f44d0>, <PyQt4.QtGui.QMenu object at 0x1112f4560>, <PyQt4.QtGui.QMenu object at 0x1112f45f0>, <PyQt4.QtGui.QMenu object at 0x1112f4680>, <PyQt4.QtGui.QMenu object at 0x1112f4710>, <PyQt4.QtGui.QMenu object at 0x1112f47a0>, <PyQt4.QtGui.QMenu object at 0x1112f4830>, <PyQt4.QtGui.QMainWindow object at 0x1112f48c0>, <PyQt4.QtGui.QMenu object at 0x1112f4950>, <PyQt4.QtGui.QMenu object at 0x1112f49e0>, <PyQt4.QtGui.QMenu object at 0x1112f4a70>, <PyQt4.QtGui.QMenu object at 0x1112f4b00>, <PyQt4.QtGui.QMenu object at 0x1112f4b90>, <PyQt4.QtGui.QMenu object at 0x1112f4c20>, <PyQt4.QtGui.QMenu object at 0x1112f4cb0>, <PyQt4.QtGui.QMenu object at 0x1112f4d40>, <PyQt4.QtGui.QMenu object at 0x1112f4dd0>, <PyQt4.QtGui.QMenu object at 0x1112f4e60>, <PyQt4.QtGui.QMenu object at 0x1112f4ef0>, <PyQt4.QtGui.QMenu object at 0x1112f4f80>, <PyQt4.QtGui.QMenu object at 0x115853050>, <PyQt4.QtGui.QMenu object at 0x1158530e0>, <PyQt4.QtGui.QMenu object at 0x115853170>, <PyQt4.QtGui.QMenu object at 0x115853200>, <PyQt4.QtGui.QMenu object at 0x115853290>, <PyQt4.QtGui.QMenuBar object at 0x115853320>, <PyQt4.QtGui.QMenu object at 0x1158533b0>, <PyQt4.QtGui.QMenu object at 0x115853440>, <PyQt4.QtGui.QMenu object at 0x1158534d0>, <PyQt4.QtGui.QMenu object at 0x115853560>, <PyQt4.QtGui.QMenu object at 0x1158535f0>, <PyQt4.QtGui.QMenu object at 0x115853680>, <PyQt4.QtGui.QMenu object at 0x115853710>, <PyQt4.QtGui.QMenu object at 0x1158537a0>, <PyQt4.QtGui.QMenu object at 0x115853830>, <PyQt4.QtGui.QMenu object at 0x1158538c0>, <PyQt4.QtGui.QMenu object at 0x115853950>, <PyQt4.QtGui.QMenu object at 0x1158539e0>, <PyQt4.QtGui.QMenu object at 0x115853a70>, <PyQt4.QtGui.QMenu object at 0x115853b00>, <PyQt4.QtGui.QMenu object at 0x115853b90>, <PyQt4.QtGui.QMenu object at 0x115853c20>, <PyQt4.QtGui.QFrame object at 0x115853cb0>, <PyQt4.QtGui.QMenu object at 0x115853d40>, <PyQt4.QtGui.QMenu object at 0x115853dd0>, <PyQt4.QtGui.QMenu object at 0x115853e60>, <PyQt4.QtGui.QMenu object at 0x115853ef0>, <PyQt4.QtGui.QMenu object at 0x115853f80>, <PyQt4.QtGui.QMenu object at 0x115854050>, <PyQt4.QtGui.QMenu object at 0x1158540e0>, <PyQt4.QtGui.QMenu object at 0x115854170>, <PyQt4.QtGui.QDialog object at 0x115854200>, <PyQt4.QtGui.QMenu object at 0x115854290>, <PyQt4.QtGui.QMenu object at 0x115854320>, <PyQt4.QtGui.QMenu object at 0x1158543b0>, <PyQt4.QtGui.QMenu object at 0x115854440>, <PyQt4.QtGui.QMenu object at 0x1158544d0>, <PyQt4.QtGui.QMenu object at 0x115854560>, <PyQt4.QtGui.QMenu object at 0x1158545f0>, <PyQt4.QtGui.QMenu object at 0x115854680>, <PyQt4.QtGui.QMenu object at 0x115854710>]

    If you are not familiar with installing packages please refer to the following documentation:

     9.2: Installation

    Package is now attached/linked at the top of the thread in the original post.

  • 0
    Avatar
    Chrystie, Adam

    Thanks Jon your example works. I'm trying to add QT widgets to the main RV Gui so i'll be examining these objects  to see if i can find a good place to add widgets in to.

  • 0
    Avatar
    Jon Morley

    Hi Adski,

    I am glad that worked for you. I think you will want to dock into the MainWindow. In my printout above it was listed as <PyQt4.QtGui.QMainWindow object at 0x1112f48c0>.  Just wanted to point that out.

    Thanks!

  • 0
    Avatar
    Chrystie, Adam

    Yup i saw the MainWindow object and I'm able to manipulate it in various ways. Thanks. Once I'm done I'll write up a tutorial on my WWW site assuming I get it all working.

  • 0
    Avatar
    Jon Morley

    Awesome!

  • 0
    Avatar
    Andry Jong

    Hi, I'm new to RV, and just found this article. So I tried out the TopLevelQtWidgetPrintout package. However, when I installed and reload RV, I got this error:

    <!--StartFragment-->Traceback (most recent call last):
    File "/usr/people/andryj/.rv/Python/TopLevelQtWidgetPrintout.py", line 3, in
    from PyQt4 import QtGui
    ImportError: No module named PyQt4
    ERROR: python module TopLevelQtWidgetPrintout could not be imported 

    Can anybody tell me what I'm doing wrong?

    I'm running RV 3.12.19, by the way. 
    Thanks!
     

  • 0
    Avatar
    Alan Trombla
    Hi Audry,
    From your other forum post it looks like you figured this out, please let us know if you still have questions.  For the record, RV does not (cannot) ship with PyQt, so to use that you need your own copy (ideally one matched with the current version of RV's Qt which as of this writing is 4.8.2).
    Cheers,
    Alan
  • 0
    Avatar
    Andry Jong

    Yes, I got it figured out!
    Thanks Alan!

  • 0
    Avatar
    nik yotis

    Jon as for your answer: "I am not sure I fully understand Method 1 listed above, but I did have luck with Method 2, so I have included my package here. After you install this package when you launch RV from the shell you can press shift-x to see the list of top level widgets printed to the shell."

    shift+x mirrors the frame on my 4.0.10 RV, how can i see the list of top level widgets? QMainWindow only also works

  • 0
    Avatar
    nik yotis

    shift+x actually does the 'Flop'

  • 0
    Avatar
    Jon Morley

    Hi Nik,

    It sounds like the package is not loading. Can you confirm both the "installed" and "Load" checkboxes are checked on the Packages tab of the preferences?

    Can you please paste any output you get when launch RV from the command line?

    Thanks,
    Jon

  • 0
    Avatar
    Mark Visser

    Hey Jon,

    Can you test your TopLevelQtWidgetPrintout package on RV 4.2.4? I've built PySide, and can create and display UI elements, but QtGui.QApplication.topLevelWidgets() doesn't appear to list a QMainWindow. Here's what I get (QMenu instances omitted for brevity):

    (the second string is w.metaObject().className(), and the third is w.objectName())

    INFO: <PySide.QtGui.QWidget object at 0x5136d40> QComboBoxPrivateContainer
    INFO: <PySide.QtGui.QWidget object at 0x513f128> Rv::RvDocument rv-session000
    INFO: <PySide.QtGui.QDialog object at 0x513fb48> QDialog RvNetworkConnect
    INFO: <PySide.QtGui.QWidget object at 0x5dcea70> Rv::RvConsoleWindow RvConsoleDialog
    INFO: <PySide.QtGui.QWidget object at 0x5dcf368> Rv::RvNetworkDialog RvNetworkDialog

    I'm thinking I either borked the PySide build somehow, or RV 4's main window is no longer derived from QMainWindow?

    cheers,

    -Mark

  • 1
    Avatar
    Jon Morley

    Hi Mark,

    I have not adapted the package yet, but we recently got this amazing code snipet from another user I think is worth sharing here:

    from PySide import QtCore, QtGui
    import shiboken
    top_window = None
    for w in QtGui.qApp.allWidgets():
        if w.inherits("QMainWindow"):
            ptr = shiboken.getCppPointer(w)
            top_window = shiboken.wrapInstance(long(ptr[0]), QtGui.QMainWindow)
    parent_widget = QtGui.QDockWidget('', top_window)
    top_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, parent_widget)

    I would give that shot and let us know if that helps you out.

    Thanks,
    Jon

  • 0
    Avatar
    Gaurav Jagnani

    To get the main window in PySide:


        import rv.qtutils as qtutils

       qtutils.sessionWindow()

     

    For pyqt you can get through topLevelWidgets()

     

    Thanks

     

请先登录再写评论。