I’ve built a dockable pane, I’ve read lots of forum posts such as these:
I am still learning here, so please be gentle.
I want to return the doc (which loads after the pane), for things like ‘doc.GetWarnings()’
I see doc can be called in a number of ways, revit.doc, doc = HOST_APP.doc etc. I am clearly missing something, because I get 'nonType object has no attrribute ‘GetWarnings’ when I click my button.
Any assistance appreciated!
import System
import os.path as op
from pyrevit import HOST_APP, framework, coreutils, PyRevitException
from pyrevit import revit, DB, UI
from pyrevit import forms, script
from pyrevit.framework import wpf, ObservableCollection
from pyrevit import routes
import sys
import time
import os.path as op
class _WPFPanelProvider(UI.IDockablePaneProvider):
def __init__(self, panel_type, default_visible=True):
self._panel_type = panel_type
self._default_visible = default_visible
self.panel = self._panel_type()
def SetupDockablePane(self, data):
data.FrameworkElement = self.panel
data.VisibleByDefault = self._default_visible
def register_dockable_panel(panel_type, default_visible=True):
if not issubclass(panel_type, forms.WPFPanel):
raise PyRevitException(
"Dockable pane must be a subclass of forms.WPFPanel"
)
panel_uuid = coreutils.Guid.Parse(panel_type.panel_id)
dockable_panel_id = UI.DockablePaneId(panel_uuid)
panel_provider = _WPFPanelProvider(panel_type, default_visible)
HOST_APP.uiapp.RegisterDockablePane(
dockable_panel_id,
panel_type.panel_title,
panel_provider
)
return panel_provider.panel
class DockableExample(forms.WPFPanel):
panel_title = "OBE Info Pane"
panel_id = "1458b7cb-4dbe-4a8e-bad3-837e14b0a1ca"
panel_source = "Z:\\Library\\BIM\\01 Revit\\05 Toolbar\\OBTool\\Oberlanders.extension\\OBE.tab\\Audit.Panel\\AuditStack.Stack\\Dockable.pushbutton\\dockable.xaml"
def __init__(self):
wpf.LoadComponent(self, self.panel_source)
self.thread_id = framework.get_current_thread_id()
self.selected_lb.Text = ""
def button_click(self, sender, args):
try:
from obe import model_audit_doc #if we call at the start there is no doc?
doc = revit.doc
wrn = doc.GetWarnings() #test call fails
data_string = "test"
self.selected_lb.Text = data_string
except Exception as e:
print e.message
registered_panel = register_dockable_panel(DockableExample)
I experimented a bit on my side.
This is definitely not a topic I fully grasp.
I started from the sample in the dev extension of pyRevit
The key seems to be to handle what is related to the Document in the EventHandler definition
I used the ViewActivated one, getting its arguments ‘args’ you can grab the Document and build from there.
python code in my 'startup.py' script
import System
import os.path as op
from pyrevit import HOST_APP, framework, coreutils, PyRevitException
from pyrevit import revit, DB, UI
from pyrevit import forms, script
from pyrevit.framework import wpf, ObservableCollection
sample_panel_id = "1458b7cb-4dbe-4a8e-bad3-837e14b0a1ca"
warnings_list = []
class _WPFPanelProvider(UI.IDockablePaneProvider):
def __init__(self, panel_type, default_visible=True):
self._panel_type = panel_type
self._default_visible = default_visible
self.panel = self._panel_type()
def SetupDockablePane(self, data):
data.FrameworkElement = self.panel
data.VisibleByDefault = self._default_visible
def register_dockable_panel(panel_type, default_visible=True):
if not issubclass(panel_type, forms.WPFPanel):
raise PyRevitException(
"Dockable pane must be a subclass of forms.WPFPanel"
)
panel_uuid = coreutils.Guid.Parse(panel_type.panel_id)
dockable_panel_id = UI.DockablePaneId(panel_uuid)
panel_provider = _WPFPanelProvider(panel_type, default_visible)
HOST_APP.uiapp.RegisterDockablePane(
dockable_panel_id,
panel_type.panel_title,
panel_provider
)
return panel_provider.panel
class DockableExample(forms.WPFPanel):
panel_source = op.join(op.dirname(__file__), "DockablePaneSample.xaml")
panel_title = "Dockable Pane Sample"
panel_id = sample_panel_id
def __init__(self):
wpf.LoadComponent(self, self.panel_source)
self.thread_id = framework.get_current_thread_id()
self.warnings_lb.ItemsSource = []
def update_list(self):
try:
template_list = [forms.TemplateListItem(w) for w in warnings_list]
self.warnings_lb.ItemsSource = ObservableCollection[forms.TemplateListItem](template_list)
except Exception as e:
print e.message
registered_panel = register_dockable_panel(DockableExample)
def viewactivated_eventhandler(sender, args):
try: dockable_pane = UI.DockablePane(UI.DockablePaneId(System.Guid(sample_panel_id)))
except: return
global warnings_list
if HOST_APP.uidoc and dockable_pane.IsShown():
try:
warns = args.Document.GetWarnings()
warns = [i.GetDescriptionText() for i in warns]
print warns
# you could print here to check if it's working
if warns:
warnings_list = warns
registered_panel.update_list()
except Exception as e:
print e.message
HOST_APP.uiapp.ViewActivated += \
framework.EventHandler[UI.Events.ViewActivatedEventArgs](viewactivated_eventhandler)