コード例 #1
0
ファイル: main.py プロジェクト: DroidCatRu/Ciaod_Practice4
class MainWindow(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.title = 'Flightradar24 parser by DroidCatRu'
        self.setWindowTitle(self.title)
        self.resize(700, 500)
        self.view = QWebEngineView(self)
        self.setpage()

        self.textbox = QLineEdit(self)
        self.textbox.move(20, 10)
        self.textbox.resize(280, 20)

        btn = QPushButton('Показать рейс', self)
        btn.resize(btn.sizeHint())
        btn.move(300, 10)

        grid = QGridLayout()
        grid.addWidget(self.view)
        self.setLayout(grid)
        btn.clicked.connect(self.clikbtn)  # Кнопка обновления карты
        self.show()

    def setpage(self, id=airplane_id):
        mypage = MyPage(self.view)
        self.view.setPage(mypage)
        s = getmaphtml(id)
        mypage.setHtml(s)

    def clikbtn(self):
        QMessageBox.question(self, 'Не увлекайтесь', "Стоимость одной загрузки карты: 0,46 рубля. Студенты тоже есть хотят. +79093636316 (сбер)", QMessageBox.Ok, QMessageBox.Ok)
        id = self.textbox.text()
        self.setpage(id)
        self.view.reload()
コード例 #2
0
class MainWindow(QMainWindow):
    """Main window for the GUI - displays flask webpage"""

    # constructor
    def __init__(self, port):
        # call parent constructor
        # hide window border
        super().__init__(flags=Qt.FramelessWindowHint)
        # window name
        self.setWindowTitle("Flask hook")

        # create view for web page
        self.web_engine_view = QWebEngineView()
        # load flask page
        self.web_engine_view.setUrl(QUrl("http://127.0.0.1:{}".format(port)))
        # update view
        self.web_engine_view.reload()

        # create main layout
        self.main_layout = QVBoxLayout()
        # add web view to layout
        self.main_layout.addWidget(self.web_engine_view)
        # self.main_layout.setContentsMargins(5, 40, 5, 5)
        # clear margins
        self.main_layout.setContentsMargins(0, 0, 0, 0)

        # create main widget
        self.central_widget = QWidget()
        # apply layout to main widget
        self.central_widget.setLayout(self.main_layout)

        # apply main widget to window
        self.setCentralWidget(self.central_widget)
コード例 #3
0
class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('Folium in PyQt Example')
        self.window_width, self.window_height = 480, 480
        self.setMinimumSize(self.window_width, self.window_height)

        layout = QVBoxLayout()
        self.setLayout(layout)

        self.x = 37.40494
        self.y = 127.11130
        m = folium.Map(
        	# tiles='Stamen Terrain',
        	zoom_start=18,
        	location=(self.x, self.y)
        )

        # save map data to data object
        self.data = io.BytesIO()
        m.save(self.data, close_file=False)
        m.save("map.html")

        self.webView = QWebEngineView()
        filepath = os.path.abspath(os.path.join(os.path.dirname(__file__), "map.html"))
        self.webView.load(QUrl.fromLocalFile(filepath))
        layout.addWidget(self.webView)
    
    def keyPressEvent(self, e):        
        if e.key() == Qt.Key_Right:
            self.x, self.y = self.x, self.y+0.0005

        elif e.key() == Qt.Key_Left:
            self.x, self.y = self.x, self.y-0.0005

        elif e.key() == Qt.Key_Up:
            self.x, self.y = self.x+0.0005, self.y

        elif e.key() == Qt.Key_Down:
            self.x, self.y = self.x-0.0005, self.y

        m = folium.Map(zoom_start=18,location=(self.x, self.y))
        m.save(self.data, close_file=False)
        m.save("map.html")
        self.webView.reload()
コード例 #4
0
class TkPyHelpWidget(QDialog):
    url = f'http://localhost:{port}/'
    title: str = 'TkPy3 帮助'

    def __init__(self, parent=None):
        super(TkPyHelpWidget, self).__init__(parent)
        self.vboxlayout = QVBoxLayout()
        self.resize(1000, 500)
        self.setWindowTitle(self.title)
        self.view = QWebEngineView()
        self.reset_to_home = QPushButton('回到主页')
        self.setLayout(self.vboxlayout)
        self.go_home()
        self.vboxlayout.addWidget(self.reset_to_home, 0)
        self.vboxlayout.addWidget(self.view, 1)
        self.reset_to_home.setWhatsThis('回到主页')
        self.reset_to_home.setToolTip(self.url)

    def go_home(self):
        self.view.load(QUrl(self.url))
        self.view.reload()
コード例 #5
0
class App(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("change map")
        self.disply_width = 640
        self.display_height = 480
        self.browser = QWebEngineView()
        self.show_location(0,0)
        current_dir = os.path.dirname(os.path.abspath(__file__))
        filename = os.path.join(current_dir, 'show_city.html')
        url = QUrl.fromLocalFile(filename)
        self.browser.setUrl(url)
        vbox = QVBoxLayout()
        vbox.addWidget(self.browser)
        self.setLayout(vbox)

        self.thread = VocalThread()
        self.thread.get_vocal_message.connect(self.search_location)
        self.thread.start()

    @pyqtSlot(str)
    def search_location(self, text):
        result = requests.get("http://www.mapquestapi.com/geocoding/v1/address?key=your-key&location="+text)
        print(text)
        result_text = result.text
        lat = float(re.findall(r'(?<="lat")(?:\s*\:\s*)(.{0,23}?(?=,))', result_text, re.IGNORECASE+re.DOTALL)[0])
        lng = float(re.findall(r'(?<="lng")(?:\s*\:\s*)(.{0,23}?(?=}))', result_text, re.IGNORECASE+re.DOTALL)[0])
        statuscode = int(re.findall(r'(?<="statuscode")(?:\s*\:\s*)(.{0,23}?(?=,))', result_text, re.IGNORECASE+re.DOTALL)[0])
        if statuscode == 0:
            self.show_location(lat, lng)
            self.reload_map()

    def reload_map(self):
        self.browser.reload()

    def show_location(self, lat, lng):
        mappy = folium.Map(location=[lat,lng],tiles = "OpenStreetMap",zoom_start = 13)
        folium.Marker([lat,lng]).add_to(mappy)
        mappy.save('show_city.html')
コード例 #6
0
ファイル: sdm.py プロジェクト: dkratzert/FinalCif
def display_cif(cif: 'CifContainer'):
    app = QApplication(sys.argv)
    # w = QWidget()
    w = QWebEngineView()
    w.heightForWidth(1)
    app.setActiveWindow(w)
    jsmoldir = TemporaryDirectory()
    mol = make_molecule(cif)
    content = write_html.write(mol, 250, 250)
    Path(jsmoldir.name).joinpath("./jsmol.htm").write_text(data=content,
                                                           encoding="utf-8",
                                                           errors='ignore')
    copy2(Path(__file__).parent.joinpath('jquery.min.js'), jsmoldir.name)
    copy2(
        Path(__file__).parent.joinpath('JSmol_dk.nojq.lite.js'), jsmoldir.name)
    print(Path(jsmoldir.name).joinpath("./jsmol.htm").resolve())
    w.load(
        QUrl.fromLocalFile(
            str(Path(jsmoldir.name).joinpath("./jsmol.htm").resolve())))
    w.show()
    w.reload()
    sys.exit(app.exec_())
コード例 #7
0
class MainWindow(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.setGeometry(100, 100, 300, 200)
        self.show()
        self.grid = QGridLayout(self)
        self.grid.setContentsMargins(0, 0, 0, 0)
        self.web = QWebEngineView()
        self.web.load(QUrl(link))
        self.grid.addWidget(self.web, 0, 0)

        self.web2 = QWebEngineView()
        self.web2.hide()
        self.web2.load(QUrl(link))
        self.grid.addWidget(self.web2, 0, 0)

        timer = QtCore.QTimer(self)
        timer.timeout.connect(self.refresh)
        timer.start(int(sys.argv[-1]))

    def refresh(self):
        print(int(time.time()))

        def finished():
            browser, another = self.web, self.web2
            if another.isHidden():
                browser, another = another, browser
            time.sleep(1)
            browser.show()
            another.hide()

        if self.web2.isHidden():
            self.web2.reload()
            self.web2.loadFinished.connect(finished)
        else:
            self.web.reload()
            self.web.loadFinished.connect(finished)
コード例 #8
0
class TeamtoolBrowser(QWidget, design.Ui_Form):
    def __init__(self, parent=None):
        super(TeamtoolBrowser, self).__init__(parent)
        self.setupUi(self)
        self.browser = QWebEngineView()
        self.profile = QWebEngineProfile("somestorage", self.browser)
        self.webpage = QWebEnginePage(self.profile, self.browser)
        self.browser.setPage(self.webpage)
        self.initUI()
        self.eventUI()

    def eventUI(self):
        self.btnRefresh.clicked.connect(lambda: self.browse(refresh=True))
        self.codeEdit.textChanged.connect(lambda: self.browse(offline=True))
        self.fileView.doubleClicked.connect(self.selectFile)
        self.urlBar.returnPressed.connect(lambda: self.browse())
        self.webpage.loadStarted.connect(lambda: self.startLoading())
        self.webpage.loadFinished.connect(lambda: self.onLoadFinished())
        self.btnPrev.clicked.connect(lambda: self.prev())
        self.btnNext.clicked.connect(lambda: self.next())

    def prev(self):
        ''' History: go back '''
        self.webpage.page().triggerAction(QWebEnginePage.Back)
        self.urlBar.setText(self.webpage.url().toString())

    def next(self):
        ''' History: move forward '''
        self.webpage.page().triggerAction(QWebEnginePage.Forward)
        self.urlBar.setText(self.webpage.url().toString())

    def startLoading(self):
        ''' When page starts to load '''
        self.loadingAnimation.start()
        self.labelLoading.setVisible(True)

    def onLoadFinished(self):
        ''' When page has finished to load '''
        self.loadingAnimation.stop()
        self.labelLoading.setVisible(False)

        if self.webpage.history().canGoBack():
            self.btnPrev.setEnabled(True)
        else:
            self.btnPrev.setEnabled(False)

        if self.webpage.history().canGoForward():
            self.btnNext.setEnabled(True)
        else:
            self.btnNext.setEnabled(False)
        self.urlBar.setText(self.webpage.url().toString())

    def browse(self, refresh=False, offline=False):
        ''' Browse to urlBar URL or render a text/html string '''

        # Offline mode, load plaintext html code
        if offline:
            self.webpage.setHtml(self.codeEdit.toPlainText())
            return
        # Online mode
        if refresh:
            url = self.browser.reload()
            return
        url = self.urlBar.text()
        if not re.match('http://|https://', url, re.I):
            url = f'http://{url}'
        # print('===============>', os.path.join('statics/button', 'lock-ssl.png'), QUrl(url).scheme())
        if QUrl(url).scheme() == 'https':
            print('HTTPS')
            self.httpsicon.setPixmap(self.pixmap_ssl)
        else:
            print('HTTP')
            self.httpsicon.setPixmap(self.pixmap_nossl)
        print(f'Browse to this URL: {url}')
        if isinstance(url, str) and url != '':
            self.webpage.setUrl(QUrl(url))

    def selectFile(self, index):
        ''' Select a file in file system '''
        if not self.fileModel.isDir(index) and index.data().lower().endswith(
            ('.html', '.txt')):
            with open(self.fileModel.fileInfo(index).absoluteFilePath(),
                      'r',
                      encoding='utf-8') as f:
                self.webpage.setHtml(f.read())
        else:
            print('Can not read this file...')

    def initUI(self):
        ''' Configuration of widgets '''
        self.gLayoutBrowser.addWidget(self.browser)
        self.loadingAnimation = QMovie('loading.gif')
        self.loadingAnimation.setScaledSize(QtCore.QSize(24, 24))
        self.labelLoading.setMovie(self.loadingAnimation)
        self.labelLoading.setVisible(False)

        self.fileModel = QFileSystemModel()
        self.fileModel.setRootPath(QtCore.QDir.currentPath())
        self.fileView.setModel(self.fileModel)
        self.fileModel.setNameFilters(('.html', '.txt'))
        self.fileView.setColumnWidth(0, 170)
        self.fileView.setColumnWidth(1, 50)
        self.fileView.setColumnWidth(2, 50)

        self.splitterMain.setStretchFactor(1, 3)
        self.splitterSidebar.setStretchFactor(0, 1)

        self.urlBar.setPlaceholderText('Tapez ici votre URL')
        self.loadPage(online=True)
        self.pixmap_ssl = QPixmap(os.path.join('static/button',
                                               'lock-ssl.png'))
        self.pixmap_nossl = QPixmap(
            os.path.join('static/button', 'lock-nossl.png'))
        print(f'w: {self.pixmap_ssl.width()} | h: {self.pixmap_ssl.height()}')
        self.httpsicon.setPixmap(self.pixmap_nossl)

        self.setGeometry(300, 300, 1280, 720)
        self.updateTitle()

        # self.codeEdit = TxtInput([QPushButton('Hello'), QPushButton('World')])
        # self.editor = CustomTextEditor(txtInput=self.codeEdit)
        self.codeEdit = QPlainTextEdit()
        self.splitterSidebar.addWidget(self.codeEdit)

        self.show()

    def loadPage(self, online=True):
        ''' Load home page '''
        if online:
            self.browser.setUrl(QUrl("https://www.google.com"))
            return
        with open('home.html', 'r') as f:
            html = f.read()
            self.browser.setHtml(html)

    def updateTitle(self):
        title = self.browser.page().title()
        self.setWindowTitle(f'{title}')
コード例 #9
0
class Browser(QWidget):
    def __init__(self):
        super().__init__()
        # Create a search url widget
        self.search_url = QLineEdit()
        self.search_url.setStyleSheet(
            "background-color:black; color:white; border-radius:14px; margin:0px,10px,0px,10px; border:2px solid grey; padding: 2px 10px 2px 10px; font-weight:bold;"
        )
        self.search_url.setFont(QtGui.QFont("sans-serif", 11))
        self.search_url.setPlaceholderText("Search in Google or Type a URL")
        self.search_url.setMinimumWidth(500)
        self.search_url.returnPressed.connect(self.webb)
        self.search_url.setEnabled(True)
        self.search_url.setAlignment(Qt.AlignCenter)

        # Create a vbox
        vbox = QVBoxLayout()

        # Back Button
        self.back_button = QPushButton()
        self.back_button.setIcon(self.style().standardIcon(
            QStyle.SP_ArrowBack))
        self.back_button.setEnabled(False)
        self.back_button.clicked.connect(self.go_back)

        # forword Button
        self.forword_button = QPushButton()
        self.forword_button.setIcon(self.style().standardIcon(
            QStyle.SP_ArrowForward))
        self.forword_button.clicked.connect(self.go_fast)

        # Reload Button
        self.reload_button = QPushButton()
        self.reload_button.setIcon(self.style().standardIcon(
            QStyle.SP_BrowserReload))
        self.reload_button.clicked.connect(self.go_reload_buton)

        # Reload Button
        self.stop_button = QPushButton()
        self.stop_button.setIcon(self.style().standardIcon(
            QStyle.SP_BrowserStop))
        self.stop_button.setEnabled(False)
        self.stop_button.clicked.connect(self.go_stop_button)

        # Create a Hbox
        hbox = QHBoxLayout()
        hbox.addWidget(self.back_button)
        hbox.addWidget(self.forword_button)
        hbox.addWidget(self.reload_button)
        hbox.addWidget(self.stop_button)
        hbox.addWidget(self.search_url)

        self.web = QWebEngineView()
        self.web.load(QUrl(f"https://google.com/"))
        self.web.show()
        vbox.addLayout(hbox)
        vbox.addWidget(self.web)
        self.setLayout(vbox)
        self.show()

    def webb(self):
        self.stop_button.setEnabled(True)
        self.back_button.setEnabled(True)
        if 'http://' or 'https://' not in self.search_url:
            self.web.load(QUrl(f"https://{self.search_url.text()}/"))
            self.web.show()

        else:
            self.web.load(QUrl(self.search_url.text()))
            self.web.show()

    def go_back(self):
        self.web.back()

    def go_fast(self):
        self.web.forward()

    def go_reload_buton(self):
        self.web.reload()

    def go_stop_button(self):
        self.web.stop()
コード例 #10
0
ファイル: mobile_laser.py プロジェクト: Paseul/python
class App(QWidget):
    def __init__(self):
        super().__init__()        
        
        self.data = io.BytesIO()
        self.x = 37.40494
        self.y = 127.11130
        self.loadMap(self.x, self.y)
        self.arcreading = 270
        self.adder = 0.1

        self.initUI()

        self.ccd = ccd_thread.Thread(self)
        self.ccd.changePixmap.connect(self.setCcdImage)        
        self.ccd.deamon = True
        self.ccd.start()        
        js.control_start()

    def closeEvent(self, e):
        self.ccd.stop()

    @pyqtSlot(QImage, QImage)
    def setCcdImage(self, image, image2):
        self.ccdLabel.setPixmap(QPixmap.fromImage(image))
        self.swirLabel.setPixmap(QPixmap.fromImage(image2))

    def convertQImageToMat(self, incomingImage):
        '''  Converts a QImage into an opencv MAT format  '''

        incomingImage = incomingImage.convertToFormat(4)

        width = incomingImage.width()
        height = incomingImage.height()

        ptr = incomingImage.bits()
        ptr.setsize(incomingImage.byteCount())
        arr = np.array(ptr).reshape(height, width, 4)  #  Copies the data
        return arr
    
    def loadMap(self, x, y):
        m = folium.Map(zoom_start=16, location=(x,y))
        m.save(self.data, close_file=False)
        m.save("map.html")

    def initUI(self):
        self.setWindowTitle('Mobile Laser')
        box = QHBoxLayout()
        gb = QGroupBox()
        box.addWidget(gb)

        ccdBox = QVBoxLayout()
        # create a label
        self.ccdLabel = QLabel(self)
        self.ccdLabel.resize(1920, 1080)
        ccdBox.addWidget(self.ccdLabel)
        gb.setLayout(ccdBox)
           
        swirbox = QHBoxLayout()
        gb = QGroupBox()
        swirbox.addWidget(gb)

        swirGpsBox = QVBoxLayout() 
        box.addLayout(swirGpsBox)
        self.swirLabel = QLabel(self)
        self.swirLabel.resize(640, 360)
        swirGpsBox.addWidget(self.swirLabel)
        self.webView = QWebEngineView()
        filepath = os.path.abspath(os.path.join(os.path.dirname(__file__), "map.html"))
        self.webView.load(QUrl.fromLocalFile(filepath))
        swirGpsBox.addWidget(self.webView)
        gb.setLayout(swirGpsBox)

        paintBox = QHBoxLayout()
        gb = QGroupBox()
        gb.setFixedHeight(200)
        paintBox.addWidget(gb)

        # 전체 배치
        vbox = QVBoxLayout()
        vbox.addLayout(box)
        vbox.addLayout(paintBox)
        self.setLayout(vbox)             
        self.show()

    def paintEvent(self, event):
        arcwidth = 50       # arc width
        self.painter = QPainter(self)    # create a painter object
        self.painter.setRenderHint(QPainter.Antialiasing)  # tune up painter
        self.painter.setPen(QPen(Qt.green, arcwidth, cap=Qt.FlatCap))
        # 그리기 함수의 호출 부분
        self.drawPoints(self, self.painter)
        self.painter.end() 
    
    def drawPoints(self, event, painter):
        kanvasx = 50        # binding box origin: x
        kanvasy = 650        # binding box origin: y
        kanvasheight = 75  # binding box height
        kanvaswidth = 75   # binding box width
        arcsize = 270       # arc angle between start and end.
        arcwidth = 50       # arc width
        # ---------- the following lines simulate sensor reading. -----------
        if self.arcreading > arcsize or self.arcreading < 0:  # variable to make arc move
            self.adder = -self.adder  # arcreading corresponds to the
            # value to be indicated by the arc.
        self.arcreading = self.arcreading + self.adder
        # --------------------- end simulation ------------------------------
        #print(arcreading)

        # drawArc syntax:
        #       drawArc(x_axis, y_axis, width, length, startAngle, spanAngle)
        painter.drawArc(kanvasx, kanvasy,   # binding box: x0, y0, pixels
                kanvasheight + arcwidth, # binding box: height
                kanvaswidth + arcwidth,  # binding box: width
                int((arcsize + (180 - arcsize) / 2)*16),  # arc start point, degrees (?)
                int(-self.arcreading*16))         # arc span
        painter.drawArc(kanvasx+190, kanvasy,   # binding box: x0, y0, pixels
                kanvasheight + arcwidth, # binding box: height
                kanvaswidth + arcwidth,  # binding box: width
                int((arcsize + (180 - arcsize) / 2)*16),  # arc start point, degrees (?)
                int(-self.arcreading*16))         # arc span
        painter.drawArc(kanvasx+380, kanvasy,   # binding box: x0, y0, pixels
                kanvasheight + arcwidth, # binding box: height
                kanvaswidth + arcwidth,  # binding box: width
                int((arcsize + (180 - arcsize) / 2)*16),  # arc start point, degrees (?)
                int(-self.arcreading*16))         # arc span
        painter.drawArc(kanvasx+570, kanvasy,   # binding box: x0, y0, pixels
                kanvasheight + arcwidth, # binding box: height
                kanvaswidth + arcwidth,  # binding box: width
                int((arcsize + (180 - arcsize) / 2)*16),  # arc start point, degrees (?)
                int(-self.arcreading*16))         # arc span
        painter.drawArc(kanvasx+760, kanvasy,   # binding box: x0, y0, pixels
                kanvasheight + arcwidth, # binding box: height
                kanvaswidth + arcwidth,  # binding box: width
                int((arcsize + (180 - arcsize) / 2)*16),  # arc start point, degrees (?)
                int(-self.arcreading*16))         # arc span
        painter.setFont(QFont('Times New Roman', 24, weight=QFont.Bold))
        painter.setPen(QPen(Qt.black, arcwidth, cap=Qt.FlatCap))
        painter.drawText(kanvasx+40, kanvasy+70, str(int(self.arcreading)))

    def keyPressEvent(self, e):        
        if e.key() == Qt.Key_Right:
            self.x, self.y = self.x, self.y+0.0005
            self.arcreading += 10

        elif e.key() == Qt.Key_Left:
            self.x, self.y = self.x, self.y-0.0005
            self.arcreading -= 10

        elif e.key() == Qt.Key_Up:
            self.x, self.y = self.x+0.0005, self.y
            self.arcreading += 1

        elif e.key() == Qt.Key_Down:
            self.x, self.y = self.x-0.0005, self.y
            self.arcreading -= 1
        
        m = folium.Map(zoom_start=18,location=(self.x, self.y))
        m.save(self.data, close_file=False)
        m.save("map.html")
        self.webView.reload()
        self.update()
コード例 #11
0
class Main(QtWidgets.QMainWindow):

    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        self.CreateUI()

    def CreateUI(self):

        # Create Necessary Widgets 
        self.centralwidget = QtWidgets.QWidget(self)

        self.line = QtWidgets.QLineEdit(self)
        self.line.setMinimumSize(500, 20)
        self.line.setStyleSheet('font-size:15px;')

        # Enter URL
        self.enter = QtWidgets.QPushButton(self)
        self.enter.resize(0,0)
        self.enter.clicked.connect(self.set_url)
        self.enter.setShortcut('Return')

        # Reload Button
        self.reload = QtWidgets.QPushButton('↻',self)
        self.reload.setMinimumSize(20, 20)
        self.reload.setShortcut('F5')
        self.reload.setStyleSheet('font-size:23px;')
        self.reload.clicked.connect(self.reload_page)

        # Back Button
        self.back = QtWidgets.QPushButton('←',self)
        self.back.setMinimumSize(20, 20)
        self.back.setStyleSheet('font-size:23px;')
        self.back.clicked.connect(self.go_back)

        # Forward Button
        self.forward = QtWidgets.QPushButton('→',self)
        self.forward.setMinimumSize(20, 20)
        self.forward.setStyleSheet('font-size:23px;')
        self.forward.clicked.connect(self.go_forwardard)

        # Create Progress Bar
        self.pbar = QtWidgets.QProgressBar()
        self.pbar.setMaximumWidth(120)

        # Update Progress Bar, Window Title etc.
        self.web = QWebEngineView(loadProgress = self.pbar.setValue, loadFinished = self.pbar.hide,         loadStarted = self.pbar.show, titleChanged = self.setWindowTitle)
        self.web.setMinimumSize(1200, 600)

        # Check for url changes
        self.web.urlChanged.connect(self.if_url_changed)

        # Check for user liink hovering
        self.web.page().linkHovered.connect(self.if_link_hover)

        # Set Grid
        grid = QtWidgets.QGridLayout()
 
 			# Set Widget Locations
		grid.addWidget(self.back,0,0, 1, 1)
		grid.addWidget(self.line,0,3, 1, 1)
		grid.addWidget(self.forward,0,1, 1, 1)
		grid.addWidget(self.reload,0,2, 1, 1)
		grid.addWidget(self.web, 2, 0, 1, 6)
 
		self.centralwidget.setLayout(grid)
 
		# Window Settings
 			# Default Window Size and Location
		self.setGeometry(25, 100, 1200, 600)
			# Window Title
		self.setWindowTitle('Browsey')
			# Window Icon
		self.setWindowIcon(QtGui.QIcon(''))
			# Window Colour
		self.setStyleSheet('background-color:')
			# Window Status Bar 
		self.status = self.statusBar()
		self.status.addPermanentWidget(self.pbar)
		self.status.hide()
 
		self.setCentralWidget(self.centralwidget)

 	# Function to Handle URLs
	def set_url(self):

		# Get default URL
		global url
		 
		url = self.line.text()

 		# Set URL Prefixes
		http = 'http://'
		www = 'www.'
		
		# Check and Set
		if www in url and http not in url:
			url = http + url			 
			 
		elif http in url and www not in url:
			url = url[:7] + www + url[7:]
			
		# If no suffix used make it a google search
		elif '.' not in url:
			url = 'http://www.google.com/search?q='+url
 
		elif http and www not in url:
			url = http + www + url
 
		self.line.setText(url)
 		
 		# Load site at URL
		self.web.load(QtCore.QUrl(url))

 		# Show URL
		self.status.show()

 	# Navigation functions
	def go_back(self):
		self.web.back()
		 
	def go_forwardard(self):
		self.web.forwardard()

	def reload_page(self):
		self.web.reload()

 	#Check if user has entered new URL
	def if_url_changed(self):
		self.line.setText(self.web.url().toString())

 	# Show link in statusbar if user hovers
	def if_link_hover(self, l):
		self.status.showMessage(l)
コード例 #12
0
class MainWidget(QWidget):
    def __init__(self, url):
        super().__init__()
        fontDB = QFontDatabase()
        fontDB.addApplicationFont(':/mono-font')
        # fontDB.addApplicationFont(':/Taipei-font')
        screen = QDesktopWidget().screenGeometry()
        self.width, self.height = screen.width(), screen.height()
        self.html = ''
        self.url = url
        self.GI = None
        self.DL = None
        self.web_view = QWebEngineView(self)
        self.web_view.load(QUrl(self.url))
        self.web_view.page().titleChanged.connect(self.get_html)
        btnExit = QPushButton('', self)
        btnExit.setIcon(QIcon(':/exit-icon'))
        btnExit.setIconSize(QSize(32, 32))
        btnExit.setToolTip('Exit')
        btnExit.clicked.connect(QApplication.quit)
        self.btnHome = QPushButton('', self)
        self.btnHome.setIcon(QIcon(':/home-icon'))
        self.btnHome.setIconSize(QSize(32, 32))
        self.btnHome.setToolTip('Home')
        self.btnHome.clicked.connect(self.goHome)
        self.btnBack = QPushButton('', self)
        self.btnBack.setIcon(QIcon(':/go_back-icon'))
        self.btnBack.setIconSize(QSize(32, 32))
        self.btnBack.setToolTip('Backward')
        self.btnBack.clicked.connect(self.goBack)
        self.btnBack.setDisabled(True)
        self.btnNext = QPushButton('', self)
        self.btnNext.setIcon(QIcon(':/go_forward-icon'))
        self.btnNext.setIconSize(QSize(32, 32))
        self.btnNext.setToolTip('Forward')
        self.btnNext.clicked.connect(self.goForward)
        self.btnNext.setDisabled(True)
        self.cmbDownList = QComboBox(self)
        self.cmbDownList.setMinimumHeight(40)
        # font = self.cmbDownList.font()
        font = QFont('Liberation Mono')
        font.setPointSize(14)
        self.cmbDownList.setFont(font)
        self.cmbDownList.setIconSize(QSize(24, 24))
        self.cmbDownList.currentIndexChanged.connect(self.onIndexChanged)
        self.cmbDownList.setToolTip('Select a stream to download')
        self.cmbCapsList = QComboBox(self)
        self.cmbCapsList.setMinimumHeight(40)
        # font = QFont('Taipei Sans TC Beta')
        font = self.cmbCapsList.font()
        font.setPointSize(14)
        self.cmbCapsList.setFont(font)
        self.cmbCapsList.setToolTip('Select a caption/subtitle to download')
        btnSettings = QPushButton('', self)
        btnSettings.setIcon(QIcon(':/settings-icon'))
        btnSettings.setIconSize(QSize(32, 32))
        btnSettings.setToolTip('Settings')
        btnSettings.clicked.connect(self.onSettings)
        self.btnDLoad = QPushButton('', self)
        self.btnDLoad.setIcon(QIcon(':/download-icon'))
        self.btnDLoad.setIconSize(QSize(32, 32))
        self.btnDLoad.setToolTip('Download')
        self.btnDLoad.clicked.connect(self.goDownload)
        self.btnDLoad.setDisabled(True)
        self.progressBar = QProgressBar(self)
        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(100)

        hBox1 = QHBoxLayout()
        hBox1.addWidget(btnExit, 0)
        hBox1.addWidget(self.btnHome, 0)
        hBox1.addWidget(self.btnBack, 0)
        hBox1.addWidget(self.btnNext, 0)
        hBox1.addWidget(self.cmbDownList, 1)
        hBox1.addWidget(self.cmbCapsList, 0)
        hBox1.addWidget(btnSettings, 0)
        hBox1.addWidget(self.btnDLoad, 0)
        vBox = QVBoxLayout()
        vBox.addLayout(hBox1)
        vBox.addWidget(self.web_view)
        vBox.addWidget(self.progressBar)
        self.setLayout(vBox)
        self.setWindowTitle('Youtube Download Helper')
        self.setGeometry(QRect(round((self.width - 760) / 2), round((self.height - 550) / 2), 760, 550))
        self.setMinimumSize(QSize(760, 550))

    def store_html(self, html):
        # print('store_html()')
        self.html = html
        if self.web_view.page().action(QWebEnginePage.Back).isEnabled():
            self.btnBack.setEnabled(True)
        else:
            self.btnBack.setDisabled(True)
        if self.web_view.page().action(QWebEnginePage.Forward).isEnabled():
            self.btnNext.setEnabled(True)
        else:
            self.btnNext.setDisabled(True)
        if self.web_view.title() != 'YouTube' and self.web_view.title() != 'https://www.youtube.com':
            # print(self.web_view.title())
            self.btnHome.setEnabled(True)
        else:
            self.btnHome.setDisabled(True)
        self.cmbDownList.clear()
        self.cmbCapsList.clear()
        url = self.web_view.page().url().url()
        if 'video-id' in self.html and '?v=' in url:
            # fp = open(self.web_view.title() + '.html', 'w')
            # fp.write(self.html)
            # fp.close()
            self.GI = GetItem(url)
            self.GI.addItem.connect(self.onAddItem)
            self.GI.addCaption.connect(self.onAddCaption)
            self.GI.finished.connect(self.onAddItemFinished)
            self.GI.start()
        else:
            self.btnDLoad.setDisabled(True)

    def get_html(self):
        # print('get_html')
        self.web_view.page().toHtml(self.store_html)

    def goHome(self):
        self.web_view.setUrl(QUrl(self.url))

    def goBack(self):
        self.web_view.back()

    def goForward(self):
        self.web_view.forward()

    def goDownload(self):
        global download_ongoing
        download_ongoing = True
        self.btnDLoad.setDisabled(True)
        self.progressBar.setValue(0)
        self.DL = DownLoad(self.web_view.page().url().url(), self.cmbDownList.currentIndex(),
                           self.cmbCapsList.currentIndex())
        self.DL.valueChanged.connect(self.onValueChanged)
        self.DL.dlCompleted.connect(self.onDlCompleted)
        self.DL.start()

    def onAddItem(self, icon, item):
        self.cmbDownList.addItem(QIcon(icon), item)

    def onAddCaption(self, cap):
        self.cmbCapsList.addItem(cap)

    def onAddItemFinished(self):
        if not download_ongoing:
            self.btnDLoad.setEnabled(True)

    def onValueChanged(self, per):
        self.progressBar.setValue(round(per))
        # print('%.2f%% completed' % per)

    def onDlCompleted(self):
        global download_ongoing
        download_ongoing = False
        self.btnDLoad.setDisabled(True)
        self.progressBar.setValue(0)

    def onIndexChanged(self):
        if not download_ongoing:
            self.btnDLoad.setEnabled(True)

    def onSettings(self):
        sWnd = SettingsDlg(self.width, self.height)
        sWnd.exec()
        if sWnd.SettingsChanged:
            # print('Settings saved!')
            if self.web_view.title() != 'YouTube' and self.web_view.title() != 'https://www.youtube.com':
                self.web_view.reload()
コード例 #13
0
ファイル: syncthingui.py プロジェクト: coolshou/syncthingui
class MainWindow(QMainWindow):

    """Main window class."""

    def __init__(self):
        """Init class."""
        super(MainWindow, self).__init__()
        self.pixmap_syncthingui = QPixmap(":/images/syncthingui.svg")
        tf = QTransform()
        self.pixmap_syncthingui0 = QPixmap(":/images/syncthingui.svg")
        tf.rotate(90.0)
        self.pixmap_syncthingui1 = self.pixmap_syncthingui0.transformed(tf)
        tf.rotate(180.0)
        self.pixmap_syncthingui2 = self.pixmap_syncthingui0.transformed(tf)
        tf.rotate(270.0)
        self.pixmap_syncthingui3 = self.pixmap_syncthingui0.transformed(tf)

        self.init_gui()
        self.init_menu()
        self.init_systray()

        self.run()

    def init_gui(self):
        """init gui setup"""
        self.setWindowIcon(QIcon(self.pixmap_syncthingui))

        self.progressbar = QProgressBar()
        self.statusBar().showMessage(getoutput(SYNCTHING + ' --version'))
        self.statusBar().addPermanentWidget(self.progressbar)
        self.setWindowTitle(__doc__.strip().capitalize())
        self.setMinimumSize(900, 600)
        self.setMaximumSize(1280, 1024)
        self.resize(self.minimumSize())
        self.center()

        # QWebView
        # self.view = QWebView(self)
        self.view = QWebEngineView(self)
        self.view.loadStarted.connect(self.start_loading)
        self.view.loadFinished.connect(self.finish_loading)
        self.view.loadProgress.connect(self.loading)
        self.view.titleChanged.connect(self.set_title)
        self.view.page().linkHovered.connect(
            lambda link_txt: self.statusBar().showMessage(link_txt[:99], 3000))
        QShortcut("Ctrl++", self, activated=lambda:
                  self.view.setZoomFactor(self.view.zoomFactor() + 0.2))
        QShortcut("Ctrl+-", self, activated=lambda:
                  self.view.setZoomFactor(self.view.zoomFactor() - 0.2))
        QShortcut("Ctrl+0", self, activated=lambda: self.view.setZoomFactor(1))
        QShortcut("Ctrl+q", self, activated=lambda: self.close())

        # syncthing console
        self.consolewidget = QWidget(self)
        # TODO: start at specify (w,h)
        self.consolewidget.setMinimumSize(QSize(200, 100))
        # TODO: setStyleSheet
        # self.consolewidget.setStyleSheet("margin:0px; padding: 0px; \
        # border:1px solid rgb(0, 0, 0);")
        # border-radius: 40px;")
        # TODO read syncthing console visible from setting
        # self.consolewidget.setVisible(False)
        # self.consolewidget.showEvent
        # self.consoletextedit = QPlainTextEdit(parent=self.consolewidget)
        self.consoletoolbar = QWidget(self)
        hlayout = QHBoxLayout()
        hlayout
        self.consoletoolbar.setLayout(hlayout)
        self.consoletextedit = QTextEdit(parent=self.consolewidget)
        self.consoletextedit.setWordWrapMode(QTextOption.NoWrap)
        # self.consoletextedit.setStyleSheet(" border:1px solid rgb(0, 0, 0);")
        # self.consoletextedit.setStyleSheet("margin:0px; padding: 0px;")
        layout = QVBoxLayout()
        layout.addWidget(self.consoletoolbar)
        layout.addWidget(self.consoletextedit)

        self.consolewidget.setLayout(layout)

        self.splitter = QSplitter(Qt.Vertical)
        self.splitter.addWidget(self.view)
        self.splitter.addWidget(self.consolewidget)

        # process
        self.process = QProcess()
        self.process.error.connect(self._process_failed)
        # QProcess emits `readyRead` when there is data to be read
        self.process.readyRead.connect(self._process_dataReady)
        self.process.stateChanged.connect(self._process_stateChanged)
        # Just to prevent accidentally running multiple times
    # Disable the button when process starts, and enable it when it finishes
    # self.process.started.connect(lambda: self.runButton.setEnabled(False))
    # self.process.finished.connect(lambda: self.runButton.setEnabled(True))

        # backend options
        self.chrt = QCheckBox("Smooth CPU ", checked=True)
        self.ionice = QCheckBox("Smooth HDD ", checked=True)
        self.chrt.setToolTip("Use Smooth CPUs priority (recommended)")
        self.ionice.setToolTip("Use Smooth HDDs priority (recommended)")
        self.chrt.setStatusTip(self.chrt.toolTip())
        self.ionice.setStatusTip(self.ionice.toolTip())
        # main toolbar
        self.toolbar = self.addToolBar("SyncthinGUI Toolbar")
        # self.toolbar.addAction(QIcon.fromTheme("media-playback-stop"),
        self.toolbar.addAction(QIcon(":/images/stop.svg"),
                               "Stop Sync", lambda: self.syncthing_stop())
        # self.toolbar.addAction(QIcon.fromTheme("media-playback-start"),
        self.toolbar.addAction(QIcon(":/images/start.svg"),
                               "Restart Sync", lambda: self.run())
        self.toolbar.addSeparator()
        self.toolbar.addWidget(self.chrt)
        self.toolbar.addWidget(self.ionice)
        self.toolbar.addSeparator()
        # TODO: test event API
        self.toolbar.addAction(QIcon(":/images/start.svg"),
                               "test ", lambda: self.test())

        # final gui setup
        self.setCentralWidget(self.splitter)

    def test(self):
        """ test some function """
        print("test")

    def init_menu(self):
        """init menu setup"""
        # file menu
        file_menu = self.menuBar().addMenu("File")
        # TODO: setting menu item
        file_menu.addAction("Exit", lambda: self.close())
        # Syncthing menu
        sync_menu = self.menuBar().addMenu("Syncthing")
        sync_menu.addAction("Start Syncronization", lambda: self.run())
        sync_menu.addAction("Stop Syncronization",
                            lambda: self.syncthing_stop())
        # TODO: restart
        # TODO: reflash F5
        sync_menu.addAction("Open in external browser",
                            lambda: open_new_tab(URL))

        # view menu
        view_menu = self.menuBar().addMenu("View")
        # TODO: syncthing console menu
        view_menu.addAction("syncthing console", lambda: self.show_console)
        #
        zoom_menu = view_menu.addMenu("Zoom browser")
        zoom_menu.addAction(
            "Zoom In",
            lambda: self.view.setZoomFactor(self.view.zoomFactor() + .2))
        zoom_menu.addAction(
            "Zoom Out",
            lambda: self.view.setZoomFactor(self.view.zoomFactor() - .2))
        zoom_menu.addAction(
            "Zoom To...",
            lambda: self.view.setZoomFactor(QInputDialog.getInt(
                self, __doc__, "<b>Zoom factor ?:", 1, 1, 9)[0]))
        zoom_menu.addAction("Zoom Reset", lambda: self.view.setZoomFactor(1))
        view_menu.addSeparator()
        act = view_menu.addAction("View Page Source",
                                  lambda: self.view_syncthing_source)
        act.setDisabled(True)

        # window menu
        window_menu = self.menuBar().addMenu("&Window")
        window_menu.addAction("Minimize", lambda: self.showMinimized())
        window_menu.addAction("Maximize", lambda: self.showMaximized())
        window_menu.addAction("Restore", lambda: self.showNormal())
        window_menu.addAction("Center", lambda: self.center())
        window_menu.addAction("Top-Left", lambda: self.move(0, 0))
        window_menu.addAction("To Mouse",
                              lambda: self.move_to_mouse_position())
        window_menu.addAction("Fullscreen", lambda: self.showFullScreen())
        window_menu.addSeparator()
        window_menu.addAction("Increase size", lambda: self.resize(
            self.size().width() * 1.2, self.size().height() * 1.2))
        window_menu.addAction("Decrease size", lambda: self.resize(
            self.size().width() // 1.2, self.size().height() // 1.2))
        window_menu.addAction("Minimum size", lambda:
                              self.resize(self.minimumSize()))
        window_menu.addAction("Maximum size", lambda:
                              self.resize(self.maximumSize()))
        window_menu.addAction("Horizontal Wide", lambda: self.resize(
            self.maximumSize().width(), self.minimumSize().height()))
        window_menu.addAction("Vertical Tall", lambda: self.resize(
            self.minimumSize().width(), self.maximumSize().height()))
        window_menu.addSeparator()
        window_menu.addAction("Disable Resize",
                              lambda: self.setFixedSize(self.size()))
        # help menu
        help_menu = self.menuBar().addMenu("&Help")
        help_menu.addAction("Support Forum", lambda: open_new_tab(HELP_URL_0))
        help_menu.addAction("Lastest Release",
                            lambda: open_new_tab(HELP_URL_1))
        help_menu.addAction("Documentation", lambda: open_new_tab(HELP_URL_2))
        help_menu.addAction("Bugs", lambda: open_new_tab(HELP_URL_3))
        help_menu.addAction("Source Code", lambda: open_new_tab(HELP_URL_4))
        help_menu.addSeparator()
        help_menu.addAction("About Qt 5", lambda: QMessageBox.aboutQt(self))
        help_menu.addAction("About Python 3",
                            lambda: open_new_tab('https://www.python.org'))
        help_menu.addAction("About " + __doc__,
                            lambda: QMessageBox.about(self, __doc__, HELPMSG))
        help_menu.addSeparator()
        help_menu.addAction("Keyboard Shortcuts", lambda:
                            QMessageBox.information(self, __doc__, SHORTCUTS))
        help_menu.addAction("View GitHub Repo", lambda: open_new_tab(__url__))
        if not sys.platform.startswith("win"):
            help_menu.addAction("Show Source Code", lambda: self.view_source())
        help_menu.addSeparator()
        help_menu.addAction("Check Updates", lambda: self.check_for_updates())

    def init_systray(self):
        """init system tray icon"""
        # self.tray = QSystemTrayIcon(QIcon(self.pixmap_syncthingui), self)
        self.tray = AnimatedSysTrayIcon(QIcon(self.pixmap_syncthingui), self)
        self.tray.add_ani_icon(QIcon(self.pixmap_syncthingui0))
        self.tray.add_ani_icon(QIcon(self.pixmap_syncthingui1))
        self.tray.add_ani_icon(QIcon(self.pixmap_syncthingui2))
        self.tray.add_ani_icon(QIcon(self.pixmap_syncthingui3))

        self.tray.setToolTip(__doc__.strip().capitalize())
        traymenu = QMenu(self)
        traymenu.addAction(__doc__).setDisabled(True)
        traymenu.addSeparator()
        # to test animate
        # traymenu.addAction("start", lambda: self.tray.animate_start())
        # traymenu.addAction("stop", lambda: self.tray.animate_stop())
        # traymenu.addSeparator()
        traymenu.addAction("Stop Sync", lambda: self.syncthing_stop())
        traymenu.addAction("Restart Sync", lambda: self.run())
        traymenu.addSeparator()
        traymenu.addAction("Show", lambda: self.show_gui())
        traymenu.addAction("Hide", lambda: self.hide())
        traymenu.addSeparator()
        # traymenu.addAction("Open Web", lambda: open_new_tab(URL))
        # traymenu.addAction("Quit All", lambda: self.close())
        traymenu.addAction("Quit All", lambda: self.app_exit())
        self.tray.setContextMenu(traymenu)
        self.tray.show()

    def show_gui(self):
        """
        Helper method to show UI, this should not be needed, but I discovered.
        """
        self.showNormal()
        # webview require 70Mb to show webpage
        self.view.load(QUrl(URL))

    def syncthing_start(self):
        """syncthing start"""
        self.run()

    def syncthing_stop(self):
        """syncthing stop"""
        print("try to stop syncthing")
        self.process.kill()
        # check there is no other syncthing is running!
        for proc in psutil.process_iter():
            # check whether the process name matches
            # print("procress: %s " % proc.name())
            if proc.name() == SYNCTHING:
                proc.kill()

    def run(self):
        """Run bitch run!."""
        # Stop first!
        self.syncthing_stop()

        command_to_run_syncthing = " ".join((
            "ionice --ignore --class 3" if self.ionice.isChecked() else "",
            "chrt --verbose --idle 0" if self.chrt.isChecked() else "",
            SYNCTHING, "-no-browser"))
        print(command_to_run_syncthing)
        self.process.start(command_to_run_syncthing)
        if not self.process.waitForStarted():
            self._process_failed()

    @pyqtSlot()
    def _process_failed(self):
        """Read and return errors."""
        self.statusBar().showMessage("ERROR:Fail:Syncthing blow up in pieces!")
        print("ERROR:Fail:Syncthing blow up in pieces! Wheres your God now?")
        return str(self.process.readAllStandardError()).strip().lower()

    @pyqtSlot()
    def _process_dataReady(self):
        """get process stdout/strerr when data ready"""
        # TODO: format the msg to remove extra b and \n
        msg = str(self.process.readAll())
        lines = msg.split("'")
        tmp = lines[1]
        tmp = tmp.splitlines(0)
        lines = tmp[0].split("\\n")
        for line in lines:
            if line != "":
                # print("1: %s" % line)
                self.consoletextedit.append(line)
        self.consoletextedit.ensureCursorVisible()
        # autoscroll to last line's first character
        self.consoletextedit.moveCursor(QTextCursor.End)
        self.consoletextedit.moveCursor(QTextCursor.StartOfLine)

    @pyqtSlot(QProcess.ProcessState)
    def _process_stateChanged(self, state):
        """ procress_stateChanged """
        # TODO handle procress_stateChanged
        print("procress_stateChanged: %s" % state)

    def center(self):
        """Center Window on the Current Screen,with Multi-Monitor support."""
        window_geometry = self.frameGeometry()
        mousepointer_position = QApplication.desktop().cursor().pos()
        screen = QApplication.desktop().screenNumber(mousepointer_position)
        centerpoint = QApplication.desktop().screenGeometry(screen).center()
        window_geometry.moveCenter(centerpoint)
        self.move(window_geometry.topLeft())

    def move_to_mouse_position(self):
        """Center the Window on the Current Mouse position."""
        window_geometry = self.frameGeometry()
        window_geometry.moveCenter(QApplication.desktop().cursor().pos())
        self.move(window_geometry.topLeft())

    def show_console(self):
        """Show syncthing console"""
        visible = not self.consolewidget.isVisible
        print("bVisible: %s" % visible)
        self.consolewidget.setVisible(True)
        self.consolewidget.resize(QSize(200, 100))

    def view_source(self):
        """ TODO: Call methods to load and display source code."""
        # call(('xdg-open ' if sys.platform.startswith("linux") else 'open ')
        #      + __file__, shell=True)
        pass

    def view_syncthing_source(self):
        """Call methods to load and display web page source code."""
        print("view_syncthing_source start")
        # access_manager = self.view.page().networkAccessManager()
        # reply = access_manager.get(QNetworkRequest(self.view.url()))
        # reply.finished.connect(self.slot_source_downloaded)

    def slot_source_downloaded(self):
        """Show actual page source code."""
        reply = self.sender()
        # TODO: highlight html source editor/viewer
        self.textedit = QPlainTextEdit()
        self.textedit.setAttribute(Qt.WA_DeleteOnClose)
        self.textedit.setReadOnly(True)
        self.textedit.setPlainText(QTextStream(reply).readAll())
        self.textedit.show()
        reply.deleteLater()

    @pyqtSlot()
    def start_loading(self):
        """show progressbar when downloading data"""
        self.progressbar.show()

    @pyqtSlot(bool)
    def finish_loading(self, finished):
        """Finished loading content."""
        if not finished:
            # TODO: When loading fail, what should we do?
            print("load fail")
            if self.process.state() == QProcess.NotRunning:
                self.run()
                self.view.reload()
            # if self.process.state != QProcess.Running:
            #    print("syncthing is not running: %s" % self.process.state())
            # pass
        print("finish_loading: %s" % finished)
        # TODO: WebEngineView does not have following function?
        # self.view.settings().clearMemoryCaches()
        # self.view.settings().clearIconDatabase()

        # print("finish_loading %s" % datetime.strftime(datetime.now(),
        #                                              '%Y-%m-%d %H:%M:%S'))
        # TODO: following line need 6 sec to finish!!
        # TODO: (" INFO: Loading Web UI increases >250Mb RAM!.")
        # self.view.page().mainFrame().evaluateJavaScript(BASE_JS)
        # print("finish_loading %s" % datetime.strftime(datetime.now(),
        #                                             '%Y-%m-%d %H:%M:%S'))
        self.progressbar.hide()

    @pyqtSlot(int)
    def loading(self, idx):
        """loading content"""
        #print("loading %s" % idx)
        self.progressbar.setValue(idx)

    @pyqtSlot(str)
    def set_title(self, title):
        """set title when webview's title change"""
        # print("title: %s" % title)
        if len(title.strip()) > 0:
            self.setWindowTitle(self.view.title()[:99])

    def check_for_updates(self):
        """Method to check for updates from Git repo versus this version."""
        # print("TODO: https://github.com/coolshou/syncthingui/releases/latest")

        print("__version__: %s" % __version__)
        '''
        this_version = str(open(__file__).read())
        print("this_version: %s" % this_version)
        last_version = str(request.urlopen(__source__).read().decode("utf8"))
        print("last_version: %s" % last_version)

        TODO: previous use file compare, when diff then there is new file!!
        if this_version != last_version:
            m = "Theres new Version available!<br>Download update from the web"
        else:
            m = "No new updates!<br>You have the lastest version of" + __doc__
        return QMessageBox.information(self, __doc__.title(), "<b>" + m)
'''
    def closeEvent(self, event):
        """Ask to Quit."""
        if self.tray.isVisible():
            if self.tray.supportsMessages():
                self.tray.showMessage("Info",
                                      "The program will keep running in the "
                                      "system tray. To terminate the program,"
                                      " choose <b>Quit</b> in the context "
                                      "menu of the system tray entry.")
            else:
                print(" System tray not supports balloon messages ")
            self.hide()
            event.ignore()

    def app_exit(self):
        """exit app"""
        # TODO: do we need to show UI when doing close?
        # self.show_gui()
        # TODO: show QMessageBox on all virtual desktop
        the_conditional_is_true = QMessageBox.question(
            self, __doc__.title(), 'Quit %s?' % __doc__,
            QMessageBox.Yes | QMessageBox.No,
            QMessageBox.No) == QMessageBox.Yes
        if the_conditional_is_true:
            self.syncthing_stop()
            self.ani_stop = True
            QApplication.instance().quit
            quit()
コード例 #14
0
class FlowchartView(q.QWidget):
    selectRequested = qc.pyqtSignal(int)
    eventNameVisibilityChanged = qc.pyqtSignal(bool)
    eventParamVisibilityChanged = qc.pyqtSignal(bool)

    # View -> Core
    readySignal = qc.pyqtSignal()
    reloadedSignal = qc.pyqtSignal()
    eventSelected = qc.pyqtSignal(int)

    def __init__(self, parent, flow_data: FlowData) -> None:
        super().__init__(parent)
        self.flow_data: FlowData = flow_data
        self.is_current = True
        self.selected_event: typing.Optional[Event] = None
        self.showEventParams = False
        self.initWidgets()
        self.initLayout()
        self.connectWidgets()

    def initWidgets(self) -> None:
        self.web_object = FlowchartWebObject(self)
        self.flow_data.flowDataChanged.connect(self.onFlowDataChanged)
        self.flow_data.fileLoaded.connect(self.web_object.fileLoaded)
        self.selectRequested.connect(self.web_object.selectRequested)
        self.eventNameVisibilityChanged.connect(
            self.web_object.eventNameVisibilityChanged)
        self.eventParamVisibilityChanged.connect(
            self.onEventParamVisibilityChanged)
        self.eventParamVisibilityChanged.connect(
            self.web_object.eventParamVisibilityChanged)

        self.view = QWebEngineView()
        self.view.setContextMenuPolicy(qc.Qt.NoContextMenu)
        self.channel = QWebChannel()
        self.channel.registerObject('widget', self.web_object)
        self.view.page().setWebChannel(self.channel)
        self.view.page().setBackgroundColor(qg.QColor(0x38, 0x38, 0x38))
        self.view.setUrl(qc.QUrl.fromLocalFile(get_path('assets/index.html')))

        self.entry_point_view = q.QListView(self)
        self.ep_proxy_model = qc.QSortFilterProxyModel(self)
        self.ep_proxy_model.setSourceModel(self.flow_data.entry_point_model)
        self.ep_proxy_model.setFilterKeyColumn(-1)
        self.entry_point_view.setModel(self.ep_proxy_model)
        self.ep_search = SearchBar()
        self.ep_search.hide()

        self.container_model = ContainerModel(self)
        self.container_view = ContainerView(None, self.container_model,
                                            self.flow_data)
        self.container_stacked_widget = q.QStackedWidget()
        self.container_stacked_widget.addWidget(q.QWidget())
        self.container_stacked_widget.addWidget(self.container_view)

        self.update_timer = qc.QTimer(self)
        self.update_timer.timeout.connect(self.web_object.flowDataChanged)
        self.update_timer.setSingleShot(True)

    def initLayout(self) -> None:
        left_pane_splitter = q.QSplitter(qc.Qt.Vertical)
        ep_widget = q.QWidget()
        ep_layout = q.QVBoxLayout(ep_widget)
        ep_layout.setContentsMargins(0, 0, 0, 0)
        ep_layout.addWidget(self.entry_point_view, stretch=1)
        ep_layout.addWidget(self.ep_search)
        left_pane_splitter.addWidget(ep_widget)
        left_pane_splitter.addWidget(self.container_stacked_widget)
        left_pane_splitter.setSizes([
            int(left_pane_splitter.height() * 0.6),
            int(left_pane_splitter.height() * 0.4)
        ])

        splitter = q.QSplitter()
        splitter.addWidget(left_pane_splitter)
        splitter.addWidget(self.view)
        splitter.setSizes(
            [int(splitter.width() * 0.3),
             int(splitter.width() * 0.7)])
        layout = q.QHBoxLayout(self)
        layout.addWidget(splitter)
        layout.setContentsMargins(0, 0, 0, 0)

    def connectWidgets(self) -> None:
        self.ep_search.connectToFilterModel(self.ep_proxy_model)
        self.ep_search.addFindShortcut(self)

        self.flow_data.flowDataChanged.connect(
            lambda reason: self.entry_point_view.clearSelection())
        self.entry_point_view.selectionModel().selectionChanged.connect(
            self.onEntryPointSelected)

        connect_model_change_signals(self.container_model, self.flow_data,
                                     FlowDataChangeReason.EventParameters)
        self.eventSelected.connect(self.onEventSelectedInWebView)
        self.flow_data.flowDataChanged.connect(
            lambda reason: self.refreshParamModel())

        self.reloadedSignal.connect(self.onWebViewReloaded)

    def onEventParamVisibilityChanged(self, show: bool) -> None:
        self.showEventParams = show

    def setIsCurrentView(self, is_current: bool) -> None:
        self.is_current = is_current
        if is_current and self.update_timer.isActive():
            self.update_timer.stop()
            self.web_object.flowDataChanged.emit()

    def export(self) -> None:
        if not self.flow_data.flow:
            return
        path = q.QFileDialog.getSaveFileName(
            self, 'Select a location for the graph data',
            self.flow_data.flow.name + '.json', 'Data (*.json)')[0]
        if not path:
            return
        data = self.web_object.getData()
        try:
            with open(path, 'w') as f:
                json.dump(data, f, default=lambda x: str(x))
        except:
            q.QMessageBox.critical(self, 'Export graph data',
                                   'Failed to write to ' + path)

    def reload(self) -> None:
        self.view.reload()

    def onWebViewReloaded(self) -> None:
        if not self.selected_event or not self.flow_data.flow or not self.flow_data.flow.flowchart:
            return

        try:
            new_idx = self.flow_data.flow.flowchart.events.index(
                self.selected_event)
            self.selectRequested.emit(new_idx)
        except ValueError:
            self.container_model.set(None)
            self.container_stacked_widget.setCurrentIndex(0)

    def refreshParamModel(self) -> bool:
        if self.selected_event and hasattr(self.selected_event.data, 'params'):
            if not self.selected_event.data.params:  # type: ignore
                self.selected_event.data.params = Container()  # type: ignore
            self.container_model.set(
                self.selected_event.data.params)  # type: ignore
            self.container_stacked_widget.setCurrentIndex(1)
            return True
        return False

    def onEventSelectedInWebView(self, idx: int) -> None:
        if idx >= 0:
            event = self.flow_data.flow.flowchart.events[idx]
            self.selected_event = event
            if self.refreshParamModel():
                return
        else:
            self.selected_event = None

        self.container_model.set(None)
        self.container_stacked_widget.setCurrentIndex(0)

    def onFlowDataChanged(self, reason: FlowDataChangeReason) -> None:
        should_reload = bool(reason & (FlowDataChangeReason.Reset
                                       | FlowDataChangeReason.Actors
                                       | FlowDataChangeReason.Events))
        if self.showEventParams:
            should_reload = should_reload or bool(
                reason & FlowDataChangeReason.EventParameters)
        if not should_reload:
            return
        if self.is_current:
            self.web_object.flowDataChanged.emit()
        else:
            self.update_timer.start(15 * 1000)

    def onEntryPointSelected(self, selected, deselected) -> None:
        if len(selected.indexes()) != 1:
            return
        idx = selected.indexes()[0]
        self.selectRequested.emit(-1000 -
                                  self.ep_proxy_model.mapToSource(idx).row())

    def delayedSelect(self, event: Event) -> None:
        try:
            qc.QTimer.singleShot(
                1000, lambda: self.selectRequested.emit(
                    self.flow_data.flow.flowchart.events.index(event)))
        except ValueError:
            pass

    def webEditEvent(self, idx: int) -> None:
        if idx < 0:
            return
        show_event_editor(self, self.flow_data, idx)

    def webAddEntryPoint(self, event_idx: int) -> None:
        if event_idx < 0:
            return

        ep_name, ok = q.QInputDialog.getText(self, 'Add entry point',
                                             f'Name of the new entry point:',
                                             q.QLineEdit.Normal)
        if not ok or not ep_name:
            return

        ep = EntryPoint(ep_name)
        assert self.flow_data.flow and self.flow_data.flow.flowchart
        ep.main_event.v = self.flow_data.flow.flowchart.events[event_idx]
        self.flow_data.entry_point_model.append(ep)

    def webRemoveEntryPoint(self, ep_idx: int) -> None:
        try:
            self.flow_data.entry_point_model.removeRow(ep_idx)
        except IndexError as e:
            q.QMessageBox.critical(
                self, 'Bug',
                f'An error has occurred: {e}\n\nPlease report this issue and mention what you were doing when this message showed up.'
            )

    def addNewEvent(self) -> typing.Optional[Event]:
        return add_new_event(self, self.flow_data)

    def webAddEventAbove(self, parent_indices: typing.List[int],
                         event_idx: int) -> None:
        if event_idx < 0:
            return
        assert self.flow_data.flow and self.flow_data.flow.flowchart
        event = self.flow_data.flow.flowchart.events[event_idx]

        parent_events = [
            self.flow_data.flow.flowchart.events[i] for i in parent_indices
            if i >= 0
        ]
        list_widget = CheckableEventParentListWidget(None, event,
                                                     parent_events)
        if parent_events:
            dialog = q.QDialog(
                self, qc.Qt.WindowTitleHint | qc.Qt.WindowSystemMenuHint)
            dialog.setWindowTitle('Add new event above...')
            btn_box = q.QDialogButtonBox(q.QDialogButtonBox.Ok
                                         | q.QDialogButtonBox.Cancel)
            btn_box.accepted.connect(dialog.accept)
            btn_box.rejected.connect(dialog.reject)
            dialog_layout = q.QVBoxLayout(dialog)
            dialog_layout.addWidget(
                q.QLabel(
                    'Please select links that should be modified to point to the new event you are going to add.'
                ))
            dialog_layout.addWidget(list_widget)
            dialog_layout.addWidget(btn_box)
            ret = dialog.exec_()
            if not ret:
                return

        new_parent = self.addNewEvent()
        if not new_parent:
            return

        self._doAddEventAbove(list_widget.getSelectedEvents(), event,
                              new_parent)
        self.flow_data.flowDataChanged.emit(FlowDataChangeReason.Events)
        self.delayedSelect(new_parent)

    def _doAddEventAbove(self, parents: typing.List[typing.Tuple[
        Event, typing.List[typing.Any]]], event: Event,
                         new_parent: Event) -> None:
        # Update the parents to point to the new parent.
        for parent, branches in parents:
            if isinstance(parent.data, ActionEvent) or isinstance(
                    parent.data, JoinEvent) or isinstance(
                        parent.data, SubFlowEvent):
                # Easy case: just set the next pointer to the new parent.
                parent.data.nxt.v = new_parent

            # For switch and fork events, update all branches that currently point to the event.
            elif isinstance(parent.data, SwitchEvent):
                for case in branches:
                    if parent.data.cases[case].v == event:
                        parent.data.cases[case].v = new_parent
            elif isinstance(parent.data, ForkEvent):
                for i, fork in enumerate(branches):
                    if fork.v == event:
                        parent.data.forks[i].v = new_parent