class PysideGui(generic.GenericGui): def __init__(self): generic.GenericGui.__init__(self) window = QWidget() window.setWindowTitle('quichem-pyside') self.compiler_view = QListWidget() self.compiler_view.currentRowChanged.connect(self.show_source) self.stacked_widget = QStackedWidget() self.stacked_widget.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) self.edit = QLineEdit() self.edit.setPlaceholderText('Type quichem input...') self.edit.textChanged.connect(self.change_value) self.view = QWebView() self.view.page().mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff) self.view.page().action(QWebPage.Reload).setVisible(False) self.view.setMaximumHeight(0) self.view.setUrl('qrc:/web/page.html') self.view.setZoomFactor(2) self.view.page().mainFrame().contentsSizeChanged.connect( self._resize_view) # For debugging JS: ## from PySide.QtWebKit import QWebSettings ## QWebSettings.globalSettings().setAttribute( ## QWebSettings.DeveloperExtrasEnabled, True) button_image = QPushButton('Copy as Image') button_image.clicked.connect(self.set_clipboard_image) button_image.setToolTip('Then paste into any graphics program') button_word = QPushButton('Copy as MS Word Equation') button_word.clicked.connect(self.set_clipboard_word) button_html = QPushButton('Copy as Formatted Text') button_html.clicked.connect(self.set_clipboard_html) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) button_layout = QHBoxLayout() button_layout.addStretch() button_layout.addWidget(button_image) button_layout.addWidget(button_word) button_layout.addWidget(button_html) source_layout = QHBoxLayout() source_layout.addWidget(self.compiler_view) source_layout.addWidget(self.stacked_widget, 1) QVBoxLayout(window) window.layout().addWidget(self.edit) window.layout().addWidget(self.view) window.layout().addLayout(button_layout) window.layout().addWidget(line) window.layout().addLayout(source_layout, 1) window.show() window.resize(window.minimumWidth(), window.height()) # To prevent garbage collection of internal Qt object. self._window = window def show_source(self, index): if not self.sources: return self.stacked_widget.setCurrentIndex(index) self.change_value(self.edit.text()) def _resize_view(self): """Set the QWebView's minimum height based on its current contents. """ div = self.view.page().mainFrame().findFirstElement('.output') scrollbar_width = QApplication.style().pixelMetric( QStyle.PM_ScrollBarExtent) self.view.setMaximumHeight( div.geometry().height() + scrollbar_width + 16) def make_source(self, name): self.compiler_view.addItem(name) self.compiler_view.setCurrentRow(0) scrollbar_width = QApplication.style().pixelMetric( QStyle.PM_ScrollBarExtent) self.compiler_view.setMaximumWidth( self.compiler_view.sizeHintForColumn(0) + scrollbar_width + 16) page = QWidget() QHBoxLayout(page) page.layout().setContentsMargins(*(0,) * 4) source = QTextEdit() source.setStyleSheet('min-width: 0; min-height: 0') source.setReadOnly(True) QVBoxLayout(source) button = QPushButton('Copy') button.clicked.connect(functools.partial(self.set_clipboard, source)) page.layout().addWidget(source) source.layout().addWidget(button, 0, Qt.AlignRight | Qt.AlignBottom) self.stacked_widget.addWidget(page) return source def run_script(self, js): self.view.page().mainFrame().evaluateJavaScript(js) def set_source(self, widget, source_factory): if widget.isVisible(): widget.setPlainText(source_factory()) def set_clipboard_image(self): """Export the formatted output to an image and store it in the clipboard. The image stored in the clipboard is a PNG file with alpha transparency. """ div = self.view.page().mainFrame().findFirstElement('.output') images = {} for background in (Qt.transparent, Qt.white): image = QImage(div.geometry().size(), QImage.Format_ARGB32_Premultiplied) image.fill(background) painter = QPainter(image) div.render(painter) painter.end() images[background] = image # Windows needs this buffer hack to get alpha transparency in # the copied PNG. buffer_ = QBuffer() buffer_.open(QIODevice.WriteOnly) images[Qt.transparent].save(buffer_, 'PNG') buffer_.close() data = QMimeData() data.setData('PNG', buffer_.data()) data.setImageData(images[Qt.white]) QApplication.clipboard().setMimeData(data) def set_clipboard_word(self): """Store the formatted output in the clipboard in a Microsoft Word friendly format. Microsoft Word interprets the clipboard contents as an equation. Other programs will see it as plain text containing XML. """ QApplication.clipboard().setText(generic.word_equation_from_mathml( self.view.page().mainFrame().evaluateJavaScript(generic.MML_JS))) def set_clipboard_html(self): """Place the HTML displayed in the HTML view widget into the system clipboard. """ data = QMimeData() data.setText(self.plain) data.setHtml(self.html) QApplication.clipboard().setMimeData(data) def set_clipboard(self, source): """Place the text displayed in the given source widget into the system clipboard. """ QApplication.clipboard().setText(source.toPlainText())