Best Python code snippet using pyatom_python
dSlidePanelControl.py
Source:dSlidePanelControl.py
1# -*- coding: utf-8 -*-2import wx3import wx.lib.foldpanelbar as fpb4import dabo5from dabo.ui import makeDynamicProperty6if __name__ == "__main__":7 dabo.ui.loadUI("wx")8import dControlMixin as dcm9import dabo.dEvents as dEvents10import dabo.dColors as dColors11from dabo.dLocalize import _12class dSlidePanel(dcm.dControlMixin, fpb.FoldPanelItem):13 def __init__(self, parent, properties=None, attProperties=None, *args, **kwargs):14 self._baseClass = dSlidePanel15 preClass = fpb.FoldPanelItem16 self._widthAlreadySet = self._heightAlreadySet = True17 self._border = 518 # This needs to be set *after* the panel is added to its parent19 collapsed = self._extractKey(attProperties, "Collapsed", None)20 if collapsed is not None:21 collapsed = (collapsed == "True")22 else:23 collapsed = self._extractKey((kwargs, properties), "Collapsed", None)24 if collapsed is None:25 # They might have passed it as 'Expanded'26 collapsed = not self._extractKey((kwargs, properties), "Expanded", True)27 cbstyle = self._extractKey((kwargs, properties), "cbstyle", None)28 if cbstyle is None:29 kwargs["cbstyle"] = fpb.CaptionBarStyle()30 if isinstance(parent, fpb.FoldPanelBar):31 # Items have to be added to the internal panel instead32 self._cont = parent33 parent = parent._foldPanel34 else:35 # Must have been created from the parent control36 self._cont = parent.GetParent()37 self._captionForeColor = "black"38 self._barStyles = ("Borderless", "BorderOnly",39 "FilledBorder", "VerticalFill", "HorizontalFill")40 self._barStylesLow = ("borderless", "borderonly",41 "filledborder", "verticalfill", "horizontalfill")42 self._barStyleConstants = {"nostyle" : fpb.CAPTIONBAR_NOSTYLE,43 "verticalfill" : fpb.CAPTIONBAR_GRADIENT_V,44 "horizontalfill" : fpb.CAPTIONBAR_GRADIENT_H,45 "borderless" : fpb.CAPTIONBAR_SINGLE,46 "borderonly" : fpb.CAPTIONBAR_RECTANGLE,47 "filledborder" : fpb.CAPTIONBAR_FILLED_RECTANGLE}48 dcm.dControlMixin.__init__(self, preClass, parent, properties=properties,49 attProperties=attProperties, *args, **kwargs)50 self._cont.appendPanel(self)51 self._cont.RedisplayFoldPanelItems()52 if collapsed is not None:53 self.Collapsed = collapsed54 # Enable detection of clicks on the caption bar55 self._captionBar.Bind(wx.EVT_LEFT_UP, self.__onWxCaptionClick)56# print "CAP BAR BINDING"57 # Set up the sizer58 self._baseSizer = sz = dabo.ui.dSizer("v")59 self.SetSizer(sz, True)60 sz.appendSpacer(self.CaptionHeight)61 def GetBestSize(self):62 ret = super(dSlidePanel, self).GetBestSize()63 sibCount = len(self.GetParent().GetChildren())64 prnt = self.GetParent()65 if prnt:66 psz = prnt.GetSize()67 pWd, pHt = psz.GetWidth(), psz.GetHeight()68 capHt = self.CaptionHeight * (sibCount-1)69 if ret.GetWidth() > pWd:70 ret.SetWidth(pWd)71 if not self.IsExpanded():72 ret.SetHeight(self.CaptionHeight)73 else:74 if self.Parent.Singleton:75 ret.SetHeight(pHt - capHt)76 else:77 if ret.GetHeight() > pHt - capHt:78 ret.SetHeight(pHt - capHt)79 return ret80 def ResizePanel(self):81 """82 The native FoldPanelBar doesn't handle removing items form panels;83 this removes the item from the panel's internal item tracking.84 """85 for itm in self._items:86 if not itm._wnd:87 self._items.remove(itm)88 super(dSlidePanel, self).ResizePanel()89 def Destroy(self):90 self.Parent._panels.remove(self)91 self.Parent.raiseEvent(dEvents.SlidePanelChange)92 super(dSlidePanel, self).Destroy()93 def onChildBorn(self, evt):94 self._cont.lockDisplay()95 ch = evt.child96 self._cont.AddFoldPanelWindow(self, ch)97 self._cont.RefreshPanelsFrom(self)98 self._cont.unlockDisplay()99 dabo.ui.callAfterInterval(50, self._cont.sizePanelHeights)100 def appendSeparator(self, color=None):101 """This draws a separator line on the panel"""102 if color is None:103 color = "black"104 self.AddSeparator(self._getWxColour(color))105 def layout(self):106 """Wrap the wx version of the call, if possible."""107 self.Layout()108 try:109 # Call the Dabo version, if present110 self._baseSizer.layout()111 except AttributeError:112 pass113 if self.Application.Platform == "Win":114 self.refresh()115 def _clickedOnIcon(self, evt):116 cb = self._captionBar117 vertical = self.IsVertical()118 if cb._foldIcons:119 pt = evt.GetPosition()120 rect = cb.GetRect()121 drw = (rect.GetWidth() - cb._iconWidth - cb._rightIndent)122 if ((vertical and (pt.x > drw)) or123 (not vertical and (pt.y < (cb._iconHeight + cb._rightIndent)))):124 # They clicked the expand/collapse icon125 return True126 return False127 def __onWxCaptionClick(self, evt):128# print "WX CAP CLICK"129 if self._clickedOnIcon(evt):130 # Already handled131 return132 self.raiseEvent(dEvents.SlidePanelCaptionClick, evt)133 def _getBarColor1(self):134 try:135 ret = self._barColor1136 except AttributeError:137 ret = self._barColor1 = self._captionBar.GetCaptionStyle().GetFirstColour().Get()138 return ret139 def _setBarColor1(self, val):140 color = self._getWxColour(val)141 self._barColor1 = val142 style = self._captionBar.GetCaptionStyle()143 style.SetFirstColour(color)144 self._captionBar.SetCaptionStyle(style)145 def _getBarColor2(self):146 try:147 ret = self._barColor2148 except AttributeError:149 ret = self._barColor2 = self._captionBar.GetCaptionStyle().GetSecondColour().Get()150 return ret151 def _setBarColor2(self, val):152 color = self._getWxColour(val)153 self._barColor2 = val154 style = self._captionBar.GetCaptionStyle()155 style.SetSecondColour(color)156 self._captionBar.SetCaptionStyle(style)157 def _getBarStyle(self):158 wxbs = self._captionBar.GetCaptionStyle()._captionStyle159 lowerStyle = [k for k,v in self._barStyleConstants.items()160 if v == wxbs][0]161 return self._barStyles[list(self._barStylesLow).index(lowerStyle)]162 def _setBarStyle(self, val):163 if self._constructed():164 if val.lower().strip() not in self._barStylesLow:165 bs = ", ".join(self._barStyles)166 dabo.log.error(_("Unknown BarStyle passed: %(val)s. BarStyle must be one of: %(bs)s")167 % locals())168 else:169 self._barStyle = val170 # Apply it171 style = self._captionBar.GetCaptionStyle()172 style.SetCaptionStyle(self._barStyleConstants[val.lower().strip()])173 self._captionBar.SetCaptionStyle(style)174 else:175 self._properties["BarStyle"] = val176 def _getBorder(self):177 return self._border178 def _setBorder(self, val):179 if self._constructed():180 if val == self._border:181 return182 try:183 bs = self._baseSizer184 except AttributeError:185 # Passed in params; base sizer isn't yet present186 dabo.ui.callAfter(self._setBorder, val)187 return188 sz = self.Sizer189 self._border = val190 if sz is not None:191 sz.setItemProp(sz, "Border", val)192 self.layout()193 else:194 self._properties["Border"] = val195 def _getCaption(self):196 return self._captionBar._caption197 def _setCaption(self, val):198 if self._constructed():199 self._captionBar._caption = val200 self.refresh()201 else:202 self._properties["Caption"] = val203 def _getCaptionForeColor(self):204 return self._captionForeColor205 def _setCaptionForeColor(self, val):206 self._captionForeColor = val207 style = self._captionBar.GetCaptionStyle()208 style.SetCaptionColour(self._getWxColour(val))209 self._captionBar.SetCaptionStyle(style)210 def _getCaptionHeight(self):211 return self._captionBar.GetSize()[1]212 def _getCollapsed(self):213 return not self.IsExpanded()214 def _setCollapsed(self, val):215 if val:216 self._cont.collapse(self)217 else:218 self._cont.expand(self)219 def _getExpanded(self):220 return self.IsExpanded()221 def _setExpanded(self, val):222 if val:223 self._cont.expand(self)224 else:225 self._cont.collapse(self)226 def _getParent(self):227 return self._cont228 def _getPanelPosition(self):229 try:230 ret = self._cont.Children.index(self)231 except (ValueError, IndexError):232 ret = None233 return ret234 def _setPanelPosition(self, val):235 if self._constructed():236 if val == self.PanelPosition:237 return238 cnt = self._cont239 if self not in cnt._panels:240 # Not fully constructed yet241 return242 cnt._panels.remove(self)243 cnt._panels.insert(val, self)244 cnt.raiseEvent(dEvents.SlidePanelChange)245 else:246 self._properties["PanelPosition"] = val247 def _getSizer(self):248 sz = self._baseSizer249 try:250 ret = sz.Children[1].GetSizer()251 except (IndexError, AttributeError):252 ret = None253 return ret254 def _setSizer(self, val):255 if self._constructed():256 sz = self._baseSizer257 try:258 userSizer = sz.Children[1].GetSizer()259 except (IndexError, AttributeError):260 userSizer = None261 if userSizer:262 sz.remove(userSizer)263 if val is not None:264 sz.append1x(val, border=self.Border)265 try:266 val.Parent = self267 except AttributeError:268 pass269 else:270 self._properties["Sizer"] = val271 BarColor1 = property(_getBarColor1, _setBarColor1, None,272 _("Main color for the caption bar (dColor)"))273 BarColor2 = property(_getBarColor2, _setBarColor2, None,274 _("Secondary color for the caption bar. Only used in gradients (dColor)"))275 BarStyle = property(_getBarStyle, _setBarStyle, None,276 _(""""Determines how the bar containing the caption277 for this panel is drawn. (str)278 Can be one of the following:279 Borderless (no border, just a plain fill color; default)280 BorderOnly (simple border, no fill color)281 FilledBorder (combination of the two above)282 VerticalFill (vertical gradient fill, using the two caption colors)283 HorizontalFill (horizontal gradient fill, using the two caption colors)284 """))285 Border = property(_getBorder, _setBorder, None,286 _("Border between the contents and edges of the panel. Default=5 (int)"))287 Caption = property(_getCaption, _setCaption, None,288 _("Caption displayed on the panel bar (str)"))289 CaptionForeColor = property(_getCaptionForeColor, _setCaptionForeColor, None,290 _("Text color of the caption bar (str or tuple)"))291 CaptionHeight = property(_getCaptionHeight, None, None,292 _("Height of the caption bar. Read-only (int)"))293 Collapsed = property(_getCollapsed, _setCollapsed, None,294 _("Is the panel main area hidden? (bool)"))295 Expanded = property(_getExpanded, _setExpanded, None,296 _("Is the panel main area visible? (bool)"))297 Parent = property(_getParent, None, None,298 _("Reference to the containing dSlidePanelControl."))299 PanelPosition = property(_getPanelPosition, _setPanelPosition, None,300 _("Position of this panel within the parent container (int)"))301 Sizer = property(_getSizer, _setSizer, None,302 _("The sizer for the object.") )303 DynamicBarColor1 = makeDynamicProperty(BarColor1)304 DynamicBarColor2 = makeDynamicProperty(BarColor2)305 DynamicBarStyle = makeDynamicProperty(BarStyle)306 DynamicCaption = makeDynamicProperty(Caption)307 DynamicCaptionForeColor = makeDynamicProperty(CaptionForeColor)308 DynamicCollapsed = makeDynamicProperty(Collapsed)309 DynamicExpanded = makeDynamicProperty(Expanded)310class dSlidePanelControl(dcm.dControlMixin, wx.lib.foldpanelbar.FoldPanelBar):311 """312 Creates a control consisting of several panels that can be313 hidden or revealed by clicking on their 'caption bar'.314 This allows you to collapse each panel down to its caption bar,315 which either remains in place or drops to the bottom.316 """317 def __init__(self, parent, properties=None, attProperties=None, *args, **kwargs):318 self._baseClass = dSlidePanelControl319 preClass = fpb.FoldPanelBar320 self._singleClick = False321 self._collapseToBottom = False322 self._singleton = False323 self._expandContent = True324 self._styleAttributeVal = None325 # Flag to indicate whether panels are being expanded326 # or collapsed due to internal rules for Singleton format.327 self.__inSingletonProcess = False328 # Flag to track the currently expanded panel in Singleton format.329 self.__openPanel = None330 # Ensures that the control has a minimum size.331 self._minSizerWidth = self._minSizerHeight = 100332 dcm.dControlMixin.__init__(self, preClass, parent, properties=properties,333 attProperties=attProperties, *args, **kwargs)334 self._setInitialOpenPanel()335 self.bindEvent(dEvents.SlidePanelChange, self.__onSlidePanelChange)336 def append(self, pnl=None, **kwargs):337 if pnl is None:338 # Make sure that the Caption property has been passed339 if not "Caption" in kwargs:340 raise ValueError(_("You must specify a Caption when adding a panel"))341 pnl = dabo.ui.dSlidePanel(self, **kwargs)342 elif isinstance(pnl, basestring):343 # Just the caption; create the panel and use that344 pnl = dabo.ui.dSlidePanel(self, Caption=pnl, **kwargs)345 return pnl346 def appendPanel(self, pnl):347 # Panel is being instantiated and added as part of its __init__().348 pos = 0349 if len(self._panels) > 0:350 pos = self._panels[-1].GetItemPos() + self._panels[-1].GetPanelLength()351 pnl.Reposition(pos)352 self._panels.append(pnl)353 self.raiseEvent(dEvents.SlidePanelChange,354 self._createCapBarEvt(pnl))355 pnl.bindEvent(dEvents.SlidePanelCaptionClick,356 self.__onSlidePanelCaptionClick, pnl)357# print "PANEL CAP CLICK BOUND"358 return pnl359 def __onSlidePanelCaptionClick(self, evt):360# print "DABO CAPCLK", self.SingleClick361 if self.SingleClick:362 obj = evt.EventObject363 obj.Expanded = not obj.Expanded364 def _createCapBarEvt(self, pnl):365 evt = fpb.CaptionBarEvent(fpb.wxEVT_CAPTIONBAR)366 cap = pnl._captionBar367 evt.SetId(cap.GetId())368 evt.SetEventObject(cap)369 evt.SetBar(cap)370 return evt371 def Collapse(self, pnl):372 if pnl.Collapsed:373 # nothing to do here374 return375 super(dSlidePanelControl, self).Collapse(pnl)376 self.raiseEvent(dEvents.SlidePanelChange,377 self._createCapBarEvt(pnl))378 def Expand(self, pnl):379 if pnl.Expanded:380 # nothing to do here381 return382 super(dSlidePanelControl, self).Expand(pnl)383 self.raiseEvent(dEvents.SlidePanelChange,384 self._createCapBarEvt(pnl))385 # Throw in Dabo-style wrapper names386 expand = Expand387 collapse = Collapse388 def collapseAll(self):389 for pnl in self._panels:390 pnl.Collapsed = True391 def expandAll(self):392 for pnl in self._panels:393 pnl.Expanded = True394 def refresh(self):395 super(dSlidePanelControl, self).refresh()396 if self.CollapseToBottom:397 rect = self.RepositionCollapsedToBottom()398 vertical = self.IsVertical()399 if vertical and rect.GetHeight() > 0 or not vertical and rect.GetWidth() > 0:400 self.RefreshRect(rect)401 def layout(self):402 """Wrap the wx version of the call, if possible."""403 if not self:404 # The object may have already been released.405 return406 self.SetMinSize((self.MinSizerWidth, self.MinSizerHeight))407 for kid in self.Children:408 kid.SetMinSize((self.MinSizerWidth, self.MinSizerHeight))409 self.Layout()410 def onResize(self, evt):411 self.sizePanelHeights()412 @classmethod413 def getBasePanelClass(cls):414 return dSlidePanel415 def _setInitialOpenPanel(self):416 """417 When self.Singleton is true, ensures that one panel is418 open.419 """420 if not self.Singleton:421 return422 # Make sure that one panel is open. If not, open the first.423 # If there is more than one panel open, close all but the424 # first open panel.425 if len(self._panels) == 0:426 return427 self.__inSingletonProcess = True428 found = False429 for pnl in self._panels:430 if pnl.Expanded:431 if found:432 pnl.Expanded = False433 else:434 self.__openPanel = pnl435 found = True436 if not found:437 self._panels[0].Expanded = True438 self.__openPanel = self._panels[0]439 self.__inSingletonProcess = False440 def __onSlidePanelChange(self, evt):441 """442 This ensures that one and only one panel remains expanded443 when the control is in Singleton mode.444 """445 if not self.Singleton:446 self.sizePanelHeights(force=True)447 return448 if self.__inSingletonProcess:449 # The panel is changing due to this method, so ignore450 # it to avoid infinite loops.451 return452 self.__inSingletonProcess = True453 # This is in response to an external request to a panel454 # being expanded or collapsed.455 curr = self.__openPanel456 try:457 evtPanel = evt.panel458 except AttributeError:459 # Not fully built yet; ignore460 return461 isOpening = evt.expanded462 changing = curr is not evtPanel463 if isOpening:464 if curr is not None:465 if curr is not evtPanel:466 # Close the current one467 dabo.ui.callAfter(self.collapse, curr)468 self.__openPanel = evtPanel469 else:470 # The panel is closing. If it was the current panel,471 # keep it open.472 if curr is None:473 # This is the first panel being added; keep it open474 self.expand(evtPanel)475 self.__openPanel = evtPanel476 elif curr is evtPanel:477 self.expand(curr)478 if changing:479 self.layout()480 dabo.ui.callAfter(self.sizePanelHeights)481 self.refresh()482 self.__inSingletonProcess = False483 def sizePanelHeights(self, force=False):484 """485 Control the heights of the panels. Originally I thought we only needed486 this when running in Singleton mode, but now it seems better to run this487 in all modes.488 """489# - if not self.Singleton and not force:490# - return491 # Size the open panel to fill the space492 top = 0493 pnlList = self._panels[:]494 if not pnlList:495 # Not constructed fully496 return497 if self.CollapseToBottom:498 # Sort so that the first panel is the expanded one.499 pnlList.sort(key=lambda x: x.Collapsed)500 fp = pnlList[0]501 fp.Reposition(0)502 self.RefreshPanelsFrom(fp)503 for pnl in pnlList:504 if not pnl.Expanded:505 pnl.Height = pnl.CaptionHeight506 elif self.ExpandContent:507 # Make the panel that big, minus the height of the captions508 capHt = pnl.CaptionHeight * (len(self._panels) -1)509 pnl.Height = self.Height - capHt510 pnl.Top = top511 pnl.layout()512 top += pnl.Height513 dabo.ui.callAfter(self.layout)514 def _setUnderlyingStyleAtt(self):515 try:516 # See if we use the original attribute name517 self._extraStyle518 self._styleAttributeVal = "_extraStyle"519 except AttributeError:520 # Newer versions use a different attribute name521 self._styleAttributeVal = "_agwStyle"522 def _getChildren(self):523 return self._panels524 def _getCollapseToBottom(self):525 return bool(self._StyleAttribute & fpb.FPB_COLLAPSE_TO_BOTTOM)526 def _setCollapseToBottom(self, val):527 self._collapseToBottom = val528 if val:529 newStyle = self._StyleAttribute | fpb.FPB_COLLAPSE_TO_BOTTOM530 else:531 newStyle = self._StyleAttribute & ~fpb.FPB_COLLAPSE_TO_BOTTOM532 self._StyleAttribute = newStyle533 if self._panels:534 fp = self._panels[0]535 fp.Reposition(0)536 self.RefreshPanelsFrom(fp)537 self.sizePanelHeights(force=True)538 self.layout()539 def _getExpandContent(self):540 return self._expandContent541 def _setExpandContent(self, val):542 if self._constructed():543 self._expandContent = val544 else:545 self._properties["ExpandContent"] = val546 def _getMinSizerHeight(self):547 return self._minSizerHeight548 def _setMinSizerHeight(self, val):549 if self._constructed():550 self._minSizerHeight = val551 else:552 self._properties["MinSizerHeight"] = val553 def _getMinSizerWidth(self):554 return self._minSizerWidth555 def _setMinSizerWidth(self, val):556 if self._constructed():557 self._minSizerWidth = val558 else:559 self._properties["MinSizerWidth"] = val560 def _getPanelClass(self):561 try:562 return self._panelClass563 except AttributeError:564 return dabo.ui.dSlidePanel565 def _setPanelClass(self, val):566 if self._constructed():567 self._panelClass = val568 else:569 self._properties["PanelClass"] = val570 def _getPanelCount(self):571 return len(self.Children)572 def _setPanelCount(self, val):573 if self._constructed():574 val = int(val)575 if val < 0:576 raise ValueError(_("Cannot set PanelCount to less than zero."))577 panelCount = len(self.Children)578 panelClass = self.PanelClass579 if val > panelCount:580 for i in range(panelCount, val):581 pnl = panelClass(self)582 if not pnl.Caption:583 pnl.Caption = _("Panel %s") % (i+1,)584 elif val < panelCount:585 for i in range(panelCount, val, -1):586 self.Panels[i-1].release()587 else:588 self._properties["PanelCount"] = val589 def _getSingleClick(self):590 return self._singleClick591 def _setSingleClick(self, val):592 self._singleClick = val593 def _getSingleton(self):594 return self._singleton595 def _setSingleton(self, val):596 self._singleton = val597 # Make sure that only one panel is open598 self._setInitialOpenPanel()599 def _getStyleAttribute(self):600 try:601 return getattr(self, self._styleAttributeVal)602 except TypeError:603 self._setUnderlyingStyleAtt()604 return getattr(self, self._styleAttributeVal)605 def _setStyleAttribute(self, val):606 if self._constructed():607 try:608 setattr(self, self._styleAttributeVal, val)609 except TypeError:610 self._setUnderlyingStyleAtt()611 setattr(self, self._styleAttributeVal, val)612 else:613 self._properties["StyleAttribute"] = val614 Children = property(_getChildren, None, None,615 _("List of all panels in the control (list))"))616 CollapseToBottom = property(_getCollapseToBottom, _setCollapseToBottom, None,617 _("When True, all collapsed panels are displayed at the bottom (bool)"))618 ExpandContent = property(_getExpandContent, _setExpandContent, None,619 _("""When True, the panels size themselves to the size of this object.620 Otherwise, panels only take up as much space as they need. (default=True) (bool)"""))621 MinSizerHeight = property(_getMinSizerHeight, _setMinSizerHeight, None,622 _("Minimum height for the control. Default=100px (int)"))623 MinSizerWidth = property(_getMinSizerWidth, _setMinSizerWidth, None,624 _("Minimum width for the control. Default=100px (int)"))625 PanelClass = property(_getPanelClass, _setPanelClass, None,626 _("""Specifies the class of control to use for panels by default. (dSlidePanel)627 This really only applies when using the PanelCount property to set the628 number of panels."""))629 PanelCount = property(_getPanelCount, _setPanelCount, None,630 _("Number of child panels. (read-only) (int)"))631 Panels = property(_getChildren, None, None,632 _("List of contained panels. Same as the 'Children' property. (read-only) (list)"))633 SingleClick = property(_getSingleClick, _setSingleClick, None,634 _("""When True, a single click on the caption bar toggles the635 expanded/collapsed state (bool)"""))636 Singleton = property(_getSingleton, _setSingleton, None,637 _("When True, one and only one panel at a time will be expanded (bool)"))638 _StyleAttribute = property(_getStyleAttribute, _setStyleAttribute, None,639 _("""FOR INTERNAL USE ONLY! Internally the code for foldpanelbar changed640 the name of a 'private' attribute that the Dabo wrapper needs to address.641 This property handles the interaction with that private attribute. (str)"""))642 DynamicCollapseToBottom = makeDynamicProperty(CollapseToBottom)643 DynamicSingleClick = makeDynamicProperty(SingleClick)644 DynamicSingleton = makeDynamicProperty(Singleton)645if __name__ == "__main__":646 from dabo.dApp import dApp647 class TestForm(dabo.ui.dForm):648 def afterInit(self):649 dSlidePanelControl(self, RegID="slideControl", ExpandContent=False,650 SingleClick=True)651 self.Sizer.append1x(self.slideControl)652 self.p1 = dabo.ui.dSlidePanel(self.slideControl, Caption="First",653 BackColor="orange")654 self.p2 = dabo.ui.dSlidePanel(self.slideControl, Caption="Second",655 BarStyle="HorizontalFill", BarColor1="lightgreen", BarColor2="ForestGreen",656 BackColor="wheat")657 self.p3 = dabo.ui.dSlidePanel(self.slideControl, Caption="Third",658 BarStyle="BorderOnly", BackColor="powderblue", Border=33)659 self.p1.Sizer = dabo.ui.dSizer("v")660 btn = dabo.ui.dButton(self.p1, Caption="Change Bar 1 Style")661 self.p1.Sizer.append(btn, border=25)662 btn.bindEvent(dEvents.Hit, self.onBtn)663 self.p2.Sizer = dabo.ui.dSizer("v")664 lbl = dabo.ui.dLabel(self.p2, Caption="Tea For Two", FontItalic=True,665 FontSize=24)666 self.p2.Sizer.append(lbl)667 def collapse3(evt):668 mc = self.slideControl669 if mc.Singleton:670 mc.expand(self.p2)671 else:672 mc.collapse(self.p3)673 self.p3.Sizer = dabo.ui.dGridSizer(HGap=5, VGap=2, MaxCols=2, DefaultBorder=3)674 lbl = dabo.ui.dLabel(self.p3, Caption="Three Strikes")675 btn = dabo.ui.dButton(self.p3, Caption="Collapse Me", OnHit=collapse3)676 self.p3.Sizer.appendItems((lbl, btn))677 # Demonstrate the grid678 self.p3.Sizer.append(dabo.ui.dLabel(self.p3, Caption="Just"))679 self.p3.Sizer.append(dabo.ui.dLabel(self.p3, Caption="taking"))680 self.p3.Sizer.append(dabo.ui.dLabel(self.p3, Caption="up"))681 self.p3.Sizer.append(dabo.ui.dLabel(self.p3, Caption="space"))682 self.p3.Sizer.append(dabo.ui.dLabel(self.p3, Caption="in"))683 self.p3.Sizer.append(dabo.ui.dLabel(self.p3, Caption="the"))684 self.p3.Sizer.append(dabo.ui.dLabel(self.p3, Caption="Grid"))685 self.p3.Sizer.append(dabo.ui.dLabel(self.p3, Caption="Sizer"))686 hsz = dabo.ui.dSizer("h")687 btnCollapse = dabo.ui.dButton(self, Caption="Collapse All")688 btnCollapse.bindEvent(dEvents.Hit, self.onCollapseAll)689 btnExpand = dabo.ui.dButton(self, Caption="Expand All")690 btnExpand.bindEvent(dEvents.Hit, self.onExpandAll)691 hsz.append(btnCollapse)692 hsz.appendSpacer(10)693 hsz.append(btnExpand)694 hsz.appendSpacer(10)695 chkSingleton = dabo.ui.dCheckBox(self, Caption="Singleton Style",696 DataSource="self.Form.slideControl", DataField="Singleton")697 chkSingle = dabo.ui.dCheckBox(self, Caption="Single Click to Toggle",698 DataSource="self.Form.slideControl", DataField="SingleClick")699 chkBottom = dabo.ui.dCheckBox(self, Caption="Collapsed Panels To Bottom",700 DataSource="self.Form.slideControl", DataField="CollapseToBottom")701 chkExpand = dabo.ui.dCheckBox(self, Caption="Expand Content to Full Size",702 DataSource="self.Form.slideControl", DataField="ExpandContent")703 self.Sizer.appendSpacer(10)704 vsz = dabo.ui.dSizer("v")705 vsz.append(chkSingleton)706 vsz.append(chkSingle)707 vsz.append(chkBottom)708 vsz.append(chkExpand)709 hsz.append(vsz)710 self.Sizer.append(hsz, 0, halign="center", border=10)711 self.layout()712 def onBtn(self, evt):713 import random714 p = self.p1715 style = random.choice(p._barStyles)716 p.BarStyle = style717 color1 = dColors.randomColorName()718 color2 = dColors.randomColorName()719 p.BarColor1 = color1720 p.BarColor2 = color2721 if style in ("VerticalFill", "HorizontalFill"):722 p.Caption = "Style: %s; Colors: %s, %s" % (style, color1, color2)723 elif style in ("BorderOnly", ):724 p.Caption = "Style: %s" % style725 else:726 p.Caption = "Style: %s; Color: %s" % (style, color1)727# lbl = dabo.ui.dLabel(p, Caption="Changed to %s" % p.BarStyle,728# FontItalic=True, FontSize=12)729# p.Sizer.append(lbl)730# p.layout()731 def onCollapseAll(self, evt):732 self.slideControl.collapseAll()733 def onExpandAll(self, evt):734 self.slideControl.expandAll()735 app = dApp()736 app.MainFormClass = TestForm...
mplwidget.py_bkup
Source:mplwidget.py_bkup
1#!/usr/bin/env python2import os3import tempfile4from PyQt4 import QtCore, QtGui5import matplotlib.cm6import matplotlib.colors7import icons_rc #@UnusedImport8#from .config import plotting9# set the default backend to be compatible with Qt in case someone uses pylab from IPython console10#def _set_default_rc():11 #matplotlib.rc('font', **plotting.font)12 #matplotlib.rc('savefig', **plotting.savefig)13#_set_default_rc()14cmap=matplotlib.colors.LinearSegmentedColormap.from_list('default',15 ['#0000ff', '#00ff00', '#ffff00', '#ff0000', '#bd7efc', '#000000'], N=256)16matplotlib.cm.register_cmap('default', cmap=cmap)17from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas18from matplotlib.backends.backend_qt4 import NavigationToolbar2QT19from matplotlib.cbook import Stack20from matplotlib.colors import LogNorm, Normalize21from matplotlib.figure import Figure22try:23 import matplotlib.backends.qt4_editor.figureoptions as figureoptions24except ImportError:25 figureoptions=None26class NavigationToolbar(NavigationToolbar2QT):27 '''28 A small change to the original navigation toolbar.29 '''30 _auto_toggle=False31 logtog = QtCore.pyqtSignal(str)32 homeClicked = QtCore.pyqtSignal()33 exportClicked = QtCore.pyqtSignal()34 35 isPanActivated = False36 isZoomActivated = False37 38 home_settings = None39 def __init__(self, canvas, parent, coordinates=False):40 NavigationToolbar2QT.__init__(self, canvas, parent, coordinates)41 self.setIconSize(QtCore.QSize(20, 20))42 def _init_toolbar(self):43 if not hasattr(self, '_actions'):44 self._actions={}45 self.basedir=os.path.join(matplotlib.rcParams[ 'datapath' ], 'images')46 icon=QtGui.QIcon()47 icon.addPixmap(QtGui.QPixmap(":/MPL Toolbar/go-home.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)48 a=self.addAction(icon, 'Home', self.home)49 a.setToolTip('Reset original view')50 icon=QtGui.QIcon()51 icon.addPixmap(QtGui.QPixmap(":/MPL Toolbar/zoom-previous.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)52 a=self.addAction(icon, 'Back', self.back)53 a.setToolTip('Back to previous view')54 icon=QtGui.QIcon()55 icon.addPixmap(QtGui.QPixmap(":/MPL Toolbar/zoom-next.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)56 a=self.addAction(icon, 'Forward', self.forward)57 a.setToolTip('Forward to next view')58 self.addSeparator()59 icon=QtGui.QIcon()60 icon.addPixmap(QtGui.QPixmap(":/MPL Toolbar/transform-move.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)61 a=self.addAction(icon, 'Pan', self.pan)62 a.setToolTip('Pan axes with left mouse, zoom with right')63 a.setCheckable(True)64 self._actions['pan']=a65 icon=QtGui.QIcon()66 icon.addPixmap(QtGui.QPixmap(":/MPL Toolbar/zoom-select.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)67 a=self.addAction(icon, 'Zoom', self.zoom)68 a.setToolTip('Zoom to rectangle')69 a.setCheckable(True)70 self._actions['zoom']=a71 self.addSeparator()72 icon=QtGui.QIcon()73 icon.addPixmap(QtGui.QPixmap(":/MPL Toolbar/edit-guides.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)74 a=self.addAction(icon, 'Subplots', self.configure_subplots)75 a.setToolTip('Configure plot boundaries')76 icon=QtGui.QIcon()77 icon.addPixmap(QtGui.QPixmap(":/MPL Toolbar/document-save.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)78 a=self.addAction(icon, 'Save', self.save_figure)79 a.setToolTip('Save the figure')80 icon=QtGui.QIcon()81 icon.addPixmap(QtGui.QPixmap(":/MPL Toolbar/document-print.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)82 a=self.addAction(icon, 'Print', self.print_figure)83 a.setToolTip('Print the figure with the default printer')84 icon=QtGui.QIcon()85 icon.addPixmap(QtGui.QPixmap(":/MPL Toolbar/export_ascii.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)86 a=self.addAction(icon, "Export", self.export_ascii)87 a.setToolTip('Export the plot into ASCII file')88 89 icon=QtGui.QIcon()90 icon.addPixmap(QtGui.QPixmap(":/MPL Toolbar/toggle-log.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)91 self.addSeparator()92 a=self.addAction(icon, 'Log', self.toggle_log)93 a.setToolTip('Toggle logarithmic scale')94 self.buttons={}95 # Add the x,y location widget at the right side of the toolbar96 # The stretch factor is 1 which means any resizing of the toolbar97 # will resize this label instead of the buttons.98 self.locLabel=QtGui.QLabel("", self)99 self.locLabel.setAlignment(100 QtCore.Qt.AlignRight|QtCore.Qt.AlignTop)101 self.locLabel.setSizePolicy(102 QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,103 QtGui.QSizePolicy.Ignored))104 self.labelAction=self.addWidget(self.locLabel)105 if self.coordinates:106 self.labelAction.setVisible(True)107 else:108 self.labelAction.setVisible(False)109 # reference holder for subplots_adjust window110 self.adj_window=None111 def activate_widget(self, widget_name, activateIt):112 113 if widget_name == 'pan':114 if activateIt:115 self.isPanActivated = True116 self.isZoomActivated = False117 else:118 self.isPanActivated = False119 elif widget_name == 'zoom':120 if activateIt:121 self.isZoomActivated = True122 self.isPanActivated = False123 else:124 self.isZoomActivated = False125 126 def home(self, *args):127 NavigationToolbar2QT.home(self,*args)128 self.homeClicked.emit()129 130 def pan(self, *args):131 NavigationToolbar2QT.pan(self, *args)132 self.activate_widget('pan', not self.isPanActivated)133 def zoom(self, *args):134 NavigationToolbar2QT.zoom(self, *args)135 self.activate_widget('zoom', not self.isZoomActivated)136 if matplotlib.__version__<'1.2':137 def pan(self, *args):138 'Activate the pan/zoom tool. pan with left button, zoom with right'139 # set the pointer icon and button press funcs to the140 # appropriate callbacks141 if self._auto_toggle:142 return143 if self._active=='ZOOM':144 self._auto_toggle=True145 self._actions['zoom'].setChecked(False)146 self._auto_toggle=False147 if self._active=='PAN':148 self._active=None149 else:150 self._active='PAN'151 if self._idPress is not None:152 self._idPress=self.canvas.mpl_disconnect(self._idPress)153 self.mode=''154 if self._idRelease is not None:155 self._idRelease=self.canvas.mpl_disconnect(self._idRelease)156 self.mode=''157 if self._active:158 self._idPress=self.canvas.mpl_connect(159 'button_press_event', self.press_pan)160 self._idRelease=self.canvas.mpl_connect(161 'button_release_event', self.release_pan)162 self.mode='pan/zoom'163 self.canvas.widgetlock(self)164 else:165 self.canvas.widgetlock.release(self)166 for a in self.canvas.figure.get_axes():167 a.set_navigate_mode(self._active)168 self.set_message(self.mode)169 def zoom(self, *args):170 'activate zoom to rect mode'171 if self._auto_toggle:172 return173 if self._active=='PAN':174 self._auto_toggle=True175 self._actions['pan'].setChecked(False)176 self._auto_toggle=False177 if self._active=='ZOOM':178 self._active=None179 else:180 self._active='ZOOM'181 if self._idPress is not None:182 self._idPress=self.canvas.mpl_disconnect(self._idPress)183 self.mode=''184 if self._idRelease is not None:185 self._idRelease=self.canvas.mpl_disconnect(self._idRelease)186 self.mode=''187 if self._active:188 self._idPress=self.canvas.mpl_connect('button_press_event', self.press_zoom)189 self._idRelease=self.canvas.mpl_connect('button_release_event', self.release_zoom)190 self.mode='zoom rect'191 self.canvas.widgetlock(self)192 else:193 self.canvas.widgetlock.release(self)194 for a in self.canvas.figure.get_axes():195 a.set_navigate_mode(self._active)196 self.set_message(self.mode)197 def export_ascii(self):198 self.exportClicked.emit()199 def print_figure(self):200 '''201 Save the plot to a temporary png file and show a preview dialog also used for printing.202 '''203 filetypes=self.canvas.get_supported_filetypes_grouped()204 sorted_filetypes=filetypes.items()205 sorted_filetypes.sort()206 filename=os.path.join(tempfile.gettempdir(), u"quicknxs_print.png")207 self.canvas.print_figure(filename, dpi=600)208 imgpix=QtGui.QPixmap(filename)209 os.remove(filename)210 imgobj=QtGui.QLabel()211 imgobj.setPixmap(imgpix)212 imgobj.setMask(imgpix.mask())213 imgobj.setGeometry(0, 0, imgpix.width(), imgpix.height())214 def getPrintData(printer):215 imgobj.render(printer)216 printer=QtGui.QPrinter()217 printer.setPrinterName('mrac4a_printer')218 printer.setPageSize(QtGui.QPrinter.Letter)219 printer.setResolution(600)220 printer.setOrientation(QtGui.QPrinter.Landscape)221 pd=QtGui.QPrintPreviewDialog(printer)222 pd.paintRequested.connect(getPrintData)223 pd.exec_()224 def save_figure(self, *args):225 filetypes=self.canvas.get_supported_filetypes_grouped()226 sorted_filetypes=filetypes.items()227 sorted_filetypes.sort()228 default_filetype=self.canvas.get_default_filetype()229 start="image."+default_filetype230 filters=[]231 for name, exts in sorted_filetypes:232 exts_list=" ".join(['*.%s'%ext for ext in exts])233 filter_='%s (%s)'%(name, exts_list)234 if default_filetype in exts:235 filters.insert(0, filter_)236 else:237 filters.append(filter_)238 filters=';;'.join(filters)239 fname=QtGui.QFileDialog.getSaveFileName(self, u"Choose a filename to save to", start, filters)240 if fname:241 try:242 self.canvas.print_figure(unicode(fname))243 except Exception, e:244 QtGui.QMessageBox.critical(245 self, "Error saving file", str(e),246 QtGui.QMessageBox.Ok, QtGui.QMessageBox.NoButton)247 def toggle_log(self, *args):248 ax=self.canvas.ax249 if len(ax.images)==0 and all([c.__class__.__name__!='QuadMesh' for c in ax.collections]):250 logstate=ax.get_yscale()251 if logstate=='linear':252 ax.set_yscale('log')253 else:254 ax.set_yscale('linear')255 self.canvas.draw()256 self.logtog.emit(ax.get_yscale())257 else:258 imgs=ax.images+[c for c in ax.collections if c.__class__.__name__=='QuadMesh']259 norm=imgs[0].norm260 if norm.__class__ is LogNorm:261 for img in imgs:262 img.set_norm(Normalize(norm.vmin, norm.vmax))263 else:264 for img in imgs:265 img.set_norm(LogNorm(norm.vmin, norm.vmax))266 self.canvas.draw()267class MplCanvas(FigureCanvas):268 269 trigger_click = QtCore.pyqtSignal()270 trigger_figure_left = QtCore.pyqtSignal()271 272 def __init__(self, parent=None, width=3, height=3, dpi=100, sharex=None, sharey=None, adjust={}):273 self.fig=Figure(figsize=(width, height), dpi=dpi, facecolor='#FFFFFF')274 self.ax=self.fig.add_subplot(111, sharex=sharex, sharey=sharey)275 self.fig.subplots_adjust(left=0.15, bottom=0.1, right=0.95, top=0.95)276 self.xtitle=""277 self.ytitle=""278 self.PlotTitle=""279 self.grid_status=True280 self.xaxis_style='linear'281 self.yaxis_style='linear'282 self.format_labels()283 self.ax.hold(True)284 FigureCanvas.__init__(self, self.fig)285 #self.fc = FigureCanvas(self.fig)286 FigureCanvas.setSizePolicy(self,287 QtGui.QSizePolicy.Expanding,288 QtGui.QSizePolicy.Expanding)289 FigureCanvas.updateGeometry(self)290 291 self.fig.canvas.mpl_connect('button_press_event', self.button_pressed)292 self.fig.canvas.mpl_connect('figure_leave_event', self.figure_leave)293 def button_pressed(self, event):294 self.trigger_click.emit()295 def figure_leave(self, event):296 self.trigger_figure_left.emit()297 298 def format_labels(self):299 self.ax.set_title(self.PlotTitle)300# self.ax.title.set_fontsize(10)301# self.ax.set_xlabel(self.xtitle, fontsize=9)302# self.ax.set_ylabel(self.ytitle, fontsize=9)303# labels_x=self.ax.get_xticklabels()304# labels_y=self.ax.get_yticklabels()305#306# for xlabel in labels_x:307# xlabel.set_fontsize(8)308# for ylabel in labels_y:309# ylabel.set_fontsize(8)310 def sizeHint(self):311 w, h=self.get_width_height()312 w=max(w, self.height())313 h=max(h, self.width())314 return QtCore.QSize(w, h)315 def minimumSizeHint(self):316 return QtCore.QSize(40, 40)317 def get_default_filetype(self):318 return 'png'319class MPLWidget(QtGui.QWidget):320 cplot=None321 cbar=None322 logtogy = QtCore.pyqtSignal(str)323 singleClick = QtCore.pyqtSignal(bool)324 leaveFigure = QtCore.pyqtSignal()325 def __init__(self, parent=None, with_toolbar=True, coordinates=False):326 QtGui.QWidget.__init__(self, parent)327 self.canvas=MplCanvas()328 self.canvas.ax2=None329 self.vbox=QtGui.QVBoxLayout()330 self.vbox.setMargin(1)331 self.vbox.addWidget(self.canvas)332 if with_toolbar:333 self.toolbar=NavigationToolbar(self.canvas, self)334 self.toolbar.coordinates=coordinates335 self.vbox.addWidget(self.toolbar)336 self.toolbar.logtog.connect(self.logtoggleylog)337 else:338 self.toolbar=None339 self.setLayout(self.vbox)340 self.canvas.trigger_click.connect(self._singleClick)341 self.canvas.trigger_figure_left.connect(self._leaveFigure)342 343 def _singleClick(self):344 status = self.toolbar.isPanActivated or self.toolbar.isZoomActivated345 self.singleClick.emit(status)346 347 def _leaveFigure(self):348 self.leaveFigure.emit()349 def logtoggleylog(self, status):350 self.logtogy.emit(status)351 def leaveEvent(self, event):352 '''353 Make sure the cursor is reset to it's default when leaving the widget.354 In some cases the zoom cursor does not reset when leaving the plot.355 '''356 if self.toolbar:357 QtGui.QApplication.restoreOverrideCursor()358 self.toolbar._lastCursor=None359 return QtGui.QWidget.leaveEvent(self, event)360 def set_config(self, config):361 self.canvas.fig.subplots_adjust(**config)362 def get_config(self):363 spp=self.canvas.fig.subplotpars364 config=dict(left=spp.left,365 right=spp.right,366 bottom=spp.bottom,367 top=spp.top)368 return config369 def draw(self):370 '''371 Convenience to redraw the graph.372 '''373 self.canvas.draw()374 def plot(self, *args, **opts):375 '''376 Convenience wrapper for self.canvas.ax.plot377 '''378 return self.canvas.ax.plot(*args, **opts)379 def semilogy(self, *args, **opts):380 '''381 Convenience wrapper for self.canvas.ax.semilogy382 '''383 return self.canvas.ax.semilogy(*args, **opts)384 def errorbar(self, *args, **opts):385 '''386 Convenience wrapper for self.canvas.ax.semilogy387 '''388 return self.canvas.ax.errorbar(*args, **opts)389 def pcolormesh(self, datax, datay, dataz, log=False, imin=None, imax=None, update=False, **opts):390 '''391 Convenience wrapper for self.canvas.ax.plot392 '''393 if self.cplot is None or not update:394 if log:395 self.cplot=self.canvas.ax.pcolormesh(datax, datay, dataz, norm=LogNorm(imin, imax), **opts)396 else:397 self.cplot=self.canvas.ax.pcolormesh(datax, datay, dataz, **opts)398 else:399 self.update(datax, datay, dataz)400 return self.cplot401 def imshow(self, data, log=False, imin=None, imax=None, update=True, **opts):402 '''403 Convenience wrapper for self.canvas.ax.plot404 '''405 if self.cplot is None or not update:406 if log:407 self.cplot=self.canvas.ax.imshow(data, norm=LogNorm(imin, imax), **opts)408 else:409 self.cplot=self.canvas.ax.imshow(data, **opts)410 else:411 self.update(data, **opts)412 return self.cplot413 def set_title(self, new_title):414 return self.canvas.ax.title.set_text(new_title)415 def set_xlabel(self, label):416 return self.canvas.ax.set_xlabel(label)417 def set_ylabel(self, label):418 return self.canvas.ax.set_ylabel(label)419 def set_xscale(self, scale):420 try:421 return self.canvas.ax.set_xscale(scale)422 except ValueError:423 pass424 def set_yscale(self, scale):425 try:426 return self.canvas.ax.set_yscale(scale)427 except ValueError:428 pass429 def clear_fig(self):430 self.cplot=None431 self.cbar=None432 self.canvas.fig.clear()433 self.canvas.ax=self.canvas.fig.add_subplot(111, sharex=None, sharey=None)434 def clear(self):435 self.cplot=None436 self.toolbar._views.clear()437 self.toolbar._positions.clear()438 self.canvas.ax.clear()439 if self.canvas.ax2 is not None:440 self.canvas.ax2.clear()441 def update(self, *data, **opts):442 self.cplot.set_data(*data)443 if 'extent' in opts:444 self.cplot.set_extent(opts['extent'])445 oldviews=self.toolbar._views446 if self.toolbar._views:447 # set the new extent as home for the new data448 newviews=Stack()449 newviews.push([tuple(opts['extent'])])450 for item in oldviews[1:]:451 newviews.push(item)452 self.toolbar._views=newviews453 if not oldviews or oldviews[oldviews._pos]==oldviews[0]:454 self.canvas.ax.set_xlim(opts['extent'][0], opts['extent'][1])455 self.canvas.ax.set_ylim(opts['extent'][2], opts['extent'][3])456 def legend(self, *args, **opts):457 return self.canvas.ax.legend(*args, **opts)458 def adjust(self, **adjustment):...
test_stitch_axis.py
Source:test_stitch_axis.py
1import pytest2import numpy as np3from qtpy import QtCore, QtWidgets4wait = 1005def test_stitch_plot(qtbot, main_gui, data_server):6 """Test the axis adjustment in stitching plot"""7 main_window = main_gui(8 configuration=data_server.path_to("REF_L_188299_to_188301.xml"),9 show=True,10 )11 # Run reduce12 main_window.run_reduction_button()13 qtbot.wait(wait)14 data_stitching_Tab = main_window.findChild(QtWidgets.QWidget, "data_stitching_Tab")15 qtbot.mouseClick(data_stitching_Tab, QtCore.Qt.LeftButton)16 qtbot.wait(wait)17 #18 stitch_plot = main_window.findChild(QtWidgets.QWidget, "data_stitching_plot")19 ax = stitch_plot.canvas.ax20 # mimic right click on the x-axis21 stitch_plot._singleClick(True, True, 0, 0)22 qtbot.wait(wait)23 popup = main_window.findChild(QtWidgets.QMainWindow, "ManualXAxisControl")24 # - adjust xmin25 xmin_line_edit = popup.findChild(QtWidgets.QLineEdit, "x_min_value")26 xmin_line_edit.setText("0.01")27 popup.x_min_event()28 qtbot.wait(wait)29 np.testing.assert_equal(0.01, ax.get_xlim()[0])30 # - adjust xmax31 xmax_line_edit = popup.findChild(QtWidgets.QLineEdit, "x_max_value")32 xmax_line_edit.setText("0.03")33 popup.x_max_event()34 qtbot.wait(wait)35 np.testing.assert_equal(0.03, ax.get_xlim()[1])36 # - toggle back to auto scale37 popup.x_auto_rescale_event()38 qtbot.wait(wait)39 popup.close()40 qtbot.wait(wait)41 # mimic right click on the y-axis42 stitch_plot._singleClick(True, False, 0, 0)43 qtbot.wait(wait)44 popup = main_window.findChild(QtWidgets.QMainWindow, "ManualYAxisControl")45 assert popup46 # - adjust ymin47 popup.ui.y_min_value.setText("0.3")48 popup.y_min_event()49 qtbot.wait(wait)50 np.testing.assert_equal(0.3, ax.get_ylim()[0])51 # - adjust ymax52 popup.ui.y_max_value.setText("14.0")53 popup.y_max_event()54 qtbot.wait(wait)55 np.testing.assert_equal(14.0, ax.get_ylim()[1])56 # - toggle back to auto scale57 popup.y_auto_rescale_event()58 qtbot.wait(wait)59 popup.close()60 qtbot.wait(wait)61if __name__ == '__main__':...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!