source: orange/Orange/OrangeWidgets/OWWidget.py @ 11746:a11c7c32494a

Revision 11746:a11c7c32494a, 13.0 KB checked in by Ales Erjavec <ales.erjavec@…>, 6 months ago (diff)

Make widgets non resizable (if requested) also on non windows platform.

Line 
1#
2# OWWidget.py
3# Orange Widget
4# A General Orange Widget, from which all the Orange Widgets are derived
5#
6
7from OWBaseWidget import *
8
9
10class OWWidget(OWBaseWidget):
11    def __init__(self, parent=None, signalManager=None, title="Orange Widget",
12                 wantGraph=False, wantStatusBar=False, savePosition=True,
13                 wantMainArea=1, noReport=False, showSaveGraph=1,
14                 resizingEnabled=1, wantStateInfoWidget=None,
15                 **args):
16        """
17        Initialization
18        Parameters:
19            title - The title of the\ widget, including a "&" (for shortcut in about box)
20            wantGraph - displays a save graph button or not
21        """
22
23        OWBaseWidget.__init__(self, parent, signalManager, title, savePosition=savePosition, resizingEnabled=resizingEnabled, **args)
24
25        self.setLayout(QVBoxLayout())
26        self.layout().setMargin(2)
27
28        if not resizingEnabled:
29            self.layout().setSizeConstraint(QLayout.SetFixedSize)
30            self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
31
32        self.topWidgetPart = OWGUI.widgetBox(self, orientation="horizontal", margin=0)
33        self.leftWidgetPart = OWGUI.widgetBox(self.topWidgetPart, orientation="vertical", margin=0)
34        if wantMainArea:
35            self.leftWidgetPart.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.MinimumExpanding))
36            self.leftWidgetPart.updateGeometry()
37            self.mainArea = OWGUI.widgetBox(self.topWidgetPart, orientation="vertical", sizePolicy=QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding), margin=0)
38            self.mainArea.layout().setMargin(4)
39            self.mainArea.updateGeometry()
40           
41        self.controlArea = OWGUI.widgetBox(self.leftWidgetPart, orientation="vertical", margin=4)# if wantMainArea else 1)
42
43        self.space = self.controlArea
44
45        self.buttonBackground = OWGUI.widgetBox(self.leftWidgetPart, orientation="horizontal", margin=4)# if wantMainArea else 1)
46        self.buttonBackground.hide()
47       
48        if wantGraph and showSaveGraph:
49            self.buttonBackground.show()
50            self.graphButton = OWGUI.button(self.buttonBackground, self, "&Save Graph")
51            self.graphButton.setAutoDefault(0)
52           
53        if wantStateInfoWidget is None:
54            wantStateInfoWidget = self._owShowStatus
55           
56        if wantStateInfoWidget:
57            # Widget for error, warnings, info.
58            self.widgetStateInfoBox = OWGUI.widgetBox(self.leftWidgetPart, "Widget state")
59            self.widgetStateInfo = OWGUI.widgetLabel(self.widgetStateInfoBox, "\n")
60            self.widgetStateInfo.setWordWrap(True)
61            self.widgetStateInfo.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
62            self.widgetStateInfo.setFixedHeight(self.widgetStateInfo.height())
63            self.widgetStateInfoBox.hide()
64                   
65            self.connect(self, SIGNAL("widgetStateChanged(QString, int, QString)"), self.updateWidgetStateInfo)
66       
67
68        self.__reportData = None
69        if not noReport and hasattr(self, "sendReport"):
70            self.buttonBackground.show()
71            self.reportButton = OWGUI.button(self.buttonBackground, self, "&Report", self.reportAndFinish, debuggingEnabled=0)
72            self.reportButton.setAutoDefault(0)
73
74        if wantStatusBar:
75            #self.widgetStatusArea = OWGUI.widgetBox(self, orientation = "horizontal", margin = 2)
76            self.widgetStatusArea = QFrame(self) 
77            self.statusBarIconArea = QFrame(self)
78            self.widgetStatusBar = QStatusBar(self) 
79           
80            self.layout().addWidget(self.widgetStatusArea)
81           
82            self.widgetStatusArea.setLayout(QHBoxLayout(self.widgetStatusArea))
83            self.widgetStatusArea.layout().addWidget(self.statusBarIconArea)
84            self.widgetStatusArea.layout().addWidget(self.widgetStatusBar)
85            self.widgetStatusArea.layout().setMargin(0)
86            self.widgetStatusArea.setFrameShape(QFrame.StyledPanel)
87                       
88            self.statusBarIconArea.setLayout(QHBoxLayout())
89            self.widgetStatusBar.setSizeGripEnabled(0) 
90            #self.statusBarIconArea.setFrameStyle (QFrame.Panel + QFrame.Sunken)
91            #self.widgetStatusBar.setFrameStyle (QFrame.Panel + QFrame.Sunken)
92            #self.widgetStatusBar.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred))
93            #self.widgetStatusBar.setSizePolicy(QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred))
94            #self.widgetStatusBar.updateGeometry()
95            #self.statusBarIconArea.setFixedSize(16*2,18)
96            self.statusBarIconArea.hide()
97           
98
99            # create pixmaps used in statusbar to show info, warning and error messages
100            #self._infoWidget, self._infoPixmap = self.createPixmapWidget(self.statusBarIconArea, os.path.join(self.widgetDir + "icons/triangle-blue.png"))
101            self._warningWidget = self.createPixmapWidget(self.statusBarIconArea, os.path.join(self.widgetDir + "icons/triangle-orange.png"))
102            self._errorWidget = self.createPixmapWidget(self.statusBarIconArea, os.path.join(self.widgetDir + "icons/triangle-red.png"))
103       
104       
105
106    # status bar handler functions
107    def createPixmapWidget(self, parent, iconName):
108        w = QLabel(parent)
109        parent.layout().addWidget(w)
110        w.setFixedSize(16, 16)
111        w.hide()
112        if os.path.exists(iconName):
113            w.setPixmap(QPixmap(iconName))
114        return w
115
116    def setState(self, stateType, id, text):
117        stateChanged = OWBaseWidget.setState(self, stateType, id, text)
118        if not stateChanged or not hasattr(self, "widgetStatusArea"):
119            return
120
121        iconsShown = 0
122        #for state, widget, icon, use in [("Info", self._infoWidget, self._owInfo), ("Warning", self._warningWidget, self._owWarning), ("Error", self._errorWidget, self._owError)]:
123        for state, widget, use in [("Warning", self._warningWidget, self._owWarning), ("Error", self._errorWidget, self._owError)]:
124            if not widget: continue
125            if use and self.widgetState[state] != {}:
126                widget.setToolTip("\n".join(self.widgetState[state].values()))
127                widget.show()
128                iconsShown = 1
129            else:
130                widget.setToolTip("")
131                widget.hide()
132
133        if iconsShown:
134            self.statusBarIconArea.show()
135        else:
136            self.statusBarIconArea.hide()
137
138        #if (stateType == "Info" and self._owInfo) or (stateType == "Warning" and self._owWarning) or (stateType == "Error" and self._owError):
139        if (stateType == "Warning" and self._owWarning) or (stateType == "Error" and self._owError):
140            if text:
141                self.setStatusBarText(stateType + ": " + text)
142            else:
143                self.setStatusBarText("")
144        self.updateStatusBarState()
145        #qApp.processEvents()
146       
147    def updateWidgetStateInfo(self, stateType, id, text):
148        html = self.widgetStateToHtml(self._owInfo, self._owWarning, self._owError)
149        if html:
150            self.widgetStateInfoBox.show()
151            self.widgetStateInfo.setText(html)
152            self.widgetStateInfo.setToolTip(html)
153        else:
154            if not self.widgetStateInfoBox.isVisible():
155                dHeight = - self.widgetStateInfoBox.height()
156            else:
157                dHeight = 0
158            self.widgetStateInfoBox.hide()
159            self.widgetStateInfo.setText("")
160            self.widgetStateInfo.setToolTip("")
161            width, height = self.width(), self.height() + dHeight
162            self.resize(width, height)
163#            QTimer.singleShot(1, lambda :self.resize(width, height))
164
165    def updateStatusBarState(self):
166        if not hasattr(self, "widgetStatusArea"):
167            return
168        if self._owShowStatus and (self.widgetState["Warning"] != {} or self.widgetState["Error"] != {}):
169            self.widgetStatusArea.show()
170        else:
171            self.widgetStatusArea.hide()
172
173    def setStatusBarText(self, text, timeout=5000):
174        if hasattr(self, "widgetStatusBar"):
175            self.widgetStatusBar.showMessage(" " + text, timeout)
176
177    def reportAndFinish(self):
178        self.sendReport()
179        self.finishReport()
180
181    def startReport(self, name=None):
182        if self.__reportData is not None:
183            print "Cannot open a new report when an old report is still active"
184            return False
185        self.reportName = name or self.windowTitle()
186        self.__reportData = ""
187        return True
188
189    def reportSection(self, title):
190        if self.__reportData is None:
191            self.startReport()
192        self.__reportData += "\n\n<h2>%s</h2>\n\n" % title
193
194    def reportSubsection(self, title):
195        if self.__reportData is None:
196            self.startReport()
197        self.__reportData += "\n\n  <h3>%s</h3>\n\n" % title
198
199    def reportList(self, items):
200        if self.__reportData is None:
201            self.startReport()
202        self.startReportList()
203        for item in items:
204            self.addToReportList(item)
205        self.finishReportList()
206
207    def getUniqueFileName(self, patt):
208        return OWReport.get_instance().getUniqueFileName(patt)
209
210    def getUniqueImageName(self, nm="img", ext=".png"):
211        return OWReport.get_instance().getUniqueFileName(nm + "%06i" + ext)
212
213    def reportImage(self, filenameOrFunc, *args):
214        if self.__reportData is None:
215            self.startReport()
216
217        if type(filenameOrFunc) in [str, unicode]:
218            self.__reportData += '    <IMG src="%s"/>\n' % filenameOrFunc
219        else:
220            sfn, ffn = self.getUniqueImageName()
221            filenameOrFunc(ffn, *args)
222            self.reportImage(sfn)
223
224    svg_type = "image/svg+xml"
225    def reportObject(self, type, data, **attrs):
226        if self.__reportData is None:
227            self.startReport()
228        self.__reportData += '<object type="%s" data="%s" %s></object>' % (type, data, " ".join('%s="%s"' % attr for attr in attrs.items()))
229
230    def startReportList(self):
231        if self.__reportData is None:
232            self.startReport()
233        self.__reportData += "    <UL>\n"
234
235    def addToReportList(self, item):
236        self.__reportData += "      <LI>%s</LI>\n" % item
237
238    def finishReportList(self):
239        self.__reportData += "    </UL>\n"
240
241    def reportSettings(self, sectionName="", settingsList=None, closeList=True):
242        if sectionName:
243            self.reportSection(sectionName)
244        elif self.__reportData is None:
245            self.startReport()
246        self.__reportData += "    <ul>%s</ul>\n" % "".join("<b>%s: </b>%s<br/>" % item for item in settingsList if item) 
247
248    def reportRaw(self, text):
249        if self.__reportData is None:
250            self.startReport()
251        self.__reportData += text
252
253    def prepareDataReport(self, data, listAttributes=True, exampleCount=True):
254        if data:
255            res = []
256            if exampleCount:
257                res.append(("Examples", str(len(data))))
258            if listAttributes:
259                if data.domain.attributes:
260                    res.append(("Attributes", "%i %s" % ( 
261                                len(data.domain.attributes), 
262                                 "(%s%s)" % (", ".join(x.name for foo, x in zip(xrange(30), data.domain.attributes)), "..." if len(data.domain.attributes) > 30 else "")
263                              )))
264                else:
265                    res.append(("Attributes", "0"))
266                metas = data.domain.getmetas()
267                if metas:
268                  if len(metas) <= 100:
269                      res.append(("Meta attributes", "%i (%s)" % (len(metas), ", ".join(x.name for x in metas.values()))))
270                  else:
271                      res.append(("Meta attributes", str(len(metas))))
272                res.append(("Class", data.domain.classVar.name if data.domain.classVar else "<none>"))
273            return res
274           
275    def reportData(self, settings, sectionName="Data", ifNone="None", listAttributes = True, exampleCount=True):
276        haveSettings = False
277        try:
278            haveSettings = isinstance(settings, list) and len(settings[0])==2
279        except:
280            pass
281        if not haveSettings:
282            settings = self.prepareDataReport(settings, listAttributes, exampleCount)
283        if not self.__reportData:
284            self.startReport()
285        if sectionName is not None:
286            self.reportSection(sectionName)
287        if settings:
288            self.reportSettings("", settings)
289        elif ifNone is not None:
290            self.reportRaw(ifNone)
291
292    def finishReport(self):
293        if self.__reportData is not None:
294            report = OWReport.get_instance()
295#            report(self.reportName, self.__reportData or "",
296#                   self.widgetId, self.windowIcon())
297            report.appendReport(self.reportName, self.__reportData,
298                                sender=self)
299            self.__reportData = None
300
301import OWReport
302
303if __name__ == "__main__":
304    a = QApplication(sys.argv)
305    ow = OWWidget()
306    ow.show()
307    a.exec_()
Note: See TracBrowser for help on using the repository browser.