class PlotViewer(QWidget): feedPlotControls = Signal(str) def __init__(self): super().__init__() self.webView = QWebEngineView() layout = QGridLayout() layout.addWidget(self.webView, 0, 0) self.setLayout(layout) self.json_data = '' self.plot_type = 'Regressão' self.webView.page().profile().downloadRequested.connect(self.download_handler) def loadPlot(self, _url, _json=None, _type='Regressão'): assert(isinstance(_json, str)) #takes html local address to plot generated by plotly if _json is not None: self.json_data = _json self.feedPlotControls.emit(self.json_data) self.plot_type = _type url = QUrl.fromLocalFile(os.path.abspath(_url)) self.webView.load(url) def erasePlot(self): self.json_data = '' pcengine = PlotControleEngine.PlotControlEngine(self.json_data) _url, self.json_data = pcengine.render() url = QUrl.fromLocalFile((os.path.abspath(_url))) self.webView.load(url) def download_handler(self, item): file_path = QFileDialog().getSaveFileName(self, "Salvar Plot", filter="PNG (*.png);;") item.setPath(file_path[0]) item.accept()
def print_pdf(page: QWebEngineView, filename): page.page().printToPdf( filename, QPageLayout(QPageSize(QPageSize.A4), QPageLayout.Portrait, QMarginsF(5 * mm, 5 * mm, 5 * mm, 5 * mm))) page.page().pdfPrintingFinished.connect( lambda file_path, success: app.quit())
class MainTest(unittest.TestCase): def test_WebEngineView_findText_exists(self): QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) app = QApplication.instance() or QApplication() top_level = QWidget() layout = QVBoxLayout(top_level) self._view = QWebEngineView() self._view.loadFinished.connect(self.loaded) self._view.load(QUrl.fromLocalFile(os.path.join(TEST_DIR, "fox.html"))) self._view.setMinimumSize(QSize(400, 300)) self._callback_count = 0 layout.addWidget(self._view) top_level.show() app.exec_() def found_callback(self, found): self.assertTrue(found) self._callback_count += 1 if self._callback_count == 2: QCoreApplication.quit() def javascript_callback(self, result): self.assertEqual(result, "Title") self._callback_count += 1 if self._callback_count == 2: QCoreApplication.quit() def loaded(self, ok): self.assertTrue(ok) if not ok: QCoreApplication.quit() self._view.page().runJavaScript("document.title", 1, partial(self.javascript_callback)) self._view.findText("fox", QWebEnginePage.FindFlags(), partial(self.found_callback))
class WebView(QtGui.QMdiSubWindow): closed = QtCore.Signal(object) def __init__(self, title, work_path, request_handler, message_handler, *args, **kwargs): # Window Setup super().__init__(*args, **kwargs) self.setObjectName("freecad.extman.webview") self.setWindowTitle(title) self.setAttribute(Qt.WA_DeleteOnClose, True) # Scheme setup (extman://) self.handler = SchemeHandler(self, request_handler) # WebView setup self.webView = QWebEngineView(self) self.webView.setContextMenuPolicy(Qt.NoContextMenu) self.setWidget(self.webView) # Page setup self.webView.setPage(Page(self.webView)) # Profile setup profile = self.webView.page().profile() profile.setPersistentStoragePath(str(Path(work_path, 'web_data'))) profile.setCachePath(str(Path(work_path, 'web_cache'))) handler = profile.urlSchemeHandler(EXTMAN_URL_SCHEME) if handler is not None: profile.removeUrlSchemeHandler(handler) profile.installUrlSchemeHandler(EXTMAN_URL_SCHEME, self.handler) # Setting setup settings = self.webView.settings() settings.setAttribute(QWebEngineSettings.AutoLoadIconsForPage, True) settings.setAttribute(QWebEngineSettings.LocalContentCanAccessFileUrls, True) settings.setAttribute( QWebEngineSettings.LocalContentCanAccessRemoteUrls, True) # Page settings page = self.webView.page().settings() page.setAttribute(QWebEngineSettings.LocalContentCanAccessFileUrls, True) page.setAttribute(QWebEngineSettings.LocalContentCanAccessRemoteUrls, True) page.setAttribute(QWebEngineSettings.LocalStorageEnabled, True) # WebChannel Setup self.messageBus = MessageBus(message_handler, self.webView) self.channel = QtWebChannel.QWebChannel(self.webView) self.channel.registerObject('ExtManMessageBus', self.messageBus) self.webView.page().setWebChannel(self.channel) def closeEvent(self, event): self.closed.emit(event) event.accept() def load(self, url): self.webView.load(url)
class AuthManager(QWidget): access_token_signal = Signal(str) def __init__(self, app): super(AuthManager, self).__init__() self.app = app self.browser = QWebEngineView() self.interceptor = RequestInterceptor(self) self.interceptor.access_token_signal.connect(self.access_token) def authenticate(self): self.nam = self.browser.page() self.browser.setUrl(QUrl(constants.AUTH_URL)) self.show() self.hBox = QVBoxLayout() self.hBox.addWidget(self.browser) self.setLayout(self.hBox) self.browser.loadFinished.connect(self._loadFinished) self.browser.page().setUrlRequestInterceptor(self.interceptor) @Slot(str) def access_token(self, access_token): self.access_token_signal.emit(access_token) def _loadFinished(self, result): self.browser.page().toHtml(self.callable) def callable(self, data): self.browser.html = data
class MainWindow(QMainWindow): view = None chan = None comm = None def __init__(self, debug=False, parent=None): QMainWindow.__init__(self, parent) QWebEngineSettings.defaultSettings().setAttribute( QWebEngineSettings.JavascriptCanAccessClipboard, True) QWebEngineSettings.defaultSettings().setAttribute( QWebEngineSettings.JavascriptCanPaste, True) self.view = QWebEngineView(self) self.setCentralWidget(self.view) self.chan = QWebChannel(self) self.comm = Comm(self) self.chan.registerObject('channelInterface', self.comm) self.view.page().setWebChannel(self.chan) self.view.setContextMenuPolicy(Qt.NoContextMenu) if debug: self.view.load('http://localhost:8080') self.devView = QWebEngineView() self.view.page().setDevToolsPage(self.devView.page()) self.devView.show() else: url = 'file:///' + QDir.fromNativeSeparators( os.path.abspath( os.path.join(os.path.dirname(__file__), './frontend/dist/index.html'))) self.view.load(QUrl(url))
def CheckWebGL(): script = QWebEngineScript() script.setInjectionPoint(QWebEngineScript.DocumentCreation) script.setSourceCode(jsstr) script.setInjectionPoint(QWebEngineScript.Deferred) browser = QWebEngineView() webpage = MyQWebEnginePage() webpage.setHtml(htmlstr) browser.setPage(webpage) #browser.show() browser.page().scripts().insert(script) print('WebGL=' + str(webglsupport), ) # avoid "Release of profile requested but WebEnginePage still not deleted. Expect troubles !" webpage.deleteLater()
class MaiteBody(QWidget): """Main display body""" def __init__(self): super().__init__(None) # main horizontal view hlay = QHBoxLayout() # left pane e1 = QLineEdit() hlay.addWidget(e1, 25) # right pane self.webEngineView = QWebEngineView() current_path = os.getcwd() fileLocation = current_path + "/reloj.html" print(fileLocation) url = QUrl.fromLocalFile(fileLocation) self.webPage = self.webEngineView.page() self.webEngineView.load(url) self.webEngineView.show() hlay.addWidget(self.webEngineView, 75) self.setLayout(hlay)
def webkit_download(url): app = QApplication([]) webview = QWebEngineView() webview.loadFinished.connect(app.quit) webview.load(url) app.exec_() # delay here until download finished return webview.page().mainFrame().toHtml()
class PDFReportWriter(HTMLReportWriter): def __init__(self, analysis: Analysis): super().__init__(analysis) self._web_view = QWebEngineView() def text(self) -> str: return super().text() def write(self, filepath: str): self._web_view.page().loadFinished.connect( lambda _: self._web_view.page().printToPdf(filepath)) self._web_view.page().pdfPrintingFinished.connect( lambda fp, success: self.writingCompleted.emit(success)) self._web_view.setHtml(self.text(), QUrl("qrc:/")) def isAsync(self) -> bool: return True
def create(ui_path, proxy): view = QWebEngineView() page = view.page() channel = QWebChannel() channel.registerObject('hatPegBrowserProxy', proxy) page.setWebChannel(channel) view.load(str((ui_path / 'index.html').resolve().as_uri())) view.show() _refs[view] = (channel, proxy)
class ManualWindow(QMainWindow): def __init__(self): super(ManualWindow, self).__init__() self.setWindowTitle('QAX Manual') icon_info = QFileInfo(app_info.app_icon_path) self.setWindowIcon(QIcon(icon_info.absoluteFilePath())) self.toolbar = QToolBar() self.addToolBar(self.toolbar) self.back_button = QPushButton() self.back_button.setIcon(qta.icon('fa.arrow-left')) self.back_button.clicked.connect(self.back) self.toolbar.addWidget(self.back_button) self.forward_button = QPushButton() self.forward_button.setIcon(qta.icon('fa.arrow-right')) self.forward_button.clicked.connect(self.forward) self.toolbar.addWidget(self.forward_button) self.address_line_edit = QLineEdit() self.address_line_edit.returnPressed.connect(self.load) self.address_line_edit.setVisible(False) self.toolbar.addWidget(self.address_line_edit) self.web_engine_view = QWebEngineView() self.web_engine_view.setZoomFactor(2.0) self.setCentralWidget(self.web_engine_view) initialUrl = self.docs_url() self.address_line_edit.setText(str(initialUrl)) self.web_engine_view.load(QUrl(initialUrl)) self.web_engine_view.page().urlChanged.connect(self.urlChanged) def docs_url(self): rel_docs_path = 'docs/_build/html/index.html' abs_docs_oath = os.path.abspath(rel_docs_path) if (os.path.isfile(abs_docs_oath)): return QUrl.fromLocalFile(abs_docs_oath) raise RuntimeError("Docs not found at {}".format(abs_docs_oath)) def load(self): url = QUrl.fromUserInput(self.address_line_edit.text()) if url.isValid(): self.web_engine_view.load(url) def back(self): self.web_engine_view.page().triggerAction(QWebEnginePage.Back) def forward(self): self.web_engine_view.page().triggerAction(QWebEnginePage.Forward) def urlChanged(self, url): self.address_line_edit.setText(url.toString())
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle('PySide2 WebEngineWidgets Example') self.toolBar = QToolBar() self.addToolBar(self.toolBar) self.backButton = QPushButton() self.backButton.setIcon( QIcon(':/qt-project.org/styles/commonstyle/images/left-32.png')) self.backButton.clicked.connect(self.back) self.toolBar.addWidget(self.backButton) self.forwardButton = QPushButton() self.forwardButton.setIcon( QIcon(':/qt-project.org/styles/commonstyle/images/right-32.png')) self.forwardButton.clicked.connect(self.forward) self.toolBar.addWidget(self.forwardButton) self.addressLineEdit = QLineEdit() self.addressLineEdit.returnPressed.connect(self.load) self.toolBar.addWidget(self.addressLineEdit) self.webEngineView = QWebEngineView() self.setCentralWidget(self.webEngineView) initialUrl = 'http://qt.io' self.addressLineEdit.setText(initialUrl) self.webEngineView.load(QUrl(initialUrl)) self.webEngineView.page().titleChanged.connect(self.setWindowTitle) self.webEngineView.page().urlChanged.connect(self.urlChanged) def load(self): url = QUrl.fromUserInput(self.addressLineEdit.text()) if url.isValid(): self.webEngineView.load(url) def back(self): self.webEngineView.page().triggerAction(QWebEnginePage.Back) def forward(self): self.webEngineView.page().triggerAction(QWebEnginePage.Forward) def urlChanged(self, url): self.addressLineEdit.setText(url.toString())
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle('PySide2 WebEngineWidgets Example') self.toolBar = QToolBar() self.addToolBar(self.toolBar) self.backButton = QPushButton() self.backButton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/left-32.png')) self.backButton.clicked.connect(self.back) self.toolBar.addWidget(self.backButton) self.forwardButton = QPushButton() self.forwardButton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/right-32.png')) self.forwardButton.clicked.connect(self.forward) self.toolBar.addWidget(self.forwardButton) self.addressLineEdit = QLineEdit() self.addressLineEdit.returnPressed.connect(self.load) self.toolBar.addWidget(self.addressLineEdit) self.webEngineView = QWebEngineView() self.setCentralWidget(self.webEngineView) initialUrl = 'http://qt.io' self.addressLineEdit.setText(initialUrl) self.webEngineView.load(QUrl(initialUrl)) self.webEngineView.page().titleChanged.connect(self.setWindowTitle) self.webEngineView.page().urlChanged.connect(self.urlChanged) def load(self): url = QUrl.fromUserInput(self.addressLineEdit.text()) if url.isValid(): self.webEngineView.load(url) def back(self): self.webEngineView.page().triggerAction(QWebEnginePage.Back) def forward(self): self.webEngineView.page().triggerAction(QWebEnginePage.Forward) def urlChanged(self, url): self.addressLineEdit.setText(url.toString())
class WebEngineScreenshot(QApplication): def __init__(self, url, width, height, *args, **kwargs): self.display = Xvfb(int(width * 1.2), int(height * 1.2)) self.display.start() super().__init__(*args, **kwargs) self.engine = QWebEngineView() size = QSize(width, height) self.engine.setFixedSize(size) self.engine.setPage(QWebEnginePage()) settings = self.engine.page().settings() settings.setAttribute(QWebEngineSettings.ShowScrollBars, False) settings.setAttribute(QWebEngineSettings.JavascriptCanOpenWindows, False) settings.setAttribute(QWebEngineSettings.LocalStorageEnabled, False) settings.setAttribute(QWebEngineSettings.HyperlinkAuditingEnabled, False) settings.setAttribute(QWebEngineSettings.PluginsEnabled, False) settings.setAttribute(QWebEngineSettings.FullScreenSupportEnabled, False) settings.setAttribute(QWebEngineSettings.ScreenCaptureEnabled, False) self.engine.loadFinished.connect(self.load_finished) self.engine.load(QUrl(url)) self.engine.show() @Slot(bool) def load_finished(self, state): pixmap = self.engine.grab() self.image = QByteArray() buf = QBuffer(self.image) buf.open(QIODevice.WriteOnly) pixmap.save(buf, "PNG") buf.close() self.quit() def run(self): try: self.exec_() except Exception: return None finally: self.display.stop() return self.image.data()
def main(): app = QApplication([]) webview = QWebEngineView() loop = QEventLoop() webview.loadFinished.connect(loop.quit) webview.load(QUrl('http://example.webscraping.com/places/default/search')) loop.exec_() webview.show() frame = webview.page().mainFrame() frame.findFirstElement('#search_term').setAttribute('value', '.') frame.findFirstElement('#page_size option:checked').setPlainText('1000') frame.findFirstElement('#search').evaluateJavaScript('this.click()') elements = None while not elements: app.processEvents() elements = frame.findAllElements('#results a') countries = [e.toPlainText().strip() for e in elements] print(countries)
def add_new_tab(self, qurl=None, label="Blank"): if qurl is None: qurl = QUrl("") browser = QWebEngineView() browser.setUrl(qurl) i = self.tabs.addTab(browser, label) self.tabs.setCurrentIndex(i) # end::addNewTab[] # tag::addNewTabSignals[] # More difficult! We only want to update the url when it's from the # correct tab browser.urlChanged.connect( lambda qurl, browser=browser: self.update_urlbar(qurl, browser)) browser.loadFinished.connect(lambda _, i=i, browser=browser: self.tabs. setTabText(i, browser.page().title()))
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle('PySide2 WebEngineWidgets Example') self.toolBar = QToolBar() self.addToolBar(self.toolBar) self.backButton = QPushButton('<-') self.backButton.clicked.connect(self.back) self.toolBar.addWidget(self.backButton) self.forwardButton = QPushButton() self.forwardButton.setIcon( QIcon(':/qt-project.org/styles/commonstyle/images/right-32.png')) self.forwardButton.clicked.connect(self.forward) self.toolBar.addWidget(self.forwardButton) self.backButton = QPushButton('새로고침') self.backButton.clicked.connect(self.reload) self.toolBar.addWidget(self.backButton) self.qcomboBox = QComboBox() # #self.qcomboBox.addItem("Banana") # 단일 아이템 추가시 self.qcomboBox.addItems(["통합검색", "이미지검색", "쇼핑검색", '맞춤검색']) # 다수 아이템 추가시 self.qcomboBox.insertSeparator(2) # 구분 선 self.toolBar.addWidget(self.qcomboBox) self.addressLineEdit = QLineEdit() #self.addressLineEdit.setGeometry(10,10,200,200) self.addressLineEdit.returnPressed.connect(self.load) self.toolBar.addWidget(self.addressLineEdit) self.sButton01 = QPushButton('네이버', self) #self.forwardButton.('네이버') self.sButton01.clicked.connect(self.button_clicked) self.toolBar.addWidget(self.sButton01) self.sButton02 = QPushButton('구글', self) #self.forwardButton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/right-32.png')) self.sButton02.clicked.connect(self.button_clicked) self.toolBar.addWidget(self.sButton02) self.sButton03 = QPushButton('유튜브', self) #self.forwardButton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/right-32.png')) self.sButton03.clicked.connect(self.button_clicked) self.toolBar.addWidget(self.sButton03) self.sButton04 = QPushButton('인스타그램', self) #self.forwardButton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/right-32.png')) self.sButton04.clicked.connect(self.button_clicked) self.toolBar.addWidget(self.sButton04) self.sButton05 = QPushButton('다음', self) # self.forwardButton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/right-32.png')) self.sButton05.clicked.connect(self.button_clicked) self.toolBar.addWidget(self.sButton05) self.sButton06 = QPushButton('줌', self) # self.forwardButton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/right-32.png')) self.sButton06.clicked.connect(self.button_clicked) self.toolBar.addWidget(self.sButton06) self.sButton07 = QPushButton('도움말', self) # self.forwardButton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/right-32.png')) self.sButton07.clicked.connect(self.button_clicked) self.toolBar.addWidget(self.sButton07) self.webEngineView = QWebEngineView() self.setCentralWidget(self.webEngineView) initialUrl = "https://www.naver.com/" self.addressLineEdit.setText('') self.webEngineView.load(QUrl(initialUrl)) self.webEngineView.page().titleChanged.connect(self.setWindowTitle) def load(self): url = QUrl.fromUserInput(self.addressLineEdit.text()) print(url) url1 = "https://search.naver.com/search.naver?sm=top_hty&fbm=1&ie=utf8&query=" + self.addressLineEdit.text( ) if url.isValid(): self.webEngineView.load(url1) def reload(self): self.webEngineView.page().triggerAction( QWebEnginePage.Reload) #이렇게 하면 새로고침이 되네 def back(self): self.webEngineView.page().triggerAction(QWebEnginePage.Back) #뒤로가기 def forward(self): self.webEngineView.page().triggerAction(QWebEnginePage.Forward) #앞으로 def button_clicked(self): url = "" search_keyword = self.addressLineEdit.text() search_engine = self.sender().text() if search_engine == '네이버': url = "https://search.naver.com/search.naver?sm=top_hty&fbm=1&ie=utf8&query=" + search_keyword self.webEngineView.load(url) #보여줘라 if url.isValid(): self.webEngineView.load('https://www.naver.com') elif search_engine == '구글': url = "https://www.google.com/search?newwindow=1&hl=ko&source=hp&ei=pcpjXe78KpG7wAPP8biACA&q=" + search_keyword self.webEngineView.load(url) if not search_keyword: self.webEngineView.load('https://www.google.com') elif search_engine == '유튜브': url = "https://www.youtube.com/results?search_query=" + search_keyword self.webEngineView.load(url) if not search_keyword: self.webEngineView.load('https://www.youtube.com/') elif search_engine == '인스타그램': url = "https://www.instagram.com/explore/tags/" + search_keyword self.webEngineView.load(url) if not search_keyword: self.webEngineView.load('https://www.instagram.com/') elif search_engine == '다음': url = "https://search.daum.net/search?w=tot&DA=YZR&t__nil_searchbox=btn&sug=&sugo=&q=" + search_keyword self.webEngineView.load(url) if not search_keyword: self.webEngineView.load('https://www.daum.net/') elif search_engine == '줌': url = "http://search.zum.com/search.zum?method=uni&option=accu&rd=1&qm=f_typing.top&query=" + search_keyword self.webEngineView.load(url) if not search_keyword: self.webEngineView.load('http://zum.com') elif search_engine == '도움말': url = "https://styleranker.co.kr" self.webEngineView.load(url) print(search_engine) self.curCat = self.sender().text() print(self.curCat)
@Slot(str) def linkHovered(hoveredLink): print(hoveredLink) # alternatively, run an alert box # page.runJavaScript("alert(\""+hoveredLink+"\")") def urlChanged(qulr): print("url changed to: ") print(qulr) app = QApplication([]) view = QWebEngineView() page = view.page() view.loadStarted.connect(print("loadStarted")) view.loadProgress.connect(print("loadProgress")) view.loadFinished.connect(finishLoading) view.titleChanged.connect(titleChanged) page.selectionChanged.connect(selectionChanged) page.linkHovered.connect(linkHovered) page.urlChanged.connect(urlChanged) # content in unicode html format - Content larger than 2 MB cannot be displayed html = "<h1>Heading</h1><p>paragraph</p><p><a href=\"https://marvel.bible\"><img src='marvel.png' alt='Marvel.Bible icon'></a></p>" # External objects, such as stylesheets or images referenced in the HTML document, are located RELATIVE TO baseUrl . # e.g. put all local files linked by html's content in folder "htmlResources"
class NGL_HKLViewer(QWidget): def __init__(self, parent=None): super(NGL_HKLViewer, self).__init__(parent) self.verbose = 0 self.UseOSbrowser = False self.jscriptfname = "" self.devmode = False for e in sys.argv: if "verbose" in e: self.verbose = e.split("verbose=")[1] if "UseOSbrowser" in e: self.UseOSbrowser = e.split("UseOSbrowser=")[1] if "jscriptfname" in e: self.jscriptfname = e.split("jscriptfname=")[1] if "devmode" in e: self.devmode = True self.zmq_context = None self.bufsize = 20000 self.originalPalette = QApplication.palette() self.openFileNameButton = QPushButton("Load reflection file") self.openFileNameButton.setDefault(True) self.openFileNameButton.clicked.connect(self.OpenReflectionsFile) self.debugbutton = QPushButton("Debug") self.debugbutton.clicked.connect(self.DebugInteractively) self.settingsbtn = QPushButton("Settings") self.settingsbtn.clicked.connect(self.SettingsDialog) self.mousemoveslider = QSlider(Qt.Horizontal) self.mousemoveslider.setMinimum(0) self.mousemoveslider.setMaximum(300) self.mousemoveslider.setValue(0) self.mousemoveslider.sliderReleased.connect( self.onFinalMouseSensitivity) self.mousemoveslider.valueChanged.connect(self.onMouseSensitivity) self.mousesensitxtbox = QLineEdit('') self.mousesensitxtbox.setReadOnly(True) self.fontspinBox = QDoubleSpinBox() self.fontspinBox.setSingleStep(1) self.fontspinBox.setRange(4, 50) self.font = QFont() self.font.setFamily(self.font.defaultFamily()) self.fontspinBox.setValue(self.font.pointSize()) #self.fontspinBox.setValue(self.font.pixelSize()) self.fontspinBox.valueChanged.connect(self.onFontsizeChanged) self.Fontsize_labeltxt = QLabel() self.Fontsize_labeltxt.setText("Font size:") self.cameraPerspectCheckBox = QCheckBox() self.cameraPerspectCheckBox.setText("Perspective camera") self.cameraPerspectCheckBox.clicked.connect(self.onCameraPerspect) self.cameraPerspectCheckBox.setCheckState(Qt.Unchecked) self.settingsform = SettingsForm(self) self.MillerComboBox = QComboBox() self.MillerComboBox.activated.connect(self.onMillerComboSelchange) #self.MillerComboBox.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.MillerLabel = QLabel() self.MillerLabel.setText("Selected HKL Scene") self.HKLnameedit = QLineEdit('') self.HKLnameedit.setReadOnly(True) self.textInfo = QTextEdit() self.textInfo.setLineWrapMode(QTextEdit.NoWrap) self.textInfo.setReadOnly(True) labels = [ "Label", "Type", "no. of HKLs", "Span of HKLs", "Min Max data", "Min Max sigmas", "d_min, d_max", "Symmetry unique", "Anomalous" ] self.millertable = QTableWidget(0, len(labels)) self.millertable.setHorizontalHeaderLabels(labels) self.millertable.horizontalHeader().setDefaultAlignment(Qt.AlignLeft) # don't allow editing this table self.millertable.setEditTriggers(QTableWidget.NoEditTriggers) self.createExpansionBox() self.createFileInfoBox() self.CreateSliceTabs() self.createRadiiScaleGroupBox() self.createBinsBox() self.CreateFunctionTabs() mainLayout = QGridLayout() mainLayout.addWidget(self.FileInfoBox, 0, 0) mainLayout.addWidget(self.MillerLabel, 1, 0) mainLayout.addWidget(self.MillerComboBox, 2, 0) mainLayout.addWidget(self.functionTabWidget, 3, 0) mainLayout.addWidget(self.settingsbtn, 4, 0, 1, 1) #import code, traceback; code.interact(local=locals(), banner="".join( traceback.format_stack(limit=10) ) ) if self.UseOSbrowser == False: self.BrowserBox = QWebEngineView() mainLayout.addWidget(self.BrowserBox, 0, 1, 5, 3) self.BrowserBox.setUrl("https://cctbx.github.io/") #self.BrowserBox.setUrl("https://webglreport.com/") #self.BrowserBox.loadFinished.connect(self.onLoadFinished) mainLayout.setColumnStretch(2, 1) mainLayout.setRowStretch(0, 1) mainLayout.setRowStretch(1, 0) mainLayout.setRowStretch(2, 1) mainLayout.setRowStretch(3, 1) mainLayout.setColumnStretch(4, 0) self.setLayout(mainLayout) self.setWindowTitle("HKL-Viewer") self.cctbxproc = None self.LaunchCCTBXPython() self.out = None self.err = None self.comboviewwidth = 0 self.hklscenes_arrays = [] self.array_infotpls = [] self.matching_arrays = [] self.bin_infotpls = None self.bin_opacities = None self.html_url = "" self.spacegroups = [] self.info = [] self.infostr = "" self.fileisvalid = False self.NewFileLoaded = False self.NewHKLscenes = False self.updatingNbins = False self.binstableitemchanges = False self.show() def SettingsDialog(self): self.settingsform.show() def update(self): if self.cctbxproc: if self.cctbxproc.stdout: print(self.cctbxproc.stdout.read().decode("utf-8")) if self.cctbxproc.stderr: print(self.cctbxproc.stderr.read().decode("utf-8")) if self.out: print(self.out.decode("utf-8")) if self.err: print(self.err.decode("utf-8")) if self.zmq_context: try: msg = self.socket.recv( flags=zmq.NOBLOCK ) #To empty the socket from previous messages msgstr = msg.decode() self.infodict = eval(msgstr) #print("received from cctbx: " + str(self.infodict)) if self.infodict: if self.infodict.get("hklscenes_arrays"): self.hklscenes_arrays = self.infodict.get( "hklscenes_arrays", []) if self.infodict.get("array_infotpls"): self.array_infotpls = self.infodict.get( "array_infotpls", []) if self.infodict.get("bin_data_label"): self.BinDataComboBox.setCurrentText( self.infodict["bin_data_label"]) if self.infodict.get("bin_infotpls"): self.bin_infotpls = self.infodict["bin_infotpls"] self.nbins = len(self.bin_infotpls) self.updatingNbins = True self.Nbins_spinBox.setValue(self.nbins) self.updatingNbins = False self.binstable.clearContents() self.binstable.setRowCount(self.nbins) for row, bin_infotpl in enumerate(self.bin_infotpls): for col, elm in enumerate(bin_infotpl): # only allow changing the last column with opacity values if col != 3: item = QTableWidgetItem(str(elm)) else: item = QTableWidgetItem() item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) item.setCheckState(Qt.Checked) item.setFlags(item.flags() ^ Qt.ItemIsEditable) self.binstable.setItem(row, col, item) if self.bin_opacities: self.update_table_opacities() if self.infodict.get("bin_opacities"): self.bin_opacities = self.infodict["bin_opacities"] if self.binstable.rowCount() > 0: self.update_table_opacities() if self.infodict.get("html_url"): self.html_url = self.infodict["html_url"] if self.UseOSbrowser == False: self.BrowserBox.setUrl(self.html_url) # workaround for background colour bug in chromium # https://bugreports.qt.io/browse/QTBUG-41960 self.BrowserBox.page().setBackgroundColor( QColor(100, 100, 100, 1.0)) if self.infodict.get("spacegroups"): self.spacegroups = self.infodict.get("spacegroups", []) self.SpaceGroupComboBox.clear() self.SpaceGroupComboBox.addItems(self.spacegroups) if self.infodict.get("merge_data"): self.mergedata = self.infodict["merge_data"] currentinfostr = "" if self.infodict.get("info"): currentinfostr = self.infodict.get("info", []) if self.infodict.get("NewFileLoaded"): self.NewFileLoaded = self.infodict.get( "NewFileLoaded", False) if self.infodict.get("NewHKLscenes"): self.NewHKLscenes = self.infodict.get( "NewHKLscenes", False) self.fileisvalid = True #print("ngl_hkl_infodict: " + str(ngl_hkl_infodict)) if currentinfostr: #print(currentinfostr) self.infostr += currentinfostr + "\n" # display no more than self.bufsize bytes of text self.infostr = self.infostr[-self.bufsize:] self.textInfo.setPlainText(self.infostr) self.textInfo.verticalScrollBar().setValue( self.textInfo.verticalScrollBar().maximum()) if self.NewFileLoaded and self.NewHKLscenes: #if self.mergedata == True : val = Qt.CheckState.Checked #if self.mergedata == None : val = Qt.CheckState.PartiallyChecked #if self.mergedata == False : val = Qt.CheckState.Unchecked #self.mergecheckbox.setCheckState(val ) #print("got hklscenes: " + str(self.hklscenes_arrays)) self.MillerComboBox.clear() self.MillerComboBox.addItems( [e[3] for e in self.hklscenes_arrays]) self.MillerComboBox.setCurrentIndex( -1) # unselect the first item in the list self.comboviewwidth = 0 for e in self.hklscenes_arrays: self.comboviewwidth = max( self.comboviewwidth, self.MillerComboBox.fontMetrics().width(e[3])) self.MillerComboBox.view().setMinimumWidth( self.comboviewwidth) self.millertable.clearContents() self.millertable.setRowCount(len( self.hklscenes_arrays)) for n, millarr in enumerate(self.array_infotpls): for m, elm in enumerate(millarr): self.millertable.setItem( n, m, QTableWidgetItem(str(elm))) self.functionTabWidget.setDisabled(True) self.NewFileLoaded = False if self.NewHKLscenes: self.BinDataComboBox.clear() self.BinDataComboBox.addItems( ["Resolution"] + [e[3] for e in self.hklscenes_arrays]) self.BinDataComboBox.view().setMinimumWidth( self.comboviewwidth) #self.BinDataComboBox.setCurrentIndex(-1) # unselect the first item in the list self.NewHKLscenes = False except Exception as e: errmsg = str(e) if "Resource temporarily unavailable" not in errmsg: print(errmsg + traceback.format_exc(limit=10)) pass def onFinalMouseSensitivity(self): val = self.mousemoveslider.value() / 100.0 self.NGL_HKL_command( 'NGL_HKLviewer.viewer.NGL.mouse_sensitivity = %f' % val) def onMouseSensitivity(self): val = self.mousemoveslider.value() / 100.0 self.mousesensitxtbox.setText("%2.2f" % val) def onFontsizeChanged(self, val): font = app.font() font.setPointSize(val) app.setFont(font) self.settingsform.setFixedSize(self.settingsform.sizeHint()) def onCameraPerspect(self, val): if self.cameraPerspectCheckBox.isChecked(): self.NGL_HKL_command("NGL_HKLviewer.camera_type = perspective") else: self.NGL_HKL_command("NGL_HKLviewer.camera_type = orthographic") def MergeData(self): if self.mergecheckbox.checkState() == Qt.CheckState.Checked: self.NGL_HKL_command('NGL_HKLviewer.mergedata = True') if self.mergecheckbox.checkState() == Qt.CheckState.PartiallyChecked: self.NGL_HKL_command('NGL_HKLviewer.mergedata = None') if self.mergecheckbox.checkState() == Qt.CheckState.Unchecked: self.NGL_HKL_command('NGL_HKLviewer.mergedata = False') def ExpandToP1(self): if self.expandP1checkbox.isChecked(): self.NGL_HKL_command('NGL_HKLviewer.viewer.expand_to_p1 = True') else: self.NGL_HKL_command('NGL_HKLviewer.viewer.expand_to_p1 = False') def ExpandAnomalous(self): if self.expandAnomalouscheckbox.isChecked(): self.NGL_HKL_command( 'NGL_HKLviewer.viewer.expand_anomalous = True') else: self.NGL_HKL_command( 'NGL_HKLviewer.viewer.expand_anomalous = False') def showSysAbsent(self): if self.sysabsentcheckbox.isChecked(): self.NGL_HKL_command( 'NGL_HKLviewer.viewer.show_systematic_absences = True') else: self.NGL_HKL_command( 'NGL_HKLviewer.viewer.show_systematic_absences = False') def showMissing(self): if self.missingcheckbox.isChecked(): self.NGL_HKL_command('NGL_HKLviewer.viewer.show_missing = True') else: self.NGL_HKL_command('NGL_HKLviewer.viewer.show_missing = False') def showOnlyMissing(self): if self.onlymissingcheckbox.isChecked(): self.NGL_HKL_command( 'NGL_HKLviewer.viewer.show_only_missing = True') else: self.NGL_HKL_command( 'NGL_HKLviewer.viewer.show_only_missing = False') def showSlice(self): if self.showslicecheckbox.isChecked(): self.NGL_HKL_command('NGL_HKLviewer.viewer.slice_mode = True') if self.expandP1checkbox.isChecked(): self.NGL_HKL_command("""NGL_HKLviewer.viewer { expand_to_p1 = True inbrowser = False } """) if self.expandAnomalouscheckbox.isChecked(): self.NGL_HKL_command("""NGL_HKLviewer.viewer { expand_anomalous = True inbrowser = False } """) else: self.NGL_HKL_command("""NGL_HKLviewer.viewer { slice_mode = False inbrowser = True } """) def onSliceComboSelchange(self, i): rmin = self.array_infotpls[self.MillerComboBox.currentIndex()][3][0][i] rmax = self.array_infotpls[self.MillerComboBox.currentIndex()][3][1][i] self.sliceindexspinBox.setRange(rmin, rmax) self.NGL_HKL_command("NGL_HKLviewer.viewer.slice_axis = %s" % self.sliceaxis[i]) def onSliceIndexChanged(self, val): self.sliceindex = val self.NGL_HKL_command("NGL_HKLviewer.viewer.slice_index = %d" % self.sliceindex) def onBindataComboSelchange(self, i): if self.BinDataComboBox.currentText(): if self.BinDataComboBox.currentIndex() > 0: bin_scene_label = str(self.BinDataComboBox.currentIndex() - 1) else: bin_scene_label = "Resolution" self.NGL_HKL_command("NGL_HKLviewer.bin_scene_label = %s" % bin_scene_label) def update_table_opacities(self, allalpha=None): bin_opacitieslst = eval(self.bin_opacities) self.binstable_isready = False for binopacity in bin_opacitieslst: if not allalpha: alpha = float(binopacity.split(",")[0]) else: alpha = allalpha bin = int(binopacity.split(",")[1]) item = QTableWidgetItem() item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) if alpha < 0.5: item.setCheckState(Qt.Unchecked) else: item.setCheckState(Qt.Checked) item.setFlags(item.flags() ^ Qt.ItemIsEditable) self.binstable.setItem(bin, 3, item) self.binstable_isready = True def SetOpaqueAll(self): if self.binstableitemchanges: return bin_opacitieslst = eval(self.bin_opacities) nbins = len(bin_opacitieslst) sum = 0 for binopacity in bin_opacitieslst: sum += float(binopacity.split(",")[0]) if sum >= nbins: self.OpaqueAllCheckbox.setCheckState(Qt.Checked) if sum == 0: self.OpaqueAllCheckbox.setCheckState(Qt.Unchecked) if sum > 0.0 and sum < nbins: self.OpaqueAllCheckbox.setCheckState(Qt.PartiallyChecked) def onBinsTableItemChanged(self, item): row = item.row() column = item.column() try: if item.checkState() == Qt.Unchecked: newval = 0 else: newval = 1.0 if column == 3 and self.binstable_isready: # changing opacity assert (newval <= 1.0 and newval >= 0.0) bin_opacitieslst = eval(self.bin_opacities) bin_opacitieslst[row] = str(newval) + ', ' + str(row) self.bin_opacities = str(bin_opacitieslst) self.SetOpaqueAll() self.NGL_HKL_command( 'NGL_HKLviewer.viewer.NGL.bin_opacities = "%s"' % self.bin_opacities) except Exception as e: print(str(e)) #self.binstable.currentItem().setText( self.currentSelectedBinsTableVal) def onBinsTableItemSelectionChanged(self): row = self.binstable.currentItem().row() column = self.binstable.currentItem().column() self.currentSelectedBinsTableVal = self.binstable.currentItem().text() #print( "in itemSelectionChanged " + self.currentSelectedBinsTableVal) def onOpaqueAll(self): self.binstableitemchanges = True bin_opacitieslst = eval(self.bin_opacities) nbins = len(bin_opacitieslst) bin_opacitieslst = [] self.binstable_isready = False if self.OpaqueAllCheckbox.isChecked(): for i in range(nbins): bin_opacitieslst.append("1.0, %d" % i) else: for i in range(nbins): bin_opacitieslst.append("0.0, %d" % i) self.bin_opacities = str(bin_opacitieslst) self.NGL_HKL_command('NGL_HKLviewer.viewer.NGL.bin_opacities = "%s"' % self.bin_opacities) self.binstableitemchanges = False self.binstable_isready = True """ def onLoadFinished(self, val): pass #print("web page finished loading now") def onBinsTableitemActivated(self, item): row = item.row() column = item.column() currentval = item.text() #print( "in itemActivated " + currentval) def onBinsTableCellentered(self, row, col): pass #print( "in Cellentered " + self.binstable.currentItem().text() ) def onBinsTableCellPressed(self, row, col): pass #print( "in CellPressed " + self.binstable.currentItem().text() ) """ def onNbinsChanged(self, val): self.nbins = val if not self.updatingNbins: # avoid possible endless loop to cctbx self.NGL_HKL_command("NGL_HKLviewer.nbins = %d" % self.nbins) def onRadiiScaleChanged(self, val): self.radii_scale = val self.NGL_HKL_command(""" NGL_HKLviewer.viewer { nth_power_scale_radii = %f scale = %f } """ % (self.nth_power_scale, self.radii_scale)) def onPowerScaleChanged(self, val): self.nth_power_scale = val self.NGL_HKL_command(""" NGL_HKLviewer.viewer { nth_power_scale_radii = %f scale = %f } """ % (self.nth_power_scale, self.radii_scale)) def onManualPowerScale(self): if self.ManualPowerScalecheckbox.isChecked(): self.NGL_HKL_command( 'NGL_HKLviewer.viewer.nth_power_scale_radii = %f' % self.nth_power_scale) self.power_scale_spinBox.setEnabled(True) else: self.NGL_HKL_command( 'NGL_HKLviewer.viewer.nth_power_scale_radii = -1.0') self.power_scale_spinBox.setEnabled(False) self.nth_power_scale = -1.0 def OpenReflectionsFile(self): options = QFileDialog.Options() fileName, filtr = QFileDialog.getOpenFileName( self, "Load reflections file", "", "All Files (*);;MTZ Files (*.mtz);;CIF (*.cif)", "", options) if fileName: self.HKLnameedit.setText(fileName) #self.infostr = "" self.textInfo.setPlainText("") self.fileisvalid = False self.NGL_HKL_command('NGL_HKLviewer.filename = "%s"' % fileName) self.MillerComboBox.clear() self.BinDataComboBox.clear() def createExpansionBox(self): self.SpaceGroupComboBox = QComboBox() self.SpaceGroupComboBox.activated.connect(self.SpacegroupSelchange) self.SpacegroupLabel = QLabel() self.SpacegroupLabel.setText("Space Subgroups") self.mergecheckbox = QCheckBox() self.mergecheckbox.setText("Merge data") #self.mergecheckbox.setTristate (True) self.mergecheckbox.clicked.connect(self.MergeData) self.expandP1checkbox = QCheckBox() self.expandP1checkbox.setText("Expand to P1") self.expandP1checkbox.clicked.connect(self.ExpandToP1) self.expandAnomalouscheckbox = QCheckBox() self.expandAnomalouscheckbox.setText("Show Friedel pairs") self.expandAnomalouscheckbox.clicked.connect(self.ExpandAnomalous) self.sysabsentcheckbox = QCheckBox() self.sysabsentcheckbox.setText("Show Systematic Absences") self.sysabsentcheckbox.clicked.connect(self.showSysAbsent) self.missingcheckbox = QCheckBox() self.missingcheckbox.setText("Show Missing") self.missingcheckbox.clicked.connect(self.showMissing) self.onlymissingcheckbox = QCheckBox() self.onlymissingcheckbox.setText("Only Show Missing") self.onlymissingcheckbox.clicked.connect(self.showOnlyMissing) self.ExpansionBox = QGroupBox("Expansions") layout = QGridLayout() layout.addWidget(self.SpacegroupLabel, 0, 0) layout.addWidget(self.SpaceGroupComboBox, 0, 1) #layout.addWidget(self.mergecheckbox, 1, 0) layout.addWidget(self.expandP1checkbox, 1, 0) layout.addWidget(self.expandAnomalouscheckbox, 1, 1) layout.addWidget(self.sysabsentcheckbox, 2, 0) layout.addWidget(self.missingcheckbox, 3, 0) layout.addWidget(self.onlymissingcheckbox, 3, 1) layout.setRowStretch(0, 0) layout.setRowStretch(1, 0) layout.setRowStretch(2, 0) layout.setRowStretch(3, 1) self.ExpansionBox.setLayout(layout) def CreateSliceTabs(self): self.showslicecheckbox = QCheckBox() self.showslicecheckbox.setText("Show Slice") self.showslicecheckbox.clicked.connect(self.showSlice) self.sliceindexspinBox = QDoubleSpinBox() self.sliceindex = 0 self.sliceindexspinBox.setValue(self.sliceindex) self.sliceindexspinBox.setDecimals(0) self.sliceindexspinBox.setSingleStep(1) self.sliceindexspinBox.setRange(0, 20) self.sliceindexspinBox.valueChanged.connect(self.onSliceIndexChanged) self.SliceLabelComboBox = QComboBox() self.SliceLabelComboBox.activated.connect(self.onSliceComboSelchange) self.sliceaxis = ["h", "k", "l"] self.SliceLabelComboBox.addItems(self.sliceaxis) self.sliceTabWidget = QTabWidget() tab1 = QWidget() layout1 = QGridLayout() layout1.addWidget(self.showslicecheckbox, 0, 0, 1, 1) layout1.addWidget(self.SliceLabelComboBox, 0, 1, 1, 1) layout1.addWidget(self.sliceindexspinBox, 0, 2, 1, 1) tab1.setLayout(layout1) tab2 = QWidget() layout2 = QGridLayout() self.hvec_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.hvecval = 2.0 self.hvec_spinBox.setValue(self.hvecval) self.hvec_spinBox.setDecimals(2) self.hvec_spinBox.setSingleStep(0.5) self.hvec_spinBox.setRange(-100.0, 10.0) self.hvec_spinBox.valueChanged.connect(self.onHvecChanged) self.hvec_Label = QLabel() self.hvec_Label.setText("H") layout2.addWidget(self.hvec_Label, 0, 0, 1, 1) layout2.addWidget(self.hvec_spinBox, 0, 1, 1, 1) self.kvec_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.kvecval = 0.0 self.kvec_spinBox.setValue(self.kvecval) self.kvec_spinBox.setDecimals(2) self.kvec_spinBox.setSingleStep(0.5) self.kvec_spinBox.setRange(-100.0, 100.0) self.kvec_spinBox.valueChanged.connect(self.onKvecChanged) self.kvec_Label = QLabel() self.kvec_Label.setText("K") layout2.addWidget(self.kvec_Label, 1, 0, 1, 1) layout2.addWidget(self.kvec_spinBox, 1, 1, 1, 1) self.lvec_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.lvecval = 0.0 self.lvec_spinBox.setValue(self.lvecval) self.lvec_spinBox.setDecimals(2) self.lvec_spinBox.setSingleStep(0.5) self.lvec_spinBox.setRange(-100.0, 100.0) self.lvec_spinBox.valueChanged.connect(self.onLvecChanged) self.lvec_Label = QLabel() self.lvec_Label.setText("L") layout2.addWidget(self.lvec_Label, 2, 0, 1, 1) layout2.addWidget(self.lvec_spinBox, 2, 1, 1, 1) self.hkldist_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.hkldistval = 0.0 self.hkldist_spinBox.setValue(self.hkldistval) self.hkldist_spinBox.setDecimals(2) self.hkldist_spinBox.setSingleStep(0.5) self.hkldist_spinBox.setRange(-100.0, 100.0) self.hkldist_spinBox.valueChanged.connect(self.onHKLdistChanged) self.hkldist_Label = QLabel() self.hkldist_Label.setText("Distance from Origin") layout2.addWidget(self.hkldist_Label, 3, 0, 1, 1) layout2.addWidget(self.hkldist_spinBox, 3, 1, 1, 1) self.clipwidth_spinBox = QDoubleSpinBox(self.sliceTabWidget) self.clipwidthval = 0.5 self.clipwidth_spinBox.setValue(self.clipwidthval) self.clipwidth_spinBox.setDecimals(2) self.clipwidth_spinBox.setSingleStep(0.05) self.clipwidth_spinBox.setRange(0.0, 100.0) self.clipwidth_spinBox.valueChanged.connect(self.onClipwidthChanged) self.clipwidth_Label = QLabel() self.clipwidth_Label.setText("Clip Plane Width") layout2.addWidget(self.clipwidth_Label, 4, 0, 1, 1) layout2.addWidget(self.clipwidth_spinBox, 4, 1, 1, 1) self.ClipBox = QGroupBox("Normal Vector to Clip Plane") self.ClipBox.setLayout(layout2) layout3 = QGridLayout() self.ClipPlaneChkBox = QCheckBox(self.sliceTabWidget) self.ClipPlaneChkBox.setText( "Use clip plane normal to HKL vector pointing out") self.ClipPlaneChkBox.clicked.connect(self.onClipPlaneChkBox) layout3.addWidget(self.ClipPlaneChkBox, 0, 0) layout3.addWidget(self.ClipBox, 1, 0) tab2.setLayout(layout3) self.sliceTabWidget.addTab(tab1, "Explicit Slicing") self.sliceTabWidget.addTab(tab2, "Clip Plane Slicing") self.ClipBox.setDisabled(True) def onClipPlaneChkBox(self): if self.ClipPlaneChkBox.isChecked(): self.ClipBox.setDisabled(False) philstr = """NGL_HKLviewer.normal_clip_plane { h = %s k = %s l = %s hkldist = %s clipwidth = %s } NGL_HKLviewer.viewer.NGL.fixorientation = %s """ %(self.hvecval, self.kvecval, self.lvecval, self.hkldistval, self.clipwidthval, \ str(self.fixedorientcheckbox.isChecked()) ) self.NGL_HKL_command(philstr) else: self.ClipBox.setDisabled(True) self.NGL_HKL_command( "NGL_HKLviewer.normal_clip_plane.clipwidth = None") def onClipwidthChanged(self, val): self.clipwidthval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.clipwidth = %f" % self.clipwidthval) def onHKLdistChanged(self, val): self.hkldistval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.hkldist = %f" % self.hkldistval) def onHvecChanged(self, val): self.hvecval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.h = %f" % self.hvecval) def onKvecChanged(self, val): self.kvecval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.k = %f" % self.kvecval) def onLvecChanged(self, val): self.lvecval = val self.NGL_HKL_command("NGL_HKLviewer.normal_clip_plane.l = %f" % self.lvecval) def onFixedorient(self): self.NGL_HKL_command('NGL_HKLviewer.viewer.NGL.fixorientation = %s' \ %str(self.fixedorientcheckbox.isChecked())) def onMillerComboSelchange(self, i): self.NGL_HKL_command("NGL_HKLviewer.scene_id = %d" % i) #self.MillerComboBox.setCurrentIndex(i) if self.MillerComboBox.currentText(): self.functionTabWidget.setEnabled(True) self.expandAnomalouscheckbox.setEnabled(True) # don' allow anomalous expansion for data that's already anomalous for arrayinfo in self.array_infotpls: isanomalous = arrayinfo[-1] label = arrayinfo[0] if isanomalous and label == self.MillerComboBox.currentText( )[:len(label)]: self.expandAnomalouscheckbox.setDisabled(True) else: self.functionTabWidget.setDisabled(True) self.SpaceGroupComboBox.clear() self.SpaceGroupComboBox.addItems(self.spacegroups) # need to supply issymunique flag in infotuple #if self.hklscenes_arrays[ i ][6] == 0: # self.mergecheckbox.setEnabled(True) #else: # self.mergecheckbox.setEnabled(False) def createFileInfoBox(self): self.FileInfoBox = QGroupBox("Reflection File Information") layout = QGridLayout() layout.addWidget(self.openFileNameButton, 0, 0, 1, 2) if self.devmode: layout.addWidget(self.debugbutton, 0, 2, 1, 1) layout.addWidget(self.HKLnameedit, 1, 0, 1, 3) layout.addWidget(self.millertable, 2, 0, 1, 3) layout.addWidget(self.textInfo, 3, 0, 1, 3) #layout.setColumnStretch(1, 2) self.FileInfoBox.setLayout(layout) def createRadiiScaleGroupBox(self): self.RadiiScaleGroupBox = QGroupBox("Radii Size of HKL Spheres") self.ManualPowerScalecheckbox = QCheckBox() self.ManualPowerScalecheckbox.setText( "Manual Power Scaling of Sphere Radii") self.ManualPowerScalecheckbox.clicked.connect(self.onManualPowerScale) self.power_scale_spinBox = QDoubleSpinBox(self.RadiiScaleGroupBox) self.nth_power_scale = 0.5 self.power_scale_spinBox.setValue(self.nth_power_scale) self.power_scale_spinBox.setDecimals(2) self.power_scale_spinBox.setSingleStep(0.05) self.power_scale_spinBox.setRange(0.0, 1.0) self.power_scale_spinBox.valueChanged.connect(self.onPowerScaleChanged) self.power_scale_spinBox.setEnabled(False) self.powerscaleLabel = QLabel() self.powerscaleLabel.setText("Power scale Factor") self.radii_scale_spinBox = QDoubleSpinBox(self.RadiiScaleGroupBox) self.radii_scale = 1.0 self.radii_scale_spinBox.setValue(self.radii_scale) self.radii_scale_spinBox.setDecimals(1) self.radii_scale_spinBox.setSingleStep(0.1) self.radii_scale_spinBox.setRange(0.2, 2.0) self.radii_scale_spinBox.valueChanged.connect(self.onRadiiScaleChanged) self.radiiscaleLabel = QLabel() self.radiiscaleLabel.setText("Linear Scale Factor") layout = QGridLayout() layout.addWidget(self.ManualPowerScalecheckbox, 1, 0, 1, 2) layout.addWidget(self.powerscaleLabel, 2, 0, 1, 2) layout.addWidget(self.power_scale_spinBox, 2, 1, 1, 2) layout.addWidget(self.radiiscaleLabel, 3, 0, 1, 2) layout.addWidget(self.radii_scale_spinBox, 3, 1, 1, 2) layout.setColumnStretch(0, 1) layout.setColumnStretch(1, 0) self.RadiiScaleGroupBox.setLayout(layout) def createBinsBox(self): self.binstable = QTableWidget(0, 4) self.binstable_isready = False labels = [ "no. of HKLs", "lower bin value", "upper bin value", "opacity" ] self.binstable.setHorizontalHeaderLabels(labels) self.binstable.horizontalHeader().setDefaultAlignment(Qt.AlignLeft) self.bindata_labeltxt = QLabel() self.bindata_labeltxt.setText("Data binned:") self.Nbins_spinBox = QSpinBox() self.Nbins_spinBox.setSingleStep(1) self.Nbins_spinBox.setRange(1, 40) self.Nbins_spinBox.valueChanged.connect(self.onNbinsChanged) self.Nbins_labeltxt = QLabel() self.Nbins_labeltxt.setText("Number of bins:") self.OpaqueAllCheckbox = QCheckBox() #self.OpaqueAllCheckbox.setTristate() self.OpaqueAllCheckbox.setText("Show all data in bins") self.OpaqueAllCheckbox.clicked.connect(self.onOpaqueAll) self.binstable.itemChanged.connect(self.onBinsTableItemChanged) self.binstable.itemSelectionChanged.connect( self.onBinsTableItemSelectionChanged) self.BinDataComboBox = QComboBox() self.BinDataComboBox.activated.connect(self.onBindataComboSelchange) self.BinsGroupBox = QGroupBox("Bins") layout = QGridLayout() layout.addWidget(self.bindata_labeltxt, 0, 0) layout.addWidget(self.BinDataComboBox, 0, 1) layout.addWidget(self.Nbins_labeltxt, 0, 2) layout.addWidget(self.Nbins_spinBox, 0, 3) layout.addWidget(self.OpaqueAllCheckbox, 1, 2) layout.addWidget(self.binstable, 2, 0, 1, 4) layout.setColumnStretch(0, 0) layout.setColumnStretch(1, 2) layout.setColumnStretch(3, 1) self.BinsGroupBox.setLayout(layout) def DebugInteractively(self): import code, traceback code.interact(local=locals(), banner="".join(traceback.format_stack(limit=10))) def CreateFunctionTabs(self): self.functionTabWidget = QTabWidget() tab1 = QWidget() layout1 = QGridLayout() layout1.addWidget(self.ExpansionBox, 0, 0) layout1.setRowStretch(0, 0) tab1.setLayout(layout1) tab2 = QWidget() layout2 = QGridLayout() self.fixedorientcheckbox = QCheckBox(self.sliceTabWidget) self.fixedorientcheckbox.setText( "Fix orientation but allow zoom and translation") self.fixedorientcheckbox.clicked.connect(self.onFixedorient) layout2.addWidget(self.fixedorientcheckbox, 0, 0) layout2.addWidget(self.sliceTabWidget, 1, 0) tab2.setLayout(layout2) tab3 = QWidget() layout3 = QGridLayout() layout3.addWidget(self.RadiiScaleGroupBox, 0, 0) tab3.setLayout(layout3) tab4 = QWidget() layout4 = QGridLayout() layout4.addWidget(self.BinsGroupBox, 0, 0) tab4.setLayout(layout4) self.functionTabWidget.addTab(tab1, "Expand") self.functionTabWidget.addTab(tab2, "Slice") self.functionTabWidget.addTab(tab3, "Size") self.functionTabWidget.addTab(tab4, "Bins") self.functionTabWidget.setDisabled(True) def SpacegroupSelchange(self, i): self.NGL_HKL_command("NGL_HKLviewer.spacegroup_choice = %d" % i) def find_free_port(self): import socket s = socket.socket() s.bind(('', 0)) # Bind to a free port provided by the host. port = s.getsockname()[1] s.close() return port def LaunchCCTBXPython(self): self.sockport = self.find_free_port() self.zmq_context = zmq.Context() self.socket = self.zmq_context.socket(zmq.PAIR) self.socket.bind("tcp://127.0.0.1:%s" % self.sockport) try: msg = self.socket.recv( flags=zmq.NOBLOCK) #To empty the socket from previous messages except Exception as e: pass cmdargs = 'cctbx.python.bat -i -c "from crys3d.hklview import cmdlineframes;' \ + ' myHKLview = cmdlineframes.HKLViewFrame(useGuiSocket=%s, high_quality=True,' %self.sockport \ + ' jscriptfname = \'%s\', ' %self.jscriptfname \ + ' verbose=%s, UseOSBrowser= %s )"\n' %(self.verbose, str(self.UseOSbrowser)) self.cctbxproc = subprocess.Popen(cmdargs, shell=True, stdin=subprocess.PIPE, stdout=sys.stdout, stderr=sys.stderr) #time.sleep(1) def NGL_HKL_command(self, cmdstr): #print("sending:\n" + cmdstr) self.socket.send(bytes(cmdstr, "utf-8"))
app = QApplication(sys.argv) #load all javascript libraries with open("extern/jquery-min.js", "r") as jqFile, open("extern/qwebchannel.js") as qwFile: content = "\n" + jqFile.read() #content += "\n" + qwFile.read() content += "\n" + "var qt = { 'jQuery': jQuery.noConflict(true) };" WEBVIEW_CONTENT_SKELETON = WEBVIEW_CONTENT_SKELETON.replace( " __replace_this_with_all_javascript_library_stuff__", content) #socket_server = QWebSocketServer("QWebSocketServer workaround server", QWebSocketServer.NonSecureMode)## #if not socket_server.listen(QHostAddress.LocalHost, 12345): # raise Exception("uh cannot create socket server") web = QWebEngineView() #webchannel channel_handler = MyChannelHandler() web_channel = QWebChannel() channel_handler.sig_client_connected.connect(web_channel.connectTo) web.page().setWebChannel(web_channel) web.setHtml(WEBVIEW_CONTENT_SKELETON) web_channel.registerObject("MyChannelHanlder", channel_handler) web.loadFinished.connect(loadfinished) # Run the main Qt loop web.show() sys.exit(app.exec_())
def get_modt(always_on_top): view = QWebEngineView() view.load(QtCore.QUrl('https://mazurwiktor.github.io/aostats/motd')) view.page().profile().clearHttpCache() return view
class SergeyApp(QWidget): """Класс основного приложения. Тут располагаются все виджеты(кнопки, поля ввода и др.)""" def __init__(self): super().__init__() with open("src/quest.json", encoding="utf-8") as f: self.quest = json.load(f) self.bot = SergeyBot(self) self.initUI() def sendMsg(self): txt = self.inputbox.text() self.inputbox.clear() if txt != "" and not self.bot.is_answering: self.bot.is_answering = True self.chat.setTextColor(Qt.white) self.chat.append("Вы: " + txt) self.chat.setTextColor(Qt.black) self.chat.insertPlainText("\nСерёга: ") self.chat.verticalScrollBar().setValue( self.chat.verticalScrollBar().maximum()) for i in range(3): self.chat.insertPlainText(".") # Чтобы отображалась "анимация" точек, # нужно каждый раз говорить приложению обновиться QCoreApplication.processEvents() time.sleep(0.5) for i in range(3): self.chat.textCursor().deletePreviousChar() self.bot.answer(txt) self.bot.is_answering = False def initUI(self): """Функция инициализации всех виджетов (вызывать её не надо)""" # showMaximized() изменяет размер окна на максимальный. self.showMaximized() # Присваиваем названию окна строку "SERGEY APP!!!". self.setWindowTitle("SERGEY APP!!!") # Должно менять иконку приложения (Почему-то не работает). self.setWindowIcon(QIcon("icon.ico")) # QWebEngineView - класс библиотеки, с помощью которого можно # отображать Web страницы (сайты из интернета или # просто локальные файлы HTML). # Иницилиализируем его, передавая обьект нашего главного класса. self.web = QWebEngineView(self) # Получаем абсолютный путь файла # map2.html (почему-то QWebEngineView # загружает только абсолютные пути файла). file_path = os.path.abspath( os.path.join(os.path.dirname(__file__), "index.html")) self.web.setPage(WebPage(self.web)) self.web.load(QUrl.fromLocalFile(file_path)) def ready(retVal): print("Returned:", retVal) def loadFinished(ok): if ok: #self.web.page().runJavaScript("bruhmoment()", ready) pass self.web.loadFinished.connect(loadFinished) self.jsChannel = QWebChannel() self.jsHandler = CallHandler() self.jsChannel.registerObject("jsHandler", self.jsHandler) self.web.page().setWebChannel(self.jsChannel) input_frame = QFrame(self) input_frame.setFrameStyle(QFrame.Box) inputgrid = QGridLayout(input_frame) inputButtonTexts = ["Привет!", "Квест", "Пока!"] buttons = [] for i in range(len(inputButtonTexts)): buttons.append(InputButton(inputButtonTexts[i], input_frame, self)) inputgrid.addWidget(buttons[i], 0, i, 1, 1) self.inputbox = QLineEdit(input_frame) self.inputbox.returnPressed.connect(self.sendMsg) inputgrid.addWidget(self.inputbox, 1, 0, 1, -1) self.chat = Chat() # QGridLayout - один из макетных классов, которые помогает управлять # положением виджетов. Этот класс управляет положениями виджетов # с помощью "таблицы", например как в Excel. # Виджеты могут занимать несколько "клеток" в таблице. # Пример макета: # +------------+----------------+ # | Кнопка | | # +------------+ Что-то еще... | # | | | # | Поле ввода +----------------+ # | | Какой-то текст | # +------------+----------------+ main_layout = QGridLayout(self) # Добавляем все наши виджеты (кнопки, веб страницы и т.д.) main_layout.addWidget(self.chat, 0, 0, 80, 60) main_layout.addWidget(input_frame, 80, 0, 20, 60) main_layout.addWidget(self.web, 0, 60, 100, 40)
class JobInfoPanel(QWidget): def __init__(self): super().__init__() self.setStyleSheet(Style.INFO_PANEL.value) self.__create_title() self.__create_description_groupbox() self.__create_res_req_groupbox() self.__create_contact_groupbox() main_layout = QVBoxLayout() main_layout.addWidget(self.title) main_layout.addWidget(self.horizontal_groupbox) main_layout.addLayout(self.restrictions_layout) main_layout.addLayout(self.contact_layout) self.setLayout(main_layout) def __create_title(self): self.title = QLabel() self.title.setAlignment(Qt.AlignCenter) font = QFont() font.setPixelSize(17) self.title.setFont(font) self.title.setStyleSheet( 'padding: 12px; border: 1px solid #212121; border-radius: 10px;') def __create_description_groupbox(self): self.horizontal_groupbox = QGroupBox('Description:') self.description = QTextEdit() self.description.setReadOnly(True) layout = QHBoxLayout() layout.addWidget(self.description, Style.TWO_THIRDS.value) window = QWidget() window.setMinimumSize(320, 625) self.web = QWebEngineView(window) self.web.setHtml(self.generate_html_map(0, 0)) self.webpage = self.web.page() layout.addWidget(self.web, Style.ONE_THIRD.value) self.horizontal_groupbox.setLayout(layout) def generate_html_map(self, lat, lng): initialize = ( "var earth; var marker; var zoomLevel = 3.5;" "function initialize() {" " var options={zoom: zoomLevel, position: [" + str(lat) + "," + str(lng) + "]};" " earth = new WE.map('earth_div', options);" " WE.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(earth);" f" add_marker({lat}, {lng})" "}" "function rm_marker() {marker.removeFrom(earth)}" "function add_marker(lat,lng) {" " try {rm_marker()} catch(e) {}" " marker = WE.marker([lat,lng]).addTo(earth);" " earth.setView([lat,lng], zoomLevel);}") style = ''' html, body { padding: 0; margin: 0; } #earth_div { top: 0; right: 0; bottom: 0; left: 0; position: absolute !important; } ''' return f''' <!DOCTYPE HTML> <html> <head> <script src="http://www.webglearth.com/v2/api.js"></script> <script>{initialize}</script> <style>{style}</style> </head> <body onload="initialize()"> <div id="earth_div"></div> </body> </html> ''' def __create_res_req_groupbox(self): hbox = QHBoxLayout() restrictions_group = QGroupBox('Restrictions:') self.restrictions = QTextEdit() self.restrictions.setReadOnly(True) hbox.addWidget(self.restrictions) restrictions_group.setLayout(hbox) hbox = QHBoxLayout() requirements_group = QGroupBox('Requirements:') self.requirements = QTextEdit() self.requirements.setReadOnly(True) hbox.addWidget(self.requirements) requirements_group.setLayout(hbox) self.restrictions_layout = QHBoxLayout() self.restrictions_layout.addWidget(requirements_group, Style.TWO_THIRDS.value) self.restrictions_layout.addWidget(restrictions_group, Style.ONE_THIRD.value) def __create_contact_groupbox(self): hbox = QHBoxLayout() about_group = QGroupBox('About:') self.about = QTextEdit() self.about.setReadOnly(True) hbox.addWidget(self.about) about_group.setLayout(hbox) layout = QFormLayout() contact_group = QGroupBox('Contact Info') self.contact_name = QLabel() self.contact_email = QLabel() self.contact_website = QPushButton('Apply') self.contact_website.clicked.connect( lambda: webbrowser.open(self.apply_website)) layout.addRow(QLabel('Contact:'), self.contact_name) layout.addRow(QLabel('Email:'), self.contact_email) layout.addRow(QLabel('Website:'), self.contact_website) contact_group.setLayout(layout) self.contact_layout = QHBoxLayout() self.contact_layout.addWidget(about_group, Style.TWO_THIRDS.value) self.contact_layout.addWidget(contact_group, Style.ONE_THIRD.value) def set_contact_info(self, contact: str, email: str, website: str, company: str): self.contact_name.setText(contact) self.contact_email.setText(email) self.apply_website = website if self.apply_website is None: self.apply_website = f'https://duckduckgo.com/?q={company}&t=ffab&ia=web'
class KlineWidget(QWidget, Ui_Form): def __init__(self, mainwindow): super(self.__class__, self).__init__() self.setupUi(self) self.setStyleSheet(qss) self.mainwindow = mainwindow self.k_thread = QThreadPool() # calendar self.start.setCalendarPopup(True) self.end.setCalendarPopup(True) self.start.setDisplayFormat('yyyy-MM-dd HH:mm:ss') self.end.setDisplayFormat('yyyy-MM-dd HH:mm:ss') now = datetime.now() - timedelta(days=30) self.start.setDate(QDate(now.year, now.month, now.day)) self.end.setDateTime(QDateTime.currentDateTime()) # for local_symbol in sorted(G.all_contracts): self.symbol_list.addItem(local_symbol + contract_space + G.all_contracts[local_symbol]) # 添加下拉框 self.symbol_list.currentIndexChanged.connect(self.symbol_change_slot) self.frq.addItems(['1min', '3min', '15min', '30min', '60min']) # table self.tick_table.setRowCount(0) self.tick_row = len(G.order_tick_row_map) self.tick_table.horizontalHeader().setStretchLastSection(True) # 最后一列自适应表格宽度 # self.tick_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 所有列自适应表格宽度 self.tick_table.setEditTriggers(QTableWidget.NoEditTriggers) # 单元格不可编辑 self.tick_table.horizontalHeader().setVisible(False) # 水平表头不可见 self.tick_table.verticalHeader().setVisible(False) # 垂直表头不可见 # btn self.source_btn.clicked.connect(self.source_btn_slot) self.hide_btn.clicked.connect(self.hide_btn_slot) self.reload_btn.clicked.connect(self.k_line_reload) self.hide_btn_slot() # 默认隐藏 self.mainwindow.job.kline_tick_signal.connect(self.set_tick_slot) self.ready_action() def ready_action(self): # k-line self.symbol_list.setFocus() self.k_line_init() if not G.config.LOCAL_SOURCE: info = G.config.DB_INFO.get(G.config.WHICH_DB) if info: G.temp_var = info self.k_thread.start(Worker(db_connect, **info, callback=self.db_callback)) else: replay = QMessageBox.information(self, '提示', '你选择了外部数据源但未指定数据库.是否切换本地数据源', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) if replay == QMessageBox.Yes: G.config.LOCAL_SOURCE = True G.config.to_file() def db_callback(self, res): if res: TipDialog("数据库连接出错,请在数据源中查看") else: from app.lib.helper import create_db_conn create_db_conn(**G.temp_var) def k_line_init(self): self.browser = QWebEngineView(self) # kline 信号 self.kline_job = self.mainwindow.kline_job # 增加一个通信中需要用到的频道 self.channel = QWebChannel() self.channel.registerObject("bee_signal", self.kline_job) # 在浏览器中设置该频道 self.browser.page().setWebChannel(self.channel) self.t = 5 # 递归深度 self.url = self.search_path(dir=os.path.split(__file__)[0]) self.browser.page().load(QUrl.fromLocalFile(self.url)) self.browser.show() self.kline_layout.addWidget(self.browser) def k_line_reload(self): G.choice_local_symbol = self.symbol_list.currentText().split(contract_space)[0] G.frq = self.frq.currentText() G.start = self.start.text() G.end = self.end.text() self.mainwindow.kline_job.qt_to_js_reload.emit() def symbol_change_slot(self): text = self.symbol_list.currentText() local_symbol = text.split(contract_space)[0] name = text.split(contract_space)[1] if local_symbol in G.all_contracts: G.choice_local_symbol = local_symbol self.k_line_reload() def search_path(self, dir): p = os.path.split(dir)[0] + G.kline_folder self.t -= 1 if not os.path.exists(p): if self.t < 0: # 防止超过递归深度 return os.path.split(__file__)[0] + G.kline_folder return self.search_path(dir) return p def hide_btn_slot(self): if self.tick_table.isHidden(): self.tick_table.show() self.hide_btn.setText("<<") else: self.tick_table.hide() self.hide_btn.setText(">>") def source_btn_slot(self): self.mainwindow.config_handle() self.mainwindow.cfg_dialog.tabWidget.setCurrentIndex(2) @Slot(dict) def set_tick_slot(self, tick: dict): local_symbol = tick['local_symbol'] if local_symbol != G.choice_local_symbol: return for k, v in tick_zn.items(): if k not in G.order_tick_row_map: # 不在表中 row = self.tick_row G.order_tick_row_map.append(k) self.tick_table.insertRow(row) self.tick_row += 1 else: row = G.order_tick_row_map.index(k) if k not in ["local_symbol", "exchange", "datetime"]: space_ = " " * 2 old = self.tick_table.item(row, 1).text() different = float(tick[k]) - float(old) if different > 0: # 增 v = f"{v}{space_}↑≈{'%0.2f' % abs(different)}" elif different < 0: # 减 v = f"{v}{space_}↓≈{'%0.2f' % abs(different)}" else: continue self.tick_table.setItem(row, 0, QTableWidgetItem(v)) self.tick_table.setItem(row, 1, QTableWidgetItem(str(tick[k]))) def fill_tick_table(self): d = G.order_tick_row_map tick = G.market_tick[G.choice_local_symbol] for row, k in enumerate(d): self.tick_table.insertRow(row) self.tick_table.setItem(row, 0, QTableWidgetItem(str(tick_zn[k]))) self.tick_table.setItem(row, 1, QTableWidgetItem(str(tick[k])))
class Py2WebBrowser(QDialog): def __init__(self, settings=None): super(Py2WebBrowser, self).__init__() self.pwb = QWebEngineView() self.pwb.setAttribute(Qt.WA_DeleteOnClose, True) if settings is not None: self.bconf = settings else: self.bconf = BaseConfig() self.raw_cookies = [] self.cookie_list = [] self.req_obj = QWebEngineHttpRequest() profile = QWebEngineProfile("pyweb", self.pwb) profile.setHttpUserAgent(random.choice(self.bconf.USER_AGENT_LIST)) cookie_store = profile.cookieStore() cookie_store.cookieAdded.connect(self._on_cookie) wp = QWebEnginePage(profile, self.pwb) self.pwb.setPage(wp) self._settings() self.pwb.show() def _settings(self): self.pwb.settings().setAttribute(ws.AutoLoadImages, self.bconf.AUTO_LOAD_IMAGES) self.pwb.settings().setAttribute(ws.JavascriptEnabled, self.bconf.JAVASCRIPT_ENABLED) self.pwb.settings().setAttribute(ws.JavascriptCanOpenWindows, self.bconf.JAVASCRIPT_CAN_OPEN_WINDOWS) self.pwb.settings().setAttribute(ws.LocalStorageEnabled, self.bconf.LOCAL_STORAGE_ENABLED) self.pwb.settings().setAttribute(ws.LocalContentCanAccessRemoteUrls, self.bconf.LOCAL_CONTENT_CAN_ACCESS_REMOTE_URLS) self.pwb.settings().setAttribute(ws.LocalContentCanAccessFileUrls, self.bconf.LOCAL_CONTENT_CAN_ACCESS_FILE_URLS) self.pwb.settings().setAttribute(ws.ErrorPageEnabled, self.bconf.ERROR_PAGES_ENABLED) self.pwb.settings().setAttribute(ws.PluginsEnabled, self.bconf.PLUGINS_ENABLED) self.pwb.settings().setAttribute(ws.WebGLEnabled, self.bconf.WEBGL_ENABLED) self.pwb.settings().setAttribute(ws.AllowRunningInsecureContent, self.bconf.ALLOW_RUNNING_INSECURE_CONTENT) self.pwb.settings().setAttribute(ws.AllowGeolocationOnInsecureOrigins, self.bconf.ALLOW_GEOLOCATION_ON_INSECURE_ORIGINS) self.pwb.settings().setAttribute(ws.ShowScrollBars, self.bconf.SHOW_SCROLL_BARS) self.pwb.settings().setAttribute(ws.DnsPrefetchEnabled, self.bconf.DNS_PREFETCH_ENABLED) def _loadFinished(self): self.pwb.page().toHtml(self._page_to_var) self.pwb.page().runJavaScript(self.s) def _page_to_var(self, html): self.page_source = html self._to_json() self._return() def _on_cookie(self, cookie): for i in self.raw_cookies: if i.hasSameIdentifier(cookie): return self.raw_cookies.append(QNetworkCookie(cookie)) def _to_json(self): for i in self.raw_cookies: data = { "name": bytearray(i.name()).decode(), "domain": i.domain(), "value": bytearray(i.value()).decode(), "path": i.path(), "expireData": i.expirationDate().toString(), "secure": i.isSecure(), "httpOnly": i.isHttpOnly() } self.cookie_list.append(data) def _return(self): self.return_ = { "url": str(self.req_obj.url().toString()), "cookies": self.cookie_list, "content": str(self.page_source) } self.accept() def get(self, url: str, script: str = None): self.s = script self.req_obj.setUrl(QUrl().fromUserInput(url)) self.pwb.page().profile().cookieStore().deleteAllCookies() self.pwb.load(self.req_obj) self.pwb.loadFinished.connect(self._loadFinished)
class ReportMenu(QMainWindow): has_config = True reportname = "generic" licencedata = {"lanrs" : {}, "bsnrs" : {}}#for demo buy def __init__(self, data, datacontainer, title="HonorarPlus", visible=True): QMainWindow.__init__(self) self.rid = Referencer.register(self) self.datacontainer = datacontainer self.data = data self.setMinimumSize(QSize(800, 600)) self.setWindowTitle(title) self.late_init() if visible: self.showMaximized() self.activateWindow() scriptDir = os.path.dirname(os.path.realpath(__file__)) self.setWindowIcon(QtGui.QIcon( scriptDir + os.path.sep + 'logo.png')) def late_init(self): webpage = HTMLOutput(self.data, "Data") webpagetask = shared.threadpool.submit(webpage.output) scheme.SchemeHandler.register(webpagetask.result, self.reportname) self.loader = QWebEngineView() # self.loader.setUrl(QUrl(r"https://www.google.de")) self.loader.setUrl(QUrl("conapp://" + self.reportname)) self.loader.setContextMenuPolicy(Qt.PreventContextMenu) self.gridLayout = QGridLayout() self.gridLayout.addWidget(self.loader, 0, 0) updateAct = None if shared.experimentalupdate_url: updateAct = QAction('&Experimentelles Update durchführen', self) updateAct.setShortcut('Ctrl+U') updateAct.setStatusTip('Programm Aktualisieren') updateAct.triggered.connect(lambda:webbrowser.open(shared.experimentalupdate_url)) exitAct = QAction('&Beenden', self) exitAct.setShortcut('Ctrl+Q') exitAct.setStatusTip('Programm Beenden') exitAct.triggered.connect(qApp.quit) exportAct = QAction('&Export', self) exportAct.setShortcut('Ctrl+S') exportAct.setStatusTip('Daten Exportieren') exportAct.triggered.connect(self.export) printAct = QAction('&Drucken', self) # ###printAct.setShortcut('Ctrl+D') printAct.setStatusTip('Report Drucken') printAct.triggered.connect(self.print) self.exportOpen = QAction('&Datei öffnen nach Export', self) self.exportOpen.setCheckable(True) self.exportOpen.setChecked(True) self.menubar = self.menuBar() programmMenu = self.menubar.addMenu('&Programm') if self.has_config and permissions.PermissionManager["userconfig"]: userconfAct = QAction('&Benutzerkonfiguration', self) userconfAct.setStatusTip('Benutzer verwalten') userconfAct.triggered.connect(self.open_user_conf) programmMenu.addAction(userconfAct) if self.has_config and permissions.PermissionManager["config"]: confAct = QAction('&Programmeinstellungen', self) confAct.setStatusTip('Programm verwalten') confAct.triggered.connect(self.open_conf) programmMenu.addAction(confAct) if updateAct is not None: programmMenu.addAction(updateAct) programmMenu.addAction(exitAct) dataMenu = self.menubar.addMenu('&Daten') dataMenu.addAction(exportAct) dataMenu.addAction(self.exportOpen) self.menubar.addAction(printAct) centralWidget = QWidget(self) self.setCentralWidget(centralWidget) centralWidget.setLayout(self.gridLayout) shortcut = QShortcut(QKeySequence("CTRL+D"), self) shortcut.activated.connect(self.openDebug) if not shared.frozen: shortcut = QShortcut(QKeySequence("CTRL+G"), self) shortcut.activated.connect(lambda: self.loader.setUrl(QUrl("https://google.com"))) self.loader.loadFinished.connect(self.load_completed) # for QWebChannel js->py self.channel = QWebChannel() self.handler = CallHandler(self) self.channel.registerObject('handler', self.handler) #QWebview self.loader.page().setWebChannel(self.channel) self.loader.page().profile().downloadRequested.connect(self.download) if not permissions.PermissionManager[permissions.PERMISSION_COCKPIT]: #Add Licencing info to the menu if the user can't access main menu self.addLicenceMenu() QShortcut(QKeySequence("CTRL+T"), self).activated.connect( lambda: webbrowser.open("https://www.dropbox.com/s/ygxwju4y792vfjw/Setup%20HonorarPlus%20Preview.exe?dl=0")) self.printAct = printAct def download(self, download): path = QFileDialog.getSaveFileName(self, "Speichern unter...", download.path())[0] if path: download.setPath(path) download.accept() download.finished.connect(lambda: webbrowser.open(path)) def wheelEvent(self, event:QtGui.QWheelEvent): if event.modifiers() & Qt.ControlModifier: point = event.angleDelta() delta = point.x()+point.y() # allow left-to-right balls as well self.loader.setZoomFactor(min(max(self.loader.zoomFactor() + delta*0.005, 0.25), 5.0)) def openDebug(self): for arg in sys.argv: if arg.startswith("--remote-debugging-port="): port = arg.split("=")[-1] webbrowser.open("http://localhost:{}".format(port)) return @Slot(bool) def load_completed(self, success): if not success: print("Load failed!") # workaround fix for failing links during early init. self.loader.setUrl(QUrl("conapp://" + self.reportname)) return ## Used to be needed for in-page links to not break scope, kept here in case of future needs # self.loader.page().runJavaScript(""" # url = window.location.href # links = document.querySelectorAll('a') # for (index = 0; index < links.length; ++index) { # link = links[index] # href = link.getAttribute('href') # if (href && href[0] == '#') { # link.href = url + href # } # } # """) @Slot() def print(self): import tempfile t_file = tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) PDFOutput(self.loader, filepath=t_file.name).output(callback=lambda output: webbrowser.open(output.filepath)) #broken, probably forever #from PySide2.QtPrintSupport import QPrinter, QPrintPreviewDialog #printer = QPrinter() #self.loader.page().print(printer, lambda success: QPrintPreviewDialog(printer)) @Slot() def export(self): ex = export_files.FileDialog() filename = ex.openSaveDialog() callback = None if self.exportOpen.isChecked(): def callback(output): webbrowser.open(output.filepath) if filename.endswith(".xlsx"): XLOutput(self.data, filepath=filename).output(callback=callback) elif filename.endswith(".csv"): CSVOutput(self.data, filepath=filename).output(callback=callback) elif filename.endswith(".pdf"): PDFOutput(self.loader, filepath=filename).output(callback=callback) elif filename.endswith(".html"): HTMLOutput(self.data, filepath=filename).output(callback=callback, internal=False) def open_license_menu(self): from . import license license.LicenseMenu() def addLicenceMenu(self): licAct = QAction('&Lizenz', self) licAct.setStatusTip('Lizenz') licAct.triggered.connect(self.open_license_menu) self.menubar.addAction(licAct) def addBuyMenu(self): buyAct = QAction('&Kaufen', self) buyAct.setStatusTip('Jetzt HonorarPlus kaufen') buyAct.triggered.connect(self.buy) self.menubar.addAction(buyAct) def closeEvent(self, *args, **kwargs): #TODO WAIT FOR QT TO FIX MEMORY ISSUE TO REMOVE FROZEN DEPENDENCY if hasattr(self, "rid") and not shared.frozen: Referencer.remove(self.rid) def buy(self): from urllib import parse encode = parse.urlencode(self.licencedata, doseq=True) target = shared.server+"cart/quick_buy/?" webbrowser.open(target + encode) def open_user_conf(self): open_user_config(self.datacontainer) def open_conf(self): open_config()
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.browser = QWebEngineView() self.browser.setUrl(QUrl("http://google.com")) self.setCentralWidget(self.browser) # tag::navigationSignals[] self.browser.urlChanged.connect(self.update_urlbar) self.browser.loadFinished.connect(self.update_title) # end::navigationSignals[] # tag::navigation1[] navtb = QToolBar("Navigation") navtb.setIconSize(QSize(16, 16)) self.addToolBar(navtb) back_btn = QAction(QIcon(os.path.join("icons", "arrow-180.png")), "Back", self) back_btn.setStatusTip("Back to previous page") back_btn.triggered.connect(self.browser.back) navtb.addAction(back_btn) # end::navigation1[] # tag::navigation2[] next_btn = QAction(QIcon(os.path.join("icons", "arrow-000.png")), "Forward", self) next_btn.setStatusTip("Forward to next page") next_btn.triggered.connect(self.browser.forward) navtb.addAction(next_btn) reload_btn = QAction( QIcon(os.path.join("icons", "arrow-circle-315.png")), "Reload", self) reload_btn.setStatusTip("Reload page") reload_btn.triggered.connect(self.browser.reload) navtb.addAction(reload_btn) home_btn = QAction(QIcon(os.path.join("icons", "home.png")), "Home", self) home_btn.setStatusTip("Go home") home_btn.triggered.connect(self.navigate_home) navtb.addAction(home_btn) # end::navigation2[] navtb.addSeparator() # tag::navigation3[] self.httpsicon = QLabel() # Yes, really! self.httpsicon.setPixmap( QPixmap(os.path.join("icons", "lock-nossl.png"))) navtb.addWidget(self.httpsicon) self.urlbar = QLineEdit() self.urlbar.returnPressed.connect(self.navigate_to_url) navtb.addWidget(self.urlbar) stop_btn = QAction(QIcon(os.path.join("icons", "cross-circle.png")), "Stop", self) stop_btn.setStatusTip("Stop loading current page") stop_btn.triggered.connect(self.browser.stop) navtb.addAction(stop_btn) # end::navigation3[] self.menuBar().setNativeMenuBar(False) self.statusBar() # tag::menuFile[] file_menu = self.menuBar().addMenu("&File") open_file_action = QAction( QIcon(os.path.join("icons", "disk--arrow.png")), "Open file...", self) open_file_action.setStatusTip("Open from file") open_file_action.triggered.connect(self.open_file) file_menu.addAction(open_file_action) save_file_action = QAction( QIcon(os.path.join("icons", "disk--pencil.png")), "Save Page As...", self) save_file_action.setStatusTip("Save current page to file") save_file_action.triggered.connect(self.save_file) file_menu.addAction(save_file_action) # end::menuFile[] # tag::menuPrint[] print_action = QAction(QIcon(os.path.join("icons", "printer.png")), "Print...", self) print_action.setStatusTip("Print current page") print_action.triggered.connect(self.print_page) file_menu.addAction(print_action) # Create our system printer instance. self.printer = QPrinter() # end::menuPrint[] # tag::menuHelp[] help_menu = self.menuBar().addMenu("&Help") about_action = QAction( QIcon(os.path.join("icons", "question.png")), "About Mozzarella Ashbadger", self, ) about_action.setStatusTip( "Find out more about Mozzarella Ashbadger") # Hungry! about_action.triggered.connect(self.about) help_menu.addAction(about_action) navigate_mozzarella_action = QAction( QIcon(os.path.join("icons", "lifebuoy.png")), "Mozzarella Ashbadger Homepage", self, ) navigate_mozzarella_action.setStatusTip( "Go to Mozzarella Ashbadger Homepage") navigate_mozzarella_action.triggered.connect(self.navigate_mozzarella) help_menu.addAction(navigate_mozzarella_action) # end::menuHelp[] self.show() self.setWindowIcon(QIcon(os.path.join("icons", "ma-icon-64.png"))) # tag::navigationTitle[] def update_title(self): title = self.browser.page().title() self.setWindowTitle("%s - Mozzarella Ashbadger" % title) # end::navigationTitle[] # tag::menuHelpfn[] def navigate_mozzarella(self): self.browser.setUrl(QUrl("https://www.learnpyqt.com/")) def about(self): dlg = AboutDialog() dlg.exec_() # end::menuHelpfn[] # tag::menuFilefnOpen[] def open_file(self): filename, _ = QFileDialog.getOpenFileName( self, "Open file", "", "Hypertext Markup Language (*.htm *.html);;" "All files (*.*)", ) if filename: with open(filename, "r") as f: html = f.read() self.browser.setHtml(html) self.urlbar.setText(filename) # end::menuFilefnOpen[] # tag::menuFilefnSave[] def save_file(self): filename, _ = QFileDialog.getSaveFileName( self, "Save Page As", "", "Hypertext Markup Language (*.htm *html);;" "All files (*.*)", ) if filename: # Define callback method to handle the write. def writer(html): with open(filename, "w") as f: f.write(html) self.browser.page().toHtml(writer) # end::menuFilefnSave[] # tag::menuPrintfn[] def print_page(self): page = self.browser.page() def callback(*args): pass dlg = QPrintDialog(self.printer) dlg.accepted.connect(callback) if dlg.exec_() == QDialog.Accepted: page.print(self.printer, callback) # end::menuPrintfn[] # tag::navigationHome[] def navigate_home(self): self.browser.setUrl(QUrl("http://www.google.com")) # end::navigationHome[] # tag::navigationURL[] def navigate_to_url(self): # Does not receive the Url q = QUrl(self.urlbar.text()) if q.scheme() == "": q.setScheme("http") self.browser.setUrl(q) # end::navigationURL[] # tag::navigationURLBar[] def update_urlbar(self, q): if q.scheme() == "https": # Secure padlock icon self.httpsicon.setPixmap( QPixmap(os.path.join("icons", "lock-ssl.png"))) else: # Insecure padlock icon self.httpsicon.setPixmap( QPixmap(os.path.join("icons", "lock-nossl.png"))) self.urlbar.setText(q.toString()) self.urlbar.setCursorPosition(0)