def readSettings(self): self.imageFolder = os.path.normpath(str(self.settings.value("imageFolder").toString())) self.ui.actionIgnore_Transparent_Pixels.setChecked( self.settings.value("ignoreAlpha", True).toBool()) self.ui.actionCheck_for_update_at_start.setChecked( self.settings.value("checkupdate", True).toBool()) self.ui.tolerance_le.setText( self.settings.value("tolerance").toString()) self.settings.beginGroup("/geometry") p = QPoint() # position s = QSize() # size x = self.settings.value("X", -1).toInt()[0] y = self.settings.value("Y", -1).toInt()[0] # don't position outside current screen qRect = QtGui.QDesktopWidget.availableGeometry(app.desktop()) if x > qRect.right(): x = 10 if y > qRect.bottom(): y = 10 p.setX(x) p.setY(y) s.setWidth(self.settings.value("W", -1).toInt()[0]) s.setHeight(self.settings.value("H", -1).toInt()[0]) self.settings.endGroup() if p.x() > 0 and p.y() > 0 and s.width() > 0 and s.height() > 0: self.resize(s) # restore size self.move(p) # restore position
def capture(self, url, output_file, page_size=(1024, 720), img_size=None, post_load_delay=0): self.output_file = output_file self.img_size = img_size self.post_load_delay = post_load_delay if not img_size: img_size = page_size self.img_size = QSize() self.img_size.setWidth(img_size[0]) self.img_size.setHeight(img_size[1]) size = QSize() size.setWidth(page_size[0]) size.setHeight(page_size[1]) self.page().setViewportSize(size) self.load(QUrl(url)) while not self._loaded: self.app.processEvents() time.sleep(0) self._loaded = False
class Screenshot(QWebView): """ Class to grab a screenshot of a web page. Adapted from: http://webscraping.com/blog/Webpage-screenshots-with-webkit/ """ def __init__(self): self.app = QApplication([__file__]) super(Screenshot, self).__init__() self._loaded = False self.loadFinished.connect(self._load_finished) def __del__(self): self.app.exit() def capture(self, url, output_file, page_size=(1024, 720), img_size=None, post_load_delay=0): self.output_file = output_file self.img_size = img_size self.post_load_delay = post_load_delay if not img_size: img_size = page_size self.img_size = QSize() self.img_size.setWidth(img_size[0]) self.img_size.setHeight(img_size[1]) size = QSize() size.setWidth(page_size[0]) size.setHeight(page_size[1]) self.page().setViewportSize(size) self.load(QUrl(url)) while not self._loaded: self.app.processEvents() time.sleep(0) self._loaded = False def _load_finished(self, result): if self.post_load_delay > 0: logger.debug( "Waiting {} seconds for page to run after load".format( self.post_load_delay)) time.sleep(int(self.post_load_delay)) frame = self.page().mainFrame() image = QImage(self.img_size, QImage.Format_ARGB32) painter = QPainter(image) frame.render(painter) painter.end() image.save(self.output_file) self._loaded = True
def sizeHint(self): """ A virtual method implementation which returns the size hint for the layout. """ if self._cached_hint is None: size = QSize(0, 0) for item in self._items: size = size.expandedTo(item.sizeHint()) left, top, right, bottom = self.getContentsMargins() size.setWidth(size.width() + left + right) size.setHeight(size.height() + top + bottom) self._cached_hint = size return self._cached_hint
def sectionSizeFromContents(self, logicalIndex: int) -> QSize: if self._pd.headerModel: curLeafIndex = QModelIndex(self._pd.leafIndex(logicalIndex)) if curLeafIndex.isValid(): styleOption = QStyleOptionHeader( self.styleOptionForCell(logicalIndex)) s = QSize(self._pd.cellSize(curLeafIndex, self, styleOption)) curLeafIndex = curLeafIndex.parent() while curLeafIndex.isValid(): if self.orientation() == Qt.Horizontal: s.setHeight(s.height() + self._pd.cellSize( curLeafIndex, self, styleOption).height()) else: s.setWidth(s.width() + self._pd.cellSize( curLeafIndex, self, styleOption).width()) curLeafIndex = curLeafIndex.parent() return s return super().sectionSizeFromContents(logicalIndex)
def calculateSize(self, sizeType): totalSize = QSize() for wrapper in self.list: position = wrapper.position itemSize = QSize() if sizeType == self.MinimumSize: itemSize = wrapper.item.minimumSize() else: # sizeType == self.SizeHint itemSize = wrapper.item.sizeHint() if position in (self.North, self.South, self.Center): totalSize.setHeight(totalSize.height() + itemSize.height()) if position in (self.West, self.East, self.Center): totalSize.setWidth(totalSize.width() + itemSize.width()) return totalSize
def minimumSize(self): """ A reimplemented method which returns the minimum size hint of the layout item widget as the minimum size of the window. """ if self._cached_min is None: size = QSize(0, 0) for item in self._items: size = size.expandedTo(item.minimumSize()) left, top, right, bottom = self.getContentsMargins() size.setWidth(size.width() + left + right) size.setHeight(size.height() + top + bottom) self._cached_min = size # XXX hack! We really need hasWidthForHeight! This doesn't quite # work because a QScrollArea internally caches the min size. d = self._options.direction if d == self.TopToBottom or d == self.BottomToTop: m = QSize(self._cached_min) if m.width() < self._cached_wfh: m.setWidth(self._cached_wfh) return m return self._cached_min
def sizeHint(self): """ Get the size hint for the scroll area. This reimplemented method fixes a Qt bug where the size hint is not updated after the scroll widget is first shown. The bug is documented on the Qt bug tracker: https://bugreports.qt-project.org/browse/QTBUG-10545 """ # This code is ported directly from QScrollArea.cpp but instead # of caching the size hint of the scroll widget, it caches the # size hint for the entire scroll area, and invalidates it when # the widget is changed or it receives a LayoutRequest event. hint = self._size_hint if hint.isValid(): return QSize(hint) fw = 2 * self.frameWidth() hint = QSize(fw, fw) font_height = self.fontMetrics().height() widget = self.widget() if widget is not None: if self.widgetResizable(): hint += widget.sizeHint() else: hint += widget.size() else: hint += QSize(12 * font_height, 8 * font_height) if self.verticalScrollBarPolicy() == Qt.ScrollBarAlwaysOn: vbar = self.verticalScrollBar() hint.setWidth(hint.width() + vbar.sizeHint().width()) if self.horizontalScrollBarPolicy() == Qt.ScrollBarAlwaysOn: hbar = self.horizontalScrollBar() hint.setHeight(hint.height() + hbar.sizeHint().height()) hint = hint.boundedTo(QSize(36 * font_height, 24 * font_height)) self._size_hint = hint return QSize(hint)
def sizeHint(self): size = QSize() size.setWidth(self.width * self.fixed_font_width + 2) size.setHeight(self.height * self.fixed_font_height) return size
def sectionSizeFromContents(self, logicalIndex: int)->QSize: if self._pd.headerModel: curLeafIndex = QModelIndex(self._pd.leafIndex(logicalIndex)) if curLeafIndex.isValid(): styleOption = QStyleOptionHeader(self.styleOptionForCell(logicalIndex)) s = QSize(self._pd.cellSize(curLeafIndex, self, styleOption)) curLeafIndex=curLeafIndex.parent() while curLeafIndex.isValid(): if self.orientation() == Qt.Horizontal: s.setHeight(s.height()+self._pd.cellSize(curLeafIndex, self, styleOption).height()) else: s.setWidth(s.width()+self._pd.cellSize(curLeafIndex, self, styleOption).width()) curLeafIndex=curLeafIndex.parent() return s return super().sectionSizeFromContents(logicalIndex) def paintSection(self, painter: QPainter, rect: QRect, logicalIndex: int): if rect.isValid(): leafIndex = QModelIndex(self._pd.leafIndex(logicalIndex)) if leafIndex.isValid(): if self.orientation() == Qt.Horizontal: self._pd.paintHorizontalSection(painter, rect, logicalIndex, self, self.styleOptionForCell(logicalIndex), leafIndex) else: self._pd.paintVerticalSection(painter, rect, logicalIndex, self, self.styleOptionForCell(logicalIndex), leafIndex) return super().paintSection(painter, rect, logicalIndex) def on_sectionResized(self, logicalIndex: int): if self.isSectionHidden(logicalIndex): return leafIndex = QModelIndex(self._pd.leafIndex(logicalIndex)) if leafIndex.isValid(): leafsList = QModelIndexList(self._pd.leafs(self._pd.findRootIndex(leafIndex))) for n in range(leafsList.indexOf(leafIndex), 0, -1): logicalIndex-=1 w = self.viewport().width() h = self.viewport().height() pos = self.sectionViewportPosition(logicalIndex) r = QRect(pos, 0, w - pos, h) if self.orientation() == Qt.Horizontal: if self.isRightToLeft(): r.setRect(0, 0, pos + self.sectionSize(logicalIndex), h) else: r.setRect(0, pos, w, h - pos) self.viewport().update(r.normalized()) def setModel(self, model): super().setModel(model) model.layoutChanged.connect(self.layoutChanged) self.layoutChanged() def layoutChanged(self): if self.model(): self._pd.initFromNewModel(self.orientation(), self.model()) axis = ("column", "row")[self.orientation()!=Qt.Horizontal] cnt = getattr(self.model(), axis+"Count")(QModelIndex()) if cnt: self.initializeSections(0, cnt-1) MultiIndexHeaderView=HierarchicalHeaderView class DataFrameModel(QtCore.QAbstractTableModel): #na_values:least|greatest - for sorting options = {"striped": True, "stripesColor": "#fafafa", "na_values": "least", "tooltip_min_len": 21} def __init__(self, dataframe=None): super().__init__() self.setDataFrame(dataframe if dataframe is not None else pd.DataFrame()) def setDataFrame(self, dataframe): self.df = dataframe.copy() # self.df_full = self.df self.layoutChanged.emit() def rowCount(self, parent): return len(self.df) def columnCount(self, parent): return len(self.df.columns) def readLevel(self, y=0, xs=0, xe=None, orient=None): c = getattr(self.df, ("columns", "index")[orient!=HorizontalHeaderDataRole]) if not hasattr(c, "levels"): #not MultiIndex return [QtGui.QStandardItem(str(i)) for i in c] sibl = [] section_start, v, xe = xs, None, xe or len(c) for i in range(xs, xe): label = c.labels[y][i] if label!=v: if y+1<len(c.levels) and i>xs: children = self.readLevel(y+1, section_start, i, orient=orient) sibl[-1].appendRow(children) item = QtGui.QStandardItem(str(c.levels[y][label])) sibl.append(item) section_start = i v=label if y+1<len(c.levels): children = self.readLevel(y+1, section_start, orient=orient) sibl[-1].appendRow(children) return sibl def data(self, index, role): row, col = index.row(), index.column() if role in (Qt.DisplayRole, Qt.ToolTipRole): ret = self.df.iat[row, col] if ret is not None and ret==ret: #convert to str except for None, NaN, NaT if isinstance(ret, float): ret = "{:n}".format(ret) elif isinstance(ret, datetime.date): #FIXME: show microseconds optionally ret = ret.strftime(("%x", "%c")[isinstance(ret, datetime.datetime)]) else: ret = str(ret) if role == Qt.ToolTipRole: if len(ret)<self.options["tooltip_min_len"]: ret = "" return ret elif role == Qt.BackgroundRole: if self.options["striped"] and row%2: return QBrush(QColor(self.options["stripesColor"])) elif role in (HorizontalHeaderDataRole, VerticalHeaderDataRole): hm = QtGui.QStandardItemModel() hm.appendRow(self.readLevel(orient=role)) return hm def reorder(self, oldIndex, newIndex, orientation): "Reorder columns / rows" horizontal = orientation==Qt.Horizontal cols = list(self.df.columns if horizontal else self.df.index) cols.insert(newIndex, cols.pop(oldIndex)) self.df = self.df[cols] if horizontal else self.df.T[cols].T return True # def filter(self, filt=None): # self.df = self.df_full if filt is None else self.df[filt] # self.layoutChanged.emit() def headerData(self, section, orientation, role): if role != Qt.DisplayRole: return label = getattr(self.df, ("columns", "index")[orientation!=Qt.Horizontal])[section] # return label if type(label) is tuple else label return ("\n", " | ")[orientation!=Qt.Horizontal].join(str(i) for i in label) if type(label) is tuple else str(label) def dataFrame(self): return self.df def sort(self, column, order): # print("sort", column, order) #FIXME: double sort after setSortingEnabled(True) if len(self.df): asc = order==Qt.AscendingOrder na_pos = 'first' if (self.options["na_values"]=="least")==asc else 'last' self.df.sort_values(self.df.columns[column], ascending=asc, inplace=True, na_position=na_pos) self.layoutChanged.emit() if __name__=="__main__": import sys, locale locale.setlocale(locale.LC_ALL, '') #system locale settings app = QtGui.QApplication(sys.argv) form = QtGui.QWidget() form.setAttribute(Qt.WA_DeleteOnClose) #http://stackoverflow.com/a/27178019/1119602 form.setMinimumSize(700, 260) view = QtGui.QTableView() QtGui.QVBoxLayout(form).addWidget(view) form.show() #Prepare data tuples=[('bar', 'one', 'q'), ('bar', 'two', 'q'), ('baz', 'one', 'q'), ('baz', 'two', 'q'), ('foo', 'one', 'q'), ('foo', 'two', 'q'), ('qux', 'one', 'q'), ('qux', 'two', 'q')] index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second', 'third']) df=pd.DataFrame(pd.np.random.randn(6, 6), index=index[:6], columns=index[:6]) print("DataFrame:\n%s"%df) #Prepare view # oldh, oldv = view.horizontalHeader(), view.verticalHeader() # oldh.setParent(form), oldv.setParent(form) #Save old headers for some reason MultiIndexHeaderView(Qt.Horizontal, view) MultiIndexHeaderView(Qt.Vertical, view) view.horizontalHeader().setMovable(True) #reorder DataFrame columns manually #Set data view.setModel(DataFrameModel(df)) view.resizeColumnsToContents() view.resizeRowsToContents() #Set sorting enabled (after setting model) view.setSortingEnabled(True) sys.exit(app.exec())
def sizeHint(self): size = QSize() size.setHeight(200) return size
class PluginWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.pluginMetadata = {} # Main layout self.mainLayout = QVBoxLayout() self.setLayout(self.mainLayout) # Define size used for the underlines self.underlineSize = QSize() self.underlineSize.setHeight(1) # Define font used for headers self.font = QFont() self.font.setPointSize(11) self.font.setBold(True) self.font.setUnderline(True) # Plugins Description self.pluginDescription = QLabel() self.pluginDescription.setText("Click a plugin to see more information." + " Plugins can be configured from the Recording tab. \n") self.pluginDescription.setWordWrap(True) # Plugins GroupBox self.pluginLayout = QVBoxLayout() self.pluginGroupBox = QGroupBox("Plugins extend the functionality of Freeseer") self.pluginGroupBox.setLayout(self.pluginLayout) self.pluginLayout.insertWidget(0, self.pluginDescription) self.mainLayout.insertWidget(0, self.pluginGroupBox) # Plugins list self.list = QTreeWidget() self.list.setHeaderHidden(True) self.list.headerItem().setText(0, "1") self.pluginLayout.insertWidget(1, self.list) # Details self.detailPane = QGroupBox() self.detailLayout = QVBoxLayout() self.detailPane.setLayout(self.detailLayout) self.detailPaneDesc = QLabel() self.detailPaneDesc.setWordWrap(True) self.detailLayout.addWidget(self.detailPaneDesc) self.pluginLayout.insertWidget(2, self.detailPane) self.list.itemSelectionChanged.connect(self.treeViewSelect) def treeViewSelect(self): item = self.list.currentItem() key = str(item.text(0)) if key in self.pluginMetadata.keys(): self.showDetails(key) else: self.hideDetails() def showDetails(self, key): self.detailPane.setTitle(key) self.detailPaneDesc.setText(self.pluginMetadata[key]) self.detailPane.show() def hideDetails(self): self.detailPane.hide() def getWidgetPlugin(self, plugin, plugin_category, plugman): plugin_name = plugin.plugin_object.get_name() item = QTreeWidgetItem() # Display Plugin's meta data in a tooltip pluginDetails = """ <table> <tr> <td>Name: </td> <td><b>%(name)s</b></td> </tr> <tr> <td>Version: </td> <td><b>%(version)s</b></td> <tr> <td>Author: </td> <td><b>%(author)s</b></td> </tr> <tr> <td>Website: </td> <td><b>%(website)s</b></td> </tr> <tr> <td>Description: </td> <td><b>%(description)s</b></td> </tr> </table> """ % {"name": plugin.name, "version": plugin.version, "author": plugin.author, "website": plugin.website, "description": plugin.description} # put the details in the hash table self.pluginMetadata[plugin_name] = pluginDetails item.setText(0, plugin_name) return item
def sizeHint(self): size = QSize() size.setWidth(640) size.setHeight(480) return size
class PluginWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.pluginMetadata = {} # Main layout self.mainLayout = QVBoxLayout() self.setLayout(self.mainLayout) # Define size used for the underlines self.underlineSize = QSize() self.underlineSize.setHeight(1) # Define font used for headers self.font = QFont() self.font.setPointSize(11) self.font.setBold(True) self.font.setUnderline(True) # Plugins Description self.pluginDescription = QLabel() self.pluginDescription.setText( "Click a plugin to see more information." + " Plugins can be configured from the Recording tab. \n") self.pluginDescription.setWordWrap(True) # Plugins GroupBox self.pluginLayout = QVBoxLayout() self.pluginGroupBox = QGroupBox( "Plugins extend the functionality of Freeseer") self.pluginGroupBox.setLayout(self.pluginLayout) self.pluginLayout.insertWidget(0, self.pluginDescription) self.mainLayout.insertWidget(0, self.pluginGroupBox) # Plugins list self.list = QTreeWidget() self.list.setHeaderHidden(True) self.list.headerItem().setText(0, "1") self.pluginLayout.insertWidget(1, self.list) # Details self.detailPane = QGroupBox() self.detailLayout = QVBoxLayout() self.detailPane.setLayout(self.detailLayout) self.detailPaneDesc = QLabel() self.detailPaneDesc.setWordWrap(True) self.detailLayout.addWidget(self.detailPaneDesc) self.pluginLayout.insertWidget(2, self.detailPane) self.list.itemSelectionChanged.connect(self.treeViewSelect) def treeViewSelect(self): item = self.list.currentItem() key = str(item.text(0)) if key in self.pluginMetadata.keys(): self.showDetails(key) else: self.hideDetails() def showDetails(self, key): self.detailPane.setTitle(key) self.detailPaneDesc.setText(self.pluginMetadata[key]) self.detailPane.show() def hideDetails(self): self.detailPane.hide() def getWidgetPlugin(self, plugin, plugin_category, plugman): plugin_name = plugin.plugin_object.get_name() item = QTreeWidgetItem() # Display Plugin's meta data in a tooltip pluginDetails = """ <table> <tr> <td>Name: </td> <td><b>%(name)s</b></td> </tr> <tr> <td>Version: </td> <td><b>%(version)s</b></td> <tr> <td>Author: </td> <td><b>%(author)s</b></td> </tr> <tr> <td>Website: </td> <td><b>%(website)s</b></td> </tr> <tr> <td>Description: </td> <td><b>%(description)s</b></td> </tr> </table> """ % { "name": plugin.name, "version": plugin.version, "author": plugin.author, "website": plugin.website, "description": plugin.description } # put the details in the hash table self.pluginMetadata[plugin_name] = pluginDetails item.setText(0, plugin_name) return item