示例#1
0
class Form(QDialog):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.broswer = QTextBrowser()  # display
        self.lineedit = QLineEdit(
            "Type an expression and press Enter")  # input
        self.lineedit.selectAll()  # ctr + a
        layout = QVBoxLayout()  # a frame with 'X' and '--' and '[]'
        layout.addWidget(self.broswer)
        layout.addWidget(self.lineedit)
        self.setLayout(layout)
        self.lineedit.setFocus()
        setting = self.broswer.document()
        setting.setMaximumBlockCount(5)
        self.lineedit.returnPressed.connect(self.updateUi)
        self.setWindowTitle("Calculate")

    def updateUi(self):
        try:
            text = str(self.lineedit.text())
            self.broswer.append(
                "%s = <b>%s</b>" %
                (text, eval(text)))  # when fresh the list in broswer
            # maybe append triggle updating ui
        except Exception:
            traceback.print_exc()
            self.broswer.append("<font color=red>%s is invalid</font>" % text)
示例#2
0
class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.le = QLineEdit()
        self.le.returnPressed.connect(self.append_text)
        # 키보드에 엔터를 눌렀는지 확인해주는 이벤트
        # 엔터를 누르면 append_text를 받아와서 입력값 자동 저장

        self.tb = QTextBrowser()  #QTextBrowser() 클래스를 이용해서 텍스트 브라우저 객체 생성
        self.tb.setAcceptRichText(True)  # 서식 있는 텍스트(Rich text)를 사용할 수 있음
        # 디폴트로 True이기 때문에 없어도 되는 부분!
        self.tb.setOpenExternalLinks(True)  # 외부 링크로의 연결 가능

        self.clear_btn = QPushButton('Clear')  # 버튼을 클릭하면
        self.clear_btn.pressed.connect(self.clear_text)  # Clear_text 메소드 호출

        vbox = QVBoxLayout()  # 레이아웃 해주기 위한 vbox 객체 생성!
        vbox.addWidget(self.le, 0)  # .addWidget() 순서 정해줄 수 있음!
        vbox.addWidget(self.tb, 1)
        vbox.addWidget(self.clear_btn, 2)
        self.setLayout(vbox)
        self.setWindowTitle('QTextBrowser')
        self.setGeometry(300, 300, 300, 300)
        self.show()

    def append_text(self):
        text = self.le.text()
        self.tb.append(text)
        self.le.clear()  # 입력값 초기화 시켜주는 함수!

    def clear_text(self):
        self.tb.clear()
示例#3
0
class Form(QDialog):
    def __init__(self):  # 作为主窗口,parent = none,可省略不写
        super().__init__()  # super()方法在python3中的新写法,更简洁

        # 定义元件
        self.browser = QTextBrowser()
        self.lineedit = QLineEdit("Type an expression and press Enter")
        self.lineedit.selectAll()

        # 布局
        layout = QVBoxLayout()
        layout.addWidget(self.browser)
        layout.addWidget(self.lineedit)
        self.setLayout(layout)

        self.setWindowTitle("Calculate")
        self.lineedit.setFocus()

        # 关联信号与槽
        self.lineedit.returnPressed.connect(self.updataUi)

        # 槽函数
    def updataUi(self):
        try:
            text = str(self.lineedit.text())
            self.browser.append("%s = <b>%s</b>" % (text, eval(text)))
        except:
            self.browser.append("<font color=red>%s is invalid!</font>" % text)
示例#4
0
	def show_help(self):
		MSG = "<h3>Issues</h3> <br>" \
		      "Please report any issues to " + GITHUB + " <br> " \
		      "<br>" \
		      "<h3>Steps</h3> <br> " \
		      "<strong>Step 1:</strong> Click 'Select SBML model' and upload a valid SBML model. The file format must be xml, json, yml or mat. Wait until the application reads the input file. <br>" \
		      "<strong>Step 2:</strong> Once the read of the input file is done the application will show the model id, number of reactions, number of metabolites and number of genes. Below it will display the buttons with the avaible operations. <br>" \
		      "<strong>Step 3:</strong> Click one of the following operations: <br>" \
		      "<ul> " \
		      " <li>'Generate spreadsheet': Generates a spreadsheet file with information about the model, reactions, metabolites, genes, dead-end metabolites found, chokepoint reactions and if the models is feasible, essential reactions and essential genes data. If the model choosed is large this proccess may take a long time. Some models may cause this procedures to block the application.</li>" \
		      " <li>'Save model without dead-end metabolites': Removes the dead-end metabolitos of the model along with the associated reactions and produces a new model. </li>" \
		      " <li>'Save model updated with flux variaiblity analysis': Produces a new model with the reactions bounds updated with the values obteined running flux variability analysis on the model.</li>" \
		      " <li>'Save model updated with flux variaiblity analysis without dead-end metabolites': Produces a new model with the reactions bounds updated with the values obteined running flux variability analysis on the model. After updating the model with flux variaiblity analysis it removes the dead-end metabolites of the model.</li>" \
		      "</ul>" \
		      "<strong>Step 4:</strong> Click 'Start' <br>" \
		      "<strong>Step 5:</strong> Once the operation chosen before ends, a window will display in order to choose the destination file. If the operation was 'generate spreadsheet' the output file must be xls or ods. If the operation produces a new models the output file must be xml, json, yml or mat. <br>" \

		helpDialog = QDialog(self)  # Added
		helpDialog.setAttribute(Qt.WA_DeleteOnClose)  # Added
		browser = QTextBrowser()
		browser.append(MSG)
		layout = QVBoxLayout()
		layout.addWidget(browser)
		helpDialog.setLayout(layout)  # Added
		helpDialog.setWindowTitle("Test App - Help")  # Added for neatness
		helpDialog.show()  # Changed
class Window(QWidget):

    def __init__(self, *args, **kwargs):
        super(Window, self).__init__(*args, **kwargs)
        layout = QVBoxLayout(self)
        self.button1 = QPushButton('已连接', self, clicked=self.doTest)
        self.button2 = QPushButton('未连接', self)
        self.retView = QTextBrowser(self)
        layout.addWidget(self.button1)
        layout.addWidget(self.button2)
        layout.addWidget(self.retView)

    def doTest(self):
        self.retView.append("""
        # button1 clicked 是否连接: %s, %s
        # button2 clicked 是否连接: %s, %s
        """ % (
            self.isSignalConnected(self.button1, 'clicked()'), self.button1.receivers(self.button1.clicked) > 0,
            self.isSignalConnected(self.button2, 'clicked()'), self.button2.receivers(self.button2.clicked) > 0,
        ))

    def isSignalConnected(self, obj, name):
        """判断信号是否连接
        :param obj:        对象
        :param name:       信号名,如 clicked()
        """
        index = obj.metaObject().indexOfMethod(name)
        if index > -1:
            method = obj.metaObject().method(index)
            if method:
                return obj.isSignalConnected(method)
        return False
示例#6
0
class Form(QDialog):

    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.browser = QTextBrowser()
        self.lineedit = QLineEdit("Type an expression and press Enter")
        self.lineedit.selectAll()
        layout = QVBoxLayout()  # 垂直盒式布局
        layout.addWidget(self.browser)
        layout.addWidget(self.lineedit)
        # layout = QGridLayout() #网格布局
        # layout.addWidget(self.browser,0, 0)
        # layout.addWidget(self.lineedit,0, 0)
        self.setLayout(layout)
        self.lineedit.setFocus()
        self.connect(self.lineedit, SIGNAL("returnPressed()"), self.updateUi)  # 信号绑定到槽
        self.setWindowTitle("Calculate")

    def updateUi(self):
        try:
            text = unicode(self.lineedit.text())
            self.browser.append("%s = <b>%s</b>" % (text, eval(text)))
        except:
            self.browser.append(
                "<font color=red>%s is invalid!</font>" % text)
示例#7
0
class Form(QDialog):


    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.browser = QTextBrowser()
        self.lineedit = QLineEdit("Type an expression and press Enter")
        self.lineedit.selectAll()
        layout = QVBoxLayout()
        layout.addWidget(self.browser)
        layout.addWidget(self.lineedit)
        self.setLayout(layout)
        self.lineedit.setFocus()
        self.lineedit.returnPressed.connect(self.updateUi)
        #antes:
        #self.connect(self.lineedit, SIGNAL("returnPressed()"), self.updateUi)

        self.setWindowTitle("Calculate")

    def updateUi(self):
            try:
                text = str(self.lineedit.text())
                self.browser.append("{0} = <b>{1}</b>".format(text,
                                    eval(text)))
            except:
                self.browser.append("<font color=red>{0} is invalid!</font>"
                                    .format(text))
示例#8
0
class JSONClass(QListWidget):  #QWidget
    def __init__(self, parent=None):
        super().__init__(parent)

        self.initUI()

    def initUI(self):

        self.tb = QTextBrowser()
        self.tb.setAcceptRichText(True)
        self.tb.setOpenExternalLinks(True)

        vbox = QVBoxLayout()
        vbox.addWidget(self.tb, 1)

        self.setLayout(vbox)

        self.setWindowTitle('QTextBrowser')
        self.setGeometry(300, 300, 300, 300)
        self.show()

        self.append_text()

    def append_text(self):

        # allText = ['a', 'b', 'c', 'd', 'e']

        allText = FileList

        for i in range(0, len(allText)):
            text = allText[i]
            self.tb.append(text)
示例#9
0
 def __init__(self, title, text, image, parent=None):
     super(AboutDialog, self).__init__(parent)
     layout = QVBoxLayout()
     titleLayout = QHBoxLayout()
     name_versionLabel = QLabel(title)
     contentsLayout = QHBoxLayout()
     aboutBrowser = QTextBrowser()
     aboutBrowser.append(text)
     aboutBrowser.setOpenExternalLinks(True)
     creditsBrowser = QTextBrowser()
     creditsBrowser.append(self.contributors())
     creditsBrowser.setOpenExternalLinks(True)
     TabWidget = QTabWidget()
     TabWidget.addTab(aboutBrowser, self.tr('About'))
     TabWidget.addTab(creditsBrowser, self.tr('Contributors'))
     aboutBrowser.moveCursor(QTextCursor.Start)
     creditsBrowser.moveCursor(QTextCursor.Start)
     imageLabel = QLabel()
     imageLabel.setPixmap(QPixmap(image))
     titleLayout.addWidget(imageLabel)
     titleLayout.addWidget(name_versionLabel)
     titleLayout.addStretch()
     contentsLayout.addWidget(TabWidget)
     buttonLayout = QHBoxLayout()
     buttonBox = QDialogButtonBox(QDialogButtonBox.Ok)
     buttonLayout.addWidget(buttonBox)
     layout.addLayout(titleLayout)
     layout.addLayout(contentsLayout)
     layout.addLayout(buttonLayout)
     self.setLayout(layout)
     buttonBox.clicked.connect(self.accept)
     self.setMinimumSize(QSize(380, 400))
     self.setWindowTitle(self.tr('About Meteo-qt'))
示例#10
0
class Window(QWidget):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        model = FileListModel(self)
        model.setDirPath(QLibraryInfo.location(QLibraryInfo.PrefixPath))

        label = QLabel("Directory")
        lineEdit = QLineEdit()
        label.setBuddy(lineEdit)

        view = QListView()
        view.setModel(model)

        self.logViewer = QTextBrowser()
        self.logViewer.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred))

        lineEdit.textChanged.connect(model.setDirPath)
        lineEdit.textChanged.connect(self.logViewer.clear)
        model.numberPopulated.connect(self.updateLog)

        layout = QGridLayout()
        layout.addWidget(label, 0, 0)
        layout.addWidget(lineEdit, 0, 1)
        layout.addWidget(view, 1, 0, 1, 2)
        layout.addWidget(self.logViewer, 2, 0, 1, 2)

        self.setLayout(layout)
        self.setWindowTitle("Fetch More Example")

    def updateLog(self, number):
        self.logViewer.append("%d items added." % number)
示例#11
0
class Window(QWidget):
    # 定义一个时间信号
    timerSignal = pyqtSignal(str)

    def __init__(self, *args, **kwargs):
        super(Window, self).__init__(*args, **kwargs)
        layout = QVBoxLayout(self)
        layout.addWidget(QPushButton('Python调用qml中的函数',
                                     self, clicked=self.callQmlFunc))
        self.resultView = QTextBrowser(self)
        layout.addWidget(self.resultView)
        self._timer = QTimer(self, timeout=self.onTimeout)
        self._timer.start(2000)

    def onTimeout(self):
        # 定时器发送信号通知qml
        self.timerSignal.emit('定时器发来:' + str(time()))

    def callQmlFunc(self):
        # 主动调用qml中的appendText函数
        engine.rootObjects()[0].appendText('我是被Python调用了')

    @pyqtSlot(int)
    def onValueChanged(self, value):
        # qml中的自定义信号valueChanged所绑定的槽函数
        self.resultView.append('拉动条值: %s' % value)

    @pyqtSlot(str, result=str)  # 可以获取返回值
    def testSlot(self, name):
        # 被qml调用的函数
        self.resultView.append('我被主动调用: %s' % name)
        return str(len(name))
示例#12
0
class Window(QWidget):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        model = FileListModel(self)
        model.setDirPath(QLibraryInfo.location(QLibraryInfo.PrefixPath))

        label = QLabel("Directory")
        lineEdit = QLineEdit()
        label.setBuddy(lineEdit)

        view = QListView()
        view.setModel(model)

        self.logViewer = QTextBrowser()
        self.logViewer.setSizePolicy(
            QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred))

        lineEdit.textChanged.connect(model.setDirPath)
        lineEdit.textChanged.connect(self.logViewer.clear)
        model.numberPopulated.connect(self.updateLog)

        layout = QGridLayout()
        layout.addWidget(label, 0, 0)
        layout.addWidget(lineEdit, 0, 1)
        layout.addWidget(view, 1, 0, 1, 2)
        layout.addWidget(self.logViewer, 2, 0, 1, 2)

        self.setLayout(layout)
        self.setWindowTitle("Fetch More Example")

    def updateLog(self, number):
        self.logViewer.append("%d items added." % number)
示例#13
0
 def __init__(self, title, text, image, contributors, parent=None):
     super(AboutDialog, self).__init__(parent)
     layout = QVBoxLayout()
     titleLayout = QHBoxLayout()
     name_versionLabel = QLabel(title)
     contentsLayout = QHBoxLayout()
     aboutBrowser = QTextBrowser()
     aboutBrowser.append(text)
     aboutBrowser.setOpenExternalLinks(True)
     creditsBrowser = QTextBrowser()
     creditsBrowser.append(contributors)
     creditsBrowser.setOpenExternalLinks(True)
     TabWidget = QTabWidget()
     TabWidget.addTab(aboutBrowser, self.tr('About'))
     TabWidget.addTab(creditsBrowser, self.tr('Contributors'))
     aboutBrowser.moveCursor(QTextCursor.Start)
     creditsBrowser.moveCursor(QTextCursor.Start)
     imageLabel = QLabel()
     imageLabel.setPixmap(QPixmap(image))
     titleLayout.addWidget(imageLabel)
     titleLayout.addWidget(name_versionLabel)
     titleLayout.addStretch()
     contentsLayout.addWidget(TabWidget)
     buttonLayout = QHBoxLayout()
     buttonBox = QDialogButtonBox(QDialogButtonBox.Ok)
     buttonLayout.addWidget(buttonBox)
     layout.addLayout(titleLayout)
     layout.addLayout(contentsLayout)
     layout.addLayout(buttonLayout)
     self.setLayout(layout)
     buttonBox.clicked.connect(self.accept)
     self.setMinimumSize(QSize(380, 400))
     self.setWindowTitle(self.tr('About Onkyo QT'))
示例#14
0
class Form(QDialog):
    # 表单类的构造函数
    def __init__(self, parent=None):
        # 用super方法进行初始化
        super(Form, self).__init__(parent)
        # QTextBrowser()为只读文本框,不能对内容进行操作
        self.browser = QTextBrowser()
        # QLineEdit()单行文本框。可给定初始化文本
        self.lineedit = QLineEdit("Type an expression and <Enter>")
        # 并将文本全部选中
        self.lineedit.selectAll()
        # 调整布局
        layout = QVBoxLayout()
        layout.addWidget(self.browser)
        layout.addWidget(self.lineedit)
        # 使布局管理器获得表单部件和该表单的所有权
        self.setLayout(layout)
        # 确定光标起始位置
        self.lineedit.setFocus()
        # returnPressed:当用户在文本框内输入回车键的时候发送信号
        # connect():当特定对象发射特定信号时调用指定函数
        self.lineedit.returnPressed.connect(self.updateUi)
        self.setWindowTitle("Calculate")

    def updateUi(self):
        try:
            text = self.lineedit.text()
            self.browser.append("{0} = <b>{1}</b>".format(text, eval(text)))
        except:
            # 如果错误就将错误输出到QTextBrowser
            self.browser.append(
                "<font color=red>{0} is invalid!</font>".format(text))
示例#15
0
class App(QWidget):
    def __init__(self, room):
        super().__init__()

        vbox = QVBoxLayout()
        self.text_browser = QTextBrowser()
        vbox.addWidget(self.text_browser)
        self.text_entry = Entry(room)
        self.text_entry.setFocus()
        vbox.addWidget(self.text_entry)
        self.setLayout(vbox)

        self.messages_future = None
        self._run(room)

    def closeEvent(self, e):
        if self.messages_future:
            self.messages_future.cancel()
        super().closeEvent(e)

    def _run(self, room):
        @coroutine
        def logger():
            while True:
                message = (yield)
                self.text_browser.append(message['text'])

        self.messages_future = asyncio.ensure_future(
            room.get_messages(logger()))
示例#16
0
def showPointsCharacteristics(characteristics: dict,
                              textBrowser: QTextBrowser):
    textBrowser.clear()
    textBrowser.append(
        "АНАЛІЗ ДВОВИМІРНОГО ОБ'ЄКТУ\n \t\t\t|---Точкові статистичні оцінки---|\n"
    )
    textBrowser.append(getPointCharacteristicsTable(characteristics))
示例#17
0
class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.le = QLineEdit()
        self.le.returnPressed.connect(self.append_text)

        self.tb = QTextBrowser()
        self.tb.setAcceptRichText(True)
        self.tb.setOpenExternalLinks(True)

        self.clear_btn = QPushButton('Clear')
        self.clear_btn.pressed.connect(self.clear_text)

        vbox = QVBoxLayout()
        vbox.addWidget(self.le, 0)
        vbox.addWidget(self.tb, 1)
        vbox.addWidget(self.clear_btn, 2)

        self.setLayout(vbox)

        self.setWindowTitle('QTextBrowser')
        self.setGeometry(300, 300, 300, 300)
        self.show()

    def append_text(self):
        text = self.le.text()
        self.tb.append(text)
        self.le.clear()

    def clear_text(self):
        self.tb.clear()
示例#18
0
class Example(QDialog):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):
        self.lineedit = QLineEdit()
        okButton = QPushButton('OK')
        hb = QHBoxLayout()
        hb.addStretch(1)
        hb.addWidget(self.lineedit)
        hb.addWidget(okButton)

        self.textbrowser = QTextBrowser()
        vb = QVBoxLayout()
        vb.addStretch(1)
        vb.addWidget(self.textbrowser)
        vb.addLayout(hb)
        self.setLayout(vb)

        okButton.clicked.connect(self.updateUI)

        self.setWindowTitle("Execute")
        self.setGeometry(300, 300, 300, 300)

    def updateUI(self):
        try:
            text = self.lineedit.text()
            self.textbrowser.append("%s = <b>%s</b>" % (text, eval(text)))
        except:
            self.textbrowser.append("error!")
示例#19
0
class LogView(QWidget):
    def __init__(self):
        super().__init__()

        self.browser = QTextBrowser()
        self.browser.setPlaceholderText('程序运行日志')

        self.clear_btn = QPushButton('清空')
        self.clear_btn.clicked.connect(lambda: self.browser.setText(''))

        self.v_layout = QVBoxLayout()
        self.v_layout.addWidget(self.browser)
        self.v_layout.addWidget(self.clear_btn)

        self.resize(600, 425)
        self.setLayout(self.v_layout)
        self.center()
        self.setWindowTitle(Const.project_name)
        self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)

    def info(self, text: str):
        self.browser.append(text)

    def center(self):
        """
        居中窗口
        """
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())
示例#20
0
    def __init__(self, parent):
        QWidget.__init__(self)
        self.ctrl = QApplication.instance().ctrl
        self.parent = parent
        self.setWindowTitle("About")
        hbox = QHBoxLayout()
        pic = QLabel(self)
        pix = QPixmap(
            os.path.join(self.ctrl.application_home, 'conf/img/logo_h.png'))
        pic.setPixmap(pix)
        hbox.addWidget(pic)

        vbox = QVBoxLayout()

        lbl_title = QLabel("Metadata Publishing Tool", self)
        lbl_title.setMinimumWidth(400)
        font = QFont()
        font.setPointSize(20)
        font.setBold(True)
        lbl_title.setFont(font)
        lbl_title.setContentsMargins(2, 5, 5, 7)
        lbl_title.setStyleSheet(Style.h2())
        vbox.addWidget(lbl_title)
        #vbox.addSpacing(20)
        vbox.addStretch(1)

        grid = QGridLayout()
        grid.setContentsMargins(0, 0, 0, 0)  # left, top, right, bottom
        grid.setVerticalSpacing(2)
        grid.setHorizontalSpacing(2)

        grid.addWidget(QLabel("Version: "), 1, 1)
        grid.addWidget(QLabel(version.__version__), 1, 2)

        grid.addWidget(QLabel("Release: "), 2, 1)
        grid.addWidget(QLabel(version.__release_date__), 2, 2)

        hbox_grid = QHBoxLayout()
        hbox_grid.addLayout(grid)
        hbox_grid.addStretch(1)
        vbox.addLayout(hbox_grid)

        vbox.addSpacing(10)
        txt = QTextBrowser()
        txt.setMinimumHeight(250)
        txt.setOpenExternalLinks(True)
        txt.setOpenLinks(False)
        txt.anchorClicked.connect(self.on_anchor_clicked)
        txt.append(version.__about__)
        vbox.addWidget(txt)

        hbox.addLayout(vbox)
        hbox.addStretch(1)
        self.setLayout(hbox)
        self.move(200, 200)
        self.setWindowFlags((self.windowFlags() | Qt.CustomizeWindowHint)
                            & ~Qt.WindowMaximizeButtonHint
                            & ~Qt.WindowMinimizeButtonHint)
        self.show()
示例#21
0
class MyApp(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        self.le = QLineEdit()
        self.le.setPlaceholderText('기본 값 유윈스 학사공')
        self.le.returnPressed.connect(self.get_url_subject)

        self.btn = QPushButton('Start')
        self.btn.clicked.connect(self.get_url_subject)

        self.lbl = QLabel('과를 입력하세요.')

        self.tb = QTextBrowser()
        self.tb.setAcceptRichText(True)
        self.tb.setOpenExternalLinks(True)

        grid = QGridLayout()
        grid.addWidget(self.le, 0, 0, 1, 3)
        grid.addWidget(self.btn, 0, 3, 1, 1)
        grid.addWidget(self.lbl, 1, 0, 1, 4)
        grid.addWidget(self.tb, 2, 0, 1, 4)

        self.setLayout(grid)

        self.setWindowTitle('Web Crawler')
        self.setGeometry(100, 100, 450, 650)
        self.show()

    def get_url_subject(self):
        urls = []
        subjects = []

        major = self.le.text()
        if not major:
            self.lbl.setText('학사 공지사항입니다.')
            self.tb.clear()
            req = requests.get(
                'https://uwins.ulsan.ac.kr/JBGJ/B/MIB01S.aspx?MenuID=MIB01S!1')
            html = req.text
            soup = BeautifulSoup(html, 'html.parser')
            id_links = soup.select('td:nth-child(1)')
            subject_links = soup.select('td.textWrap.Left')
            for id_link in id_links:
                id = id_link.text.strip()
                url = 'https://uwins.ulsan.ac.kr/JBGJ/B/MIB02S.aspx?MenuID=MIB01S!1&board_gb=A38002&seq=' + id + '&Grade=3&current_page=1'
                urls.append(url)

            for subject_link in subject_links:
                subject = subject_link.text.strip()
                subjects.append(subject)
            for i in range(10):
                self.tb.append(
                    str(i + 1) + '. ' + subjects[i] + ' (' + '<a href="' +
                    urls[i] + '">링크</a>' + ')')
示例#22
0
文件: HotKey.py 项目: zyj0021200/PyQt
class Window(QWidget):

    KeyIds = {}

    def __init__(self, *args, **kwargs):
        super(Window, self).__init__(*args, **kwargs)
        layout = QVBoxLayout(self)
        self.logView = QTextBrowser(self)
        self.logView.append("点击右上角关闭按钮会隐藏窗口,通过热键Alt+S来显示")
        self.logView.append("等待热键中")
        layout.addWidget(QPushButton("退出整个程序", self, clicked=self.onQuit))
        layout.addWidget(self.logView)

    def unregisterHotKey(self, kid):
        ctypes.windll.user32.UnregisterHotKey(ctypes.c_int(self.winId()), kid)

    def registerHotKey(self, kid, modifier, key):
        key = str(key).upper()
        _modifier = Modifier.get(modifier, None)
        if not _modifier:
            return QMessageBox.critical(self, "错误",
                                        "modifier key {0}未找到".format(modifier))
        success = ctypes.windll.user32.RegisterHotKey(
            ctypes.c_int(self.winId()), kid, _modifier, ord(key))
        if success:
            self.KeyIds[kid] = modifier + "+" + key
            self.logView.append("热键:{0}+{1}注册{2}".format(modifier, key, "成功"))
        else:
            self.logView.append("热键:{0}+{1}注册{2}".format(modifier, key, "失败"))

    def onQuit(self):
        # 退出程序
        for kid in self.KeyIds:
            self.unregisterHotKey(kid)
        QApplication.instance().quit()

    def closeEvent(self, event):
        # 忽略关闭窗口,直接隐藏
        self.hide()
        return event.ignore()

    # 能监听热键,但是有个问题就是其它程序无法接受到事件
    # 比如Ctrl+S,在记事本里随便输入内容按下Ctrl+S发现无法保存
    def nativeEvent(self, eventType, message):
        if eventType == "windows_generic_MSG" or eventType == "windows_dispatcher_MSG":
            msg = ctypes.wintypes.MSG.from_address(message.__int__())
            # 这段代码无法运行
            # if ctypes.windll.user32.GetMessageA(ctypes.byref(msg), None, 0,
            # 0) != 0:
            if msg.message == WM_HOTKEY:
                if msg.wParam == 1:  # Alt+S
                    self.show()
                self.logView.append("id:{0}, {1} at time:{2}".format(
                    msg.wParam, self.KeyIds.get(msg.wParam, None),
                    datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
                return True, 0
        return super(Window, self).nativeEvent(eventType, message)
class MyApp(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        self.le = QLineEdit()
        self.le.setPlaceholderText('기본 값 유윈스 학사공')
        self.le.returnPressed.connect(self.ulsan_urls_subjects)

        self.btn = QPushButton('Start')
        self.btn.clicked.connect(self.ulsan_urls_subjects)

        self.lbl = QLabel('과를 입력하세요.')

        self.tb = QTextBrowser()
        self.tb.setAcceptRichText(True)
        self.tb.setOpenExternalLinks(True)

        grid = QGridLayout()
        grid.addWidget(self.le, 0, 0, 1, 3)
        grid.addWidget(self.btn, 0, 3, 1, 1)
        grid.addWidget(self.lbl, 1, 0, 1, 4)
        grid.addWidget(self.tb, 2, 0, 1, 4)

        self.setLayout(grid)

        self.setWindowTitle('Web Crawler')
        self.setGeometry(100, 100, 450, 650)
        self.show()
    def ulsan_urls_subjects(self):
        ulsan_urls = []
        ulsan_subjects = []
        ulsan_
        major = self.le.text()
        if not major:
            self.lbl.setText('울산대 홈페이지 공지사항입니다.')
            self.tb.clear()
            req = requests.get('http://www.ulsan.ac.kr/unews/news/notice.aspx?o=L')
            html = req.text
            soup = BeautifulSoup(html, 'html.parser')
            id_links = soup.select('tr > td.no')
            subject_links = soup.select('tr > td.title')
            for id_link in id_links:
                id = id_link.text.strip()
                url = 'http://www.ulsan.ac.kr/unews/news/notice.aspx?o=R&a_no='+str(int(id)+2468)
                urls.append(url)
            for subject_link in subject_links:
                subject = subject_link.text.strip()
                subjects.append(subject)
            for i in range(10):
                self.tb.append(str(i + 1) + '. ' + subjects[i] + ' (' + '<a href="' + urls[i] + '">링크</a>' + ')')
示例#24
0
class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.le = QLineEdit()
        self.le.returnPressed.connect(self.append_text)

        self.tb = QTextBrowser()
        self.tb.setAcceptRichText(True)
        self.tb.setOpenExternalLinks(True)

        self.clear_btn = QPushButton('Clear')
        self.clear_btn.pressed.connect(self.clear_text)

        self.lbl1 = QLabel('Enter your sentence:')
        self.te = QTextEdit()
        self.te.setAcceptRichText(False)
        self.lbl2 = QLabel('The number of words is 0')

        self.te.textChanged.connect(self.text_changed)

        layout = QHBoxLayout()
        vbox1 = QVBoxLayout()
        vbox1.addWidget(self.lbl1)
        vbox1.addWidget(self.te)
        vbox1.addWidget(self.lbl2)
        vbox1.addStretch()

        vbox = QVBoxLayout()
        vbox.addWidget(self.le, 0)
        vbox.addWidget(self.tb, 1)
        vbox.addWidget(self.clear_btn, 2)
        layout.addLayout(vbox)
        layout.addLayout(vbox1)

        self.setLayout(layout)

        self.setWindowTitle('으에에ㅔ')
        self.setGeometry(300, 300, 700, 800)
        self.show()

    def append_text(self):
        text = self.le.text()
        self.tb.append(text)
        self.le.clear()

    def clear_text(self):
        self.tb.clear()

    def text_changed(self):
        text = self.te.toPlainText()
        self.lbl2.setText('The number of words is ' + str(len(text.split())))
示例#25
0
class MyApp(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        # self.le = QLineEdit()
        # self.le.returnPressed.connect(self.append_text)

        self.tb = QTextBrowser()
        self.tb.setAcceptRichText(True)
        self.tb.setOpenExternalLinks(True)

        # self.clear_btn = QPushButton('Clear')
        # self.clear_btn.pressed.connect(self.clear_text)

        vbox = QVBoxLayout()
        # vbox.addWidget(self.le, 0)
        vbox.addWidget(self.tb, 1)
        # vbox.addWidget(self.clear_btn, 2)

        self.setLayout(vbox)

        self.setWindowTitle('QTextBrowser')
        self.setGeometry(300, 300, 300, 300)
        self.show()

        self.append_text()

    def append_text(self):

        allText = ['a', 'b', 'c', 'd', 'e']

        # text = self.le.text()

        for i in range(0, len(allText)):
            text = allText[i]
            # self.i = self.i + 1
            self.tb.append(text)

        # self.le.clear()

    # def clear_text(self):
    #
    #     self.tb.clear()


# if __name__ == '__main__':
#
#     app = QApplication(sys.argv)
#     ex = MyApp()
#     sys.exit(app.exec_())
class QTextEditLogger(logging.Handler):
    def __init__(self, parent):
        super().__init__()
        self.widget = QTextBrowser(parent)

    def emit(self, record):
        msg = self.format(record)
        self.widget.append(msg)
        with open('log.log', 'a') as f:
            f.write(msg+"\n")
        f.close()
示例#27
0
class MyApp(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        self.le = QLineEdit()
        self.le.setPlaceholderText('yymmdd')
        self.le.returnPressed.connect(self.crawl_news)

        self.btn = QPushButton('Start')
        self.btn.clicked.connect(self.crawl_news)

        self.lbl = QLabel('날짜를 입력하세요.')

        self.tb = QTextBrowser()
        self.tb.setAcceptRichText(True)
        self.tb.setOpenExternalLinks(True)

        grid = QGridLayout()
        grid.addWidget(self.le, 0, 0, 1, 3)
        grid.addWidget(self.btn, 0, 3, 1, 1)
        grid.addWidget(self.lbl, 1, 0, 1, 4)
        grid.addWidget(self.tb, 2, 0, 1, 4)

        self.setLayout(grid)

        self.setWindowTitle('Web Crawler')
        self.setGeometry(100, 100, 450, 650)
        self.show()

    def crawl_news(self):
        date = self.le.text()

        if date:
            self.lbl.setText('[20' + str(date) + '] 많이 본 뉴스입니다.')
            self.tb.clear()
            url_news = 'https://news.naver.com'
            url = url_news + '/main/ranking/popularDay.nhn?rankingType=popular_day&date=20' + date
            r = requests.get(url)
            html = r.content
            soup = BeautifulSoup(html, 'html.parser')
            titles_html = soup.select(
                '.ranking_section > ol > li > dl > dt > a')

            for i in range(len(titles_html)):
                title = titles_html[i].text
                link = url_news + titles_html[i].get('href')
                self.tb.append(
                    str(i + 1) + '. ' + title + ' (' + '<a href="' + link +
                    '">링크</a>' + ')')
示例#28
0
 def set_type_combo(self):
     txt = QTextBrowser(self)
     txt.append('请选择烟花类型:')
     txt.resize(230, 30)
     txt.move(10, 0)
     self.type_combo = QComboBox(self, minimumWidth=100)
     self.type_combo.addItem('球状烟花', FireworkType.Normal)
     self.type_combo.addItem('两次爆炸', FireworkType.MultiExplosion)
     self.type_combo.addItem('两个球状混合', FireworkType.DualMixture)
     self.type_combo.setCurrentIndex(-1)
     self.type_combo.resize(self.type_combo.sizeHint())
     self.type_combo.move(110, 5)
示例#29
0
class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.le = QLineEdit()
        self.le.returnPressed.connect(self.append_text)
        # 줄편집기 하나를 만들었습니다.
        #
        # Enter키를 누르면 append_text 메서드가 호출됩니다.

        self.tb = QTextBrowser()
        self.tb.setAcceptRichText(True)
        self.tb.setOpenExternalLinks(True)
        # QTextBrowser() 클래스를 이용해서 텍스트 브라우저를 하나 만들었습니다.
        #
        # setAcceptRichText()를 True로 설정해주면, 서식 있는 텍스트
        # (Rich text)를 사용할 수 있습니다.
        #
        # 디폴트로 True이기 때문에 없어도 되는 부분입니다.
        #
        # setOpenExternalLinks()를 True로 설정해주면, 외부 링크로의 연결이 가능합니다.

        self.clear_btn = QPushButton('Clear')
        self.clear_btn.pressed.connect(self.clear_text)
        # clear_btn을 클릭하면, clear_text 메서드가 호출됩니다.

        vbox = QVBoxLayout()
        vbox.addWidget(self.le, 0)
        vbox.addWidget(self.tb, 1)
        vbox.addWidget(self.clear_btn, 2)

        self.setLayout(vbox)

        self.setWindowTitle('QTextBrowser')
        self.setGeometry(300, 300, 300, 300)
        self.show()

    def append_text(self):
        text = self.le.text()
        self.tb.append(text)
        self.le.clear()
        # append_text 메서드는 줄편집기에 작성된 텍스트
        # (self.le.text())를 텍스트 브라우저 (self.tb)에 append 해주는 기능을 합니다.
        #
        # 텍스트가 텍스트 브라우저에 추가되면, clear 메서드를 이용해서 줄편집기에 있던
        # 텍스트는 없애줍니다.

    def clear_text(self):
        self.tb.clear()
示例#30
0
class DebugInfo(QDockWidget):
    def __init__(self, parent=None):
        super(DebugInfo, self).__init__()
        self.head_info = None

        self.setWindowTitle('日志')
        self.setFeatures(QDockWidget.NoDockWidgetFeatures
                         | QDockWidget.DockWidgetMovable
                         | QDockWidget.DockWidgetFloatable)
        self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)

        self.dock_widget_contents = QWidget()
        self.setWidget(self.dock_widget_contents)

        self.info_text_browser = QTextBrowser(self.dock_widget_contents)
        self.info_text_browser.setReadOnly(True)

        self.horizontal_spacer = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                             QSizePolicy.Minimum)
        self.clear_button = QPushButton("清除记录", self.dock_widget_contents)

        self.hLayout = QHBoxLayout()
        self.hLayout.addItem(self.horizontal_spacer)
        self.hLayout.addWidget(self.clear_button)

        self.vLayout = QVBoxLayout(self.dock_widget_contents)
        self.vLayout.setSpacing(4)
        self.vLayout.setContentsMargins(4, 4, 4, 4)
        self.vLayout.addWidget(self.info_text_browser)
        self.vLayout.addLayout(self.hLayout)

        self.clear_button.clicked.connect(self.clear)

        # self.dock_widget_contents.setMinimumWidth(300)

    def set_head_info(self, head_info):
        self.head_info = head_info
        self.clear()

    def set_text_browser(self, text_info):
        pass

    def clear(self):
        self.info_text_browser.clear()
        if self.head_info is not None:
            self.info_text_browser.append(self.head_info)
            h = self.height()
            w = self.width()
            self.resize(w, 10)
            self.resize(w, h)
示例#31
0
class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.icon = dir_icon + 'icon_qt.png'
        self.title = 'Ex5.19_QTextBrowser'
        self.posXY = (600, 45)
        self.windowSize = (300, 300)
        self.initUI()
        self.showBasic()

    def initUI(self):
        lb1 = QLabel('TEXT HISTORY :')
        lb2 = QLabel('TYPE & ENTER to Store ABOVE!')

        self.le = QLineEdit()
        self.le.returnPressed.connect(self.append_text)

        self.tb = QTextBrowser()
        self.tb.setAcceptRichText(True)
        self.tb.setOpenExternalLinks(True)

        clear_btn = QPushButton('Clear')
        clear_btn.pressed.connect(self.clear_text)

        vbox = QVBoxLayout()
        vbox.addWidget(lb1)
        vbox.addWidget(self.tb, 1)
        vbox.addWidget(lb2)
        vbox.addWidget(self.le, 0)
        vbox.addWidget(clear_btn, 2)

        self.setLayout(vbox)

    def showBasic(self):
        """Basci Attribution & Geometry display"""
        self.setWindowIcon(QIcon(self.icon))
        self.setWindowTitle(self.title)
        self.setGeometry(*self.posXY, *self.windowSize)
        self.show()

    def append_text(self):
        """CallBack() When le.returnPressed.connect"""
        text = self.le.text()
        self.tb.append(text)
        self.le.clear()

    def clear_text(self):
        """CallBack() When clear_btn.pressed.connect"""
        self.tb.clear()
示例#32
0
class SummaryWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__()
        self.parent = parent
        self.setWindowTitle(self.tr("Installation Information"))
        self.setLayout(QVBoxLayout())

        label1 = QLabel()
        label1.setText(self.tr("<h3>Take a look at the summary of your choices for the installation.</h3>"))
        self.layout().addWidget(label1)

        label2 = QLabel()
        label2.setText(self.tr("<h1>System Location</h1>"))
        self.layout().addWidget(label2)

        self.textbrowser1 = QTextBrowser()
        self.layout().addWidget(self.textbrowser1)

        label3 = QLabel()
        label3.setText(self.tr("<h1>Keyboard Layout</h1>"))
        self.layout().addWidget(label3)

        self.textbrowser2 = QTextBrowser()
        self.layout().addWidget(self.textbrowser2)

        label4 = QLabel()
        label4.setText(self.tr("<h1>Disk Partition</h1>"))
        self.layout().addWidget(label4)

        self.textbrowser3 = QTextBrowser()
        self.layout().addWidget(self.textbrowser3)

    def showEvent(self, event):
        self.textbrowser1.setText(self.tr("System time will be set to {}.\nSystem language will be set to {}.")
                                  .format(self.parent.lilii_settings["timezone"], self.parent.lilii_settings["lang"]))

        variant = None
        if self.parent.lilii_settings["keyboard_variant"] != None:
            variant = self.parent.lilii_settings["keyboard_variant"][-1]
        else:
            variant = "Default"

        self.textbrowser2.setText(self.tr("Keyboard model is choosen as {}.\nKeyboard kind is choosen as {}/{}.")
                                  .format(self.parent.lilii_settings["keyboard_model"][-1],
                                          self.parent.lilii_settings["keyboard_layout"][-1], variant))

        self.textbrowser3.clear()
        if self.parent.lilii_settings["/"]:
            self.textbrowser3.append(self.tr("Root directory is {}.").format(self.parent.lilii_settings["/"]))

        if self.parent.lilii_settings["/home"]:
            self.textbrowser3.append(self.tr("Home directory is {}.").format(self.parent.lilii_settings["/home"]))

        if is_efi() and self.parent.lilii_settings["/boot/efi"]:
            self.textbrowser3.append(self.tr("Bootloader installation directory is {}.").format(self.parent.lilii_settings["/boot/efi"]))

        else:
            self.textbrowser3.append(self.tr("Bootloader installation disk: {}").format(self.parent.lilii_settings["bootloader"]))
示例#33
0
class ContactWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.getContactText()

    def initUI(self):
        self.textbox_contact_1 = QTextBrowser()
        layout = QHBoxLayout()
        layout.addWidget(self.textbox_contact_1)
        self.setLayout(layout)

    def getContactText(self):
        f = open("contact.txt", mode="r", encoding="utf-8")
        for line in f:
            self.textbox_contact_1.append(line)
示例#34
0
class Form(QDialog):
	def __init__(self,parent=None):
		super(Form,self).__init__(parent)
		self.browser = QTextBrowser()
		self.browser.setFont(QFont("Consolas",12,QFont.StyleItalic))
		self.lineedit = QLineEdit('Type an express and press Enter')
		self.lineedit.selectAll()
		layout = QVBoxLayout()
		layout.addWidget(self.browser)
		layout.addWidget(self.lineedit)
		self.setLayout(layout)
		self.lineedit.setFocus()
		# self.connect(self.lineedit,SIGNAL('returnPressed()'),self.updateUi)
		self.lineedit.returnPressed.connect(self.updateUi)
		self.setWindowTitle('Calculate')
	def updateUi(self):
		try:
			text = self.lineedit.text()
			self.browser.append('%s = %s' % (text, eval(text)))
		except:
			self.browser.append('%s is invalid!' % text)
示例#35
0
class AboutDialog(QDialog):
    def __init__(self, title="Test", message="Test Text"):
        super(AboutDialog, self).__init__()

        self.title = title
        self.message = message

        self.initUI()

    def initUI(self):
        """
        initUI()
        """

        vbox = QVBoxLayout(self)
        grid1 = QGridLayout()
        grid1.setSpacing(10)

        self.text = QTextBrowser()
        self.text.setReadOnly(True)
        self.text.setOpenExternalLinks(True)
        self.text.append(self.message)
        self.text.moveCursor(QTextCursor.Start)
        self.text.ensureCursorVisible()

        vbox.addWidget(self.text)

        self.setLayout(vbox)
        self.setMinimumSize(550, 450)
        self.resize(550, 600)
        self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint)
        self.setWindowTitle(self.title)
        iconWT = QIcon()
        iconWT.addPixmap(QPixmap(":images/DXF2GCODE-001.ico"),
                         QIcon.Normal, QIcon.Off)
        self.setWindowIcon(QIcon(iconWT))

        self.exec_()
示例#36
0
class Dialog(QDialog):
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)
        
        self._info = None
        self._text = ''
        self._convertedtext = ''
        self._encoding = None
        self.mainwindow = parent
        
        self.fromVersionLabel = QLabel()
        self.fromVersion = QLineEdit()
        self.reason = QLabel()
        self.toVersionLabel = QLabel()
        self.toVersion = QLineEdit()
        self.lilyChooser = lilychooser.LilyChooser()
        self.messages = QTextBrowser()
        self.diff = QTextBrowser(lineWrapMode=QTextBrowser.NoWrap)
        self.uni_diff = QTextBrowser(lineWrapMode=QTextBrowser.NoWrap)
        self.copyCheck = QCheckBox(checked=
            QSettings().value('convert_ly/copy_messages', True, bool))
        self.tabw = QTabWidget()
        
        self.tabw.addTab(self.messages, '')
        self.tabw.addTab(self.diff, '')
        self.tabw.addTab(self.uni_diff, '')
        
        self.buttons = QDialogButtonBox(
            QDialogButtonBox.Reset | QDialogButtonBox.Save |
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.buttons.button(QDialogButtonBox.Ok).clicked    .connect(self.accept)
        self.buttons.rejected.connect(self.reject)
        self.buttons.button(QDialogButtonBox.Reset).clicked.connect(self.run)
        self.buttons.button(QDialogButtonBox.Save).clicked.connect(self.saveFile)
        
        layout = QVBoxLayout()
        self.setLayout(layout)
        
        grid = QGridLayout()
        grid.addWidget(self.fromVersionLabel, 0, 0)
        grid.addWidget(self.fromVersion, 0, 1)
        grid.addWidget(self.reason, 0, 2, 1, 3)
        grid.addWidget(self.toVersionLabel, 1, 0)
        grid.addWidget(self.toVersion, 1, 1)
        grid.addWidget(self.lilyChooser, 1, 3, 1, 2)
        
        layout.addLayout(grid)
        layout.addWidget(self.tabw)
        layout.addWidget(self.copyCheck)
        layout.addWidget(widgets.Separator())
        layout.addWidget(self.buttons)
        
        app.translateUI(self)
        qutil.saveDialogSize(self, 'convert_ly/dialog/size', QSize(600, 300))
        app.settingsChanged.connect(self.readSettings)
        self.readSettings()
        self.finished.connect(self.saveCopyCheckSetting)
        self.lilyChooser.currentIndexChanged.connect(self.slotLilyPondVersionChanged)
        self.slotLilyPondVersionChanged()
        
    def translateUI(self):
        self.fromVersionLabel.setText(_("From version:"))
        self.toVersionLabel.setText(_("To version:"))
        self.copyCheck.setText(_("Save convert-ly messages in document"))
        self.copyCheck.setToolTip(_(
            "If checked, the messages of convert-ly are appended as a "
            "comment to the end of the document."))
        self.tabw.setTabText(0, _("&Messages"))
        self.tabw.setTabText(1, _("&Changes"))
        self.tabw.setTabText(2, _("&Diff"))
        self.buttons.button(QDialogButtonBox.Reset).setText(_("Run Again"))
        self.buttons.button(QDialogButtonBox.Save).setText(_("Save as file"))
        self.setCaption()
    
    def saveCopyCheckSetting(self):
        QSettings().setValue('convert_ly/copy_messages', self.copyCheck.isChecked())
    
    def readSettings(self):
        font = textformats.formatData('editor').font
        self.diff.setFont(font)
        diffFont = QFont("Monospace")
        diffFont.setStyleHint(QFont.TypeWriter)
        self.uni_diff.setFont(diffFont)
    
    def slotLilyPondVersionChanged(self):
        self.setLilyPondInfo(self.lilyChooser.lilyPondInfo())
    
    def setCaption(self):
        version = self._info and self._info.versionString() or _("<unknown>")
        title = _("Convert-ly from LilyPond {version}").format(version=version)
        self.setWindowTitle(app.caption(title))

    def setLilyPondInfo(self, info):
        self._info = info
        self.setCaption()
        self.toVersion.setText(info.versionString())
        self.setConvertedText()
        self.setDiffText()
        self.messages.clear()
    
    def setConvertedText(self, text=''):
        self._convertedtext = text
        self.buttons.button(QDialogButtonBox.Ok).setEnabled(bool(text))
        if text:
            self.diff.setHtml(htmldiff.htmldiff(
                self._text, text,
                _("Current Document"), _("Converted Document"),
                wrapcolumn=100))
        else:
            self.diff.clear()
            
    def setDiffText(self, text=''):
        if text:
            from_filename = "current"   # TODO: maybe use real filename here
            to_filename = "converted"   # but difflib can choke on non-ascii characters,
                                        # see https://github.com/wbsoft/frescobaldi/issues/674
            difflist = list(difflib.unified_diff(
                    self._text.split('\n'), text.split('\n'), 
                    from_filename, to_filename))
            diffHLstr = self.diffHighl(difflist)
            self.uni_diff.setHtml(diffHLstr)
        else:
            self.uni_diff.clear()
    
    def convertedText(self):
        return self._convertedtext or ''
    
    def setDocument(self, doc):
        v = documentinfo.docinfo(doc).version_string()
        if v:
            self.fromVersion.setText(v)
            self.reason.setText(_("(set in document)"))
        else:
            self.reason.clear()
        self._text = doc.toPlainText()
        self._encoding = doc.encoding() or 'UTF-8'
        self.setConvertedText()
        self.setDiffText()
        
    def run(self):
        """Runs convert-ly (again)."""
        fromVersion = self.fromVersion.text()
        toVersion = self.toVersion.text()
        if not fromVersion or not toVersion:
            self.messages.setPlainText(_(
                "Both 'from' and 'to' versions need to be set."))
            return
        info = self._info
        command = info.toolcommand(info.ly_tool('convert-ly'))
        command += ['-f', fromVersion, '-t', toVersion, '-']
        
        # if the user wants english messages, do it also here: LANGUAGE=C
        env = None
        if os.name == "nt":
            # Python 2.7 subprocess on Windows chokes on unicode in env
            env = util.bytes_environ()
        else:
            env = dict(os.environ)
        if sys.platform.startswith('darwin'):
            try:
                del env['PYTHONHOME']
            except KeyError:
                pass
            try:
                del env['PYTHONPATH']
            except KeyError:
                pass
        if QSettings().value("lilypond_settings/no_translation", False, bool):
            if os.name == "nt":
                # Python 2.7 subprocess on Windows chokes on unicode in env
                env[b'LANGUAGE'] = b'C'
            else:
                env['LANGUAGE'] = 'C'
        
        with qutil.busyCursor():
            try:
                proc = subprocess.Popen(command,
                    env = env,
                    stdin = subprocess.PIPE,
                    stdout = subprocess.PIPE,
                    stderr = subprocess.PIPE)
                out, err = proc.communicate(util.platform_newlines(self._text).encode(self._encoding))
            except OSError as e:
                self.messages.setPlainText(_(
                    "Could not start {convert_ly}:\n\n"
                    "{message}\n").format(convert_ly = command[0], message = e))
                return
            out = util.universal_newlines(out.decode('UTF-8'))
            err = util.universal_newlines(err.decode('UTF-8'))
            self.messages.setPlainText(err)
            self.setConvertedText(out)
            self.setDiffText(out)
            if not out or self._convertedtext == self._text:
                self.messages.append('\n' + _("The document has not been changed."))

    def saveFile(self):
        """Save content in tab as file"""
        tabdata = self.getTabData(self.tabw.currentIndex())
        doc = self.mainwindow.currentDocument()
        orgname = doc.url().toLocalFile()
        filename = os.path.splitext(orgname)[0] + '['+tabdata.filename+']'+'.'+tabdata.ext
        caption = app.caption(_("dialog title", "Save File"))
        filetypes = '{0} (*.txt);;{1} (*.htm);;{2} (*)'.format(_("Text Files"), _("HTML Files"), _("All Files"))
        filename = QFileDialog.getSaveFileName(self.mainwindow, caption, filename, filetypes)[0]
        if not filename:
            return False # cancelled
        with open(filename, 'wb') as f:
            f.write(tabdata.text.encode('utf-8'))

    def getTabData(self, index):
        """Get content of current tab from current index"""
        if index == 0:
            return FileInfo('message', 'txt', self.messages.toPlainText())
        elif index == 1:
            return FileInfo('html-diff', 'html', self.diff.toHtml())
        elif index == 2:
            return FileInfo('uni-diff', 'diff', self.uni_diff.toPlainText())
            
    def diffHighl(self, difflist):
        """Return highlighted version of input."""
        result = []
        for l in difflist:
            if l.startswith('-'):
                s = '<span style="color: red; white-space: pre-wrap;">'
            elif l.startswith('+'):
                s = '<span style="color: green; white-space: pre-wrap;">'
            else:
                s = '<span style="white-space: pre-wrap;">'
            h = l.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
            result.append(s + h + '</span>')
        return '<br>'.join(result)
示例#37
0
    def onAbout(self, widget):
        dialog = QDialog(self)
        aboutText = self.tr("""<p>A simple applet for enable/disable webcams.</p>
            <p>Website: <a href="https://github.com/abbarrasa/openbox">
            https://github.com/abbarrasa/openbox</a></p>
            <p>Based in <a href="https://extensions.gnome.org/extension/1477/webcam-manager/">Webcam Manager</a>.</p>
            <p>If you want to report a dysfunction or a suggestion,
            feel free to open an issue in <a href="https://github.com/abbarrasa/openbox/issues">
            github</a>.""")
        creditsText = self.tr("""(c) 2018 Alberto Buitrago <%s>""") % base64.b64decode('YWJiYXJyYXNhQGdtYWlsLmNvbQ==').decode('utf-8')
        licenseText = self.tr("""<p>This program is free software: you
            can redistribute it and/or modify it under the terms of the
            GNU General Public License as published by the Free Software
            Foundation, either version 3 of the License, or (at your
            option) any later version.</p>
            <p>This program is distributed in the hope that it will be
            useful, but WITHOUT ANY WARRANTY; without even the implied
            warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
            PURPOSE. See the GNU General Public License for more
            details.</p>
            <p>You should have received a copy of the GNU General Public
            License along with this program. If not, see
            <a href="https://www.gnu.org/licenses/gpl-3.0.html">
            GNU General Public License version 3</a>.</p>""")
        layout = QVBoxLayout()
        titleLayout = QHBoxLayout()
        titleLabel = QLabel('<font size="4"><b>{0} {1}</b></font>'.format('Webcam Manager', VERSION))

        contentsLayout = QHBoxLayout()
        aboutBrowser = QTextBrowser()
        aboutBrowser.append(aboutText)
        aboutBrowser.setOpenExternalLinks(True)

        creditsBrowser = QTextBrowser()
        creditsBrowser.append(creditsText)
        creditsBrowser.setOpenExternalLinks(True)

        licenseBrowser = QTextBrowser()
        licenseBrowser.append(licenseText)
        licenseBrowser.setOpenExternalLinks(True)

        TabWidget = QTabWidget()
        TabWidget.addTab(aboutBrowser, self.tr('About'))
        TabWidget.addTab(creditsBrowser, self.tr('Contributors'))
        TabWidget.addTab(licenseBrowser, self.tr('License'))

        aboutBrowser.moveCursor(QTextCursor.Start)
        creditsBrowser.moveCursor(QTextCursor.Start)
        licenseBrowser.moveCursor(QTextCursor.Start)

        icon = QIcon.fromTheme('camera-web')
        pixmap = icon.pixmap(QSize(64, 64))
        imageLabel = QLabel()
        imageLabel.setPixmap(pixmap)
        titleLayout.addWidget(imageLabel)
        titleLayout.addWidget(titleLabel)
        titleLayout.addStretch()
        contentsLayout.addWidget(TabWidget)
        buttonLayout = QHBoxLayout()
        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok)
        buttonLayout.addWidget(buttonBox)
        layout.addLayout(titleLayout)
        layout.addLayout(contentsLayout)
        layout.addLayout(buttonLayout)
        buttonBox.clicked.connect(dialog.accept)

        dialog.setLayout(layout)
        dialog.setMinimumSize(QSize(480, 400))
        dialog.setWindowTitle(self.tr('About Webcam Manager'))
        dialog.setWindowIcon(QIcon.fromTheme('help-about'))

        dialog.show()
示例#38
0
class Chat(QMainWindow):
    def __init__(self):
        super(Chat, self).__init__()
        self.setWindowTitle('chat')

        self.createActions()
        self.createQWidget()
        self.createAboutQWidget()

    def about(self):
        self.bar.showMessage('about')
        self.aboutArea.show()

    def logout(self):
        self.outputArea.clear()
        self.loginArea.show()
        self.hide()

    def set_thing(self):
        self.bar.showMessage('set')
        
    def createActions(self):
        aboutAct = QAction("&about", self)
        aboutAct.triggered.connect(self.about)


        setAct = QAction("&set", self)
        setAct.triggered.connect(self.set_thing)


        logoutAct = QAction("&logout", self)
        logoutAct.triggered.connect(self.logout)

        self.bar = self.statusBar()
        self.bar.showMessage('hello')


        self.aboutmenu = self.menuBar()
        self.aboutmenu.addMenu('&about').addAction(aboutAct)
        self.aboutmenu.addMenu('&set').addAction(setAct)
        self.aboutmenu.addMenu('&logout').addAction(logoutAct)
        
        # this is ubuntu special thing, so you should input this to stop origin ubuntu menubar
        self.aboutmenu.setNativeMenuBar(False)

    def createQWidget(self):
        self.talkArea = QWidget()
        self.setCentralWidget(self.talkArea)   #let QWidget in QMainWindwos

        #qtextbrowser and qpushbutton and qlineedit of self is self.talkArea
        self.outputArea = QTextBrowser(self.talkArea)
        self.pushButton = QPushButton("push", self.talkArea)
        self.inputtext = QLineEdit(self.talkArea)
        self.hbox = QHBoxLayout()

        self.hbox.addWidget(self.inputtext)
        self.hbox.addWidget(self.pushButton)

        #because qwidget only have setlayout, so use self.talkArea to set
        self.talkArea.setLayout(QVBoxLayout())
        self.talkArea.layout().addWidget(self.outputArea)
        self.talkArea.layout().addLayout(self.hbox)

        self.pushButton.clicked.connect(self.push)

        
        self.talkArea.show()

    def push(self):
        self.outputArea.append(self.inputtext.text())
        self.bar.showMessage(self.inputtext.text())
        self.inputtext.clear()

    def loginQWidget(self):
        self.loginArea = QWidget()
        self.loginArea.setWindowTitle('login')

        self.label = QLabel('輸入ip:', self.loginArea)
        self.ip_input = QLineEdit(self.loginArea)
        self.login_button = QPushButton('login', self.loginArea)

        self.loginArea.setLayout(QVBoxLayout())
        self.loginArea.layout().addWidget(self.label)
        self.loginArea.layout().addWidget(self.ip_input)
        self.loginArea.layout().addWidget(self.login_button)

        self.login_button.clicked.connect(self.login)

        self.loginArea.show()

    def login(self):
        self.show()
        self.ip_input.clear()
        self.loginArea.hide()

    def createAboutQWidget(self):
        self.aboutArea = QWidget()
        self.aboutArea.setWindowTitle('about')

        self.about_label = QLabel('這是我在工程獅計劃中的作品之一', self.aboutArea)

        self.aboutArea.setLayout(QVBoxLayout())
        self.aboutArea.layout().addWidget(self.about_label)
class MainWindow(QWidget):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
#        self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint)
#        self.setAttribute(Qt.WA_TranslucentBackground)
        self.resize(900, 700)
        self.__search_mode = {'fuzzy':   'fuzzy_search',
                              'precise': 'precise_search',
                              'reg':     'reg_search'}
        # self.__pbn_switch_view = None

        # 创建窗口部件
        self.__widget_frame = QLabel()

        # window title
        self.__lab_title_fram = QLabel()
        self.__lab_title = QLabel('搜索辅助工具')
        self.__lab_title.setAlignment(Qt.AlignCenter)

        self.__lab_open_tool = QLabel('打开文件方式')
        self.__ln_open_tool = QLineEdit()
        self.__pbn_open_tool = QToolButton()
        self.__pbn_open_tool.setText('选择...')
        self.__ln_open_tool.setFixedHeight(20)
        self.__ln_open_tool.setFixedWidth(150)
        self.__pbn_open_tool.setFixedSize(48, 20)
        self.__lab_title_fram.setFixedHeight(50)

        # search mode
        self.__lab_mode_fram = QLabel()
        self.__rbn_fuzzy = QRadioButton('模糊搜索')
        self.__rbn_precise = QRadioButton('精确搜索')
        self.__rbn_reg = QRadioButton('正则表达式搜索')
        self.__rbn_fuzzy.setChecked(True)
        self.__lab_mode_fram.setFixedHeight(22)

        # search pattern
        self.__lab_pattern_fram = QLabel()
        self.__ln_file_name = QLineEdit()
        self.__ln_file_name.setPlaceholderText('请输入搜索条件或正则表达式......')
        self.__rbn_reg_Iyes = QRadioButton('区分大小写')
        self.__rbn_reg_Ino = QRadioButton('不区分大小写')
        self.__lab_pattern_fram.setFixedHeight(20)

        # search path
        self.__lab_path_fram = QLabel()
        self.__ln_file_path = QLineEdit()
        self.__ln_file_path.setPlaceholderText('请选择或输入路径......')
        self.__pbn_file_path = QToolButton()
        self.__pbn_file_path.setText('浏览...')
        self.__rbn_search_file = QRadioButton('检索文件名')
        self.__rbn_search_content = QRadioButton('检索文件内容')
        self.__pbn_file_path.setFixedSize(48, 20)
        self.__lab_path_fram.setFixedHeight(20)

        # search state
        self.__lab_state_fram = QLabel()
        self.__lab_state = QLabel('状态:暂无搜索结果!')
        self.__pbn_search = QPushButton('开始')
        self.__pbn_stop = QPushButton('停止')
        self.__pbn_search.setFixedWidth(89)
        self.__pbn_stop.setFixedWidth(89)
        self.__lab_state_fram.setFixedHeight(35)

        # search result
        self.__tabView = QTabWidget()
        self.__browser_result = QListWidget()
        self.__browser_error = QTextBrowser()
        self.__tabView.addTab(self.__browser_result, '匹配结果')
        self.__tabView.addTab(self.__browser_error, '错误结果')

        self.__btn_group_type = QButtonGroup()
        self.__btn_group_type.addButton(self.__rbn_search_file)
        self.__btn_group_type.addButton(self.__rbn_search_content)
        self.__rbn_search_file.setChecked(True)

        # radiobutton group
        self.__btn_group_re_I = QButtonGroup()
        self.__btn_group_re_I.addButton(self.__rbn_reg_Iyes)
        self.__btn_group_re_I.addButton(self.__rbn_reg_Ino)
        self.__rbn_reg_Iyes.setChecked(True)

        # lines
        '''
        self.__line_1 = QFrame()
        self.__line_1.setFrameStyle(QFrame.HLine | QFrame.Sunken)
        '''

        # 布局
        # open tool
        self.__layout_tool_choose = QHBoxLayout()
        self.__layout_tool_choose.addWidget(self.__ln_open_tool)
        self.__layout_tool_choose.addWidget(self.__pbn_open_tool)
        self.__layout_tool_choose.setSpacing(0)
        self.__layout_tool_choose.setContentsMargins(0, 0, 0, 0)
        
        self.__layout_open_tool = QHBoxLayout()
        self.__layout_open_tool.addWidget(self.__lab_open_tool)
        self.__layout_open_tool.addLayout(self.__layout_tool_choose)
        self.__layout_open_tool.setSpacing(2)

        # window title
        self.__layout_title = QHBoxLayout()
        self.__layout_title.addStretch(5)
        self.__layout_title.addWidget(self.__lab_title)
        self.__layout_title.addStretch(1)
        self.__layout_title.addLayout(self.__layout_open_tool)
        self.__layout_title.setContentsMargins(0, 0, 0, 20)
        self.__lab_title_fram.setLayout(self.__layout_title)

        # search mode
        self.__layout_search_mode = QHBoxLayout()
        self.__layout_search_mode.addWidget(self.__rbn_fuzzy)
        self.__layout_search_mode.addStretch()
        self.__layout_search_mode.addWidget(self.__rbn_precise)
        self.__layout_search_mode.addStretch()
        self.__layout_search_mode.addWidget(self.__rbn_reg)
        self.__layout_search_mode.setContentsMargins(60, 0, 60, 0)
        self.__lab_mode_fram.setLayout(self.__layout_search_mode)

        # search pattern
        self.__layout_search_reg_I = QHBoxLayout()
        self.__layout_search_reg_I.addWidget(self.__rbn_reg_Iyes)
        self.__layout_search_reg_I.addWidget(self.__rbn_reg_Ino)

        self.__layout_pattern = QHBoxLayout()
        self.__layout_pattern.addWidget(self.__ln_file_name)
        self.__layout_pattern.addLayout(self.__layout_search_reg_I)
        self.__layout_pattern.setContentsMargins(0, 0, 0, 0)
        self.__lab_pattern_fram.setLayout(self.__layout_pattern)

        # search path
        self.__layout_choose_path = QHBoxLayout()
        self.__layout_choose_path.addWidget(self.__ln_file_path)
        self.__layout_choose_path.addWidget(self.__pbn_file_path)
        self.__layout_choose_path.setSpacing(0)

        self.__layout_path = QHBoxLayout()
        self.__layout_path.addLayout(self.__layout_choose_path)
        self.__layout_path.addWidget(self.__rbn_search_file)
        self.__layout_path.addWidget(self.__rbn_search_content)
        self.__layout_path.setContentsMargins(0, 0, 0, 0)
        self.__lab_path_fram.setLayout(self.__layout_path)

        # search state
        self.__layout_state = QHBoxLayout()
        self.__layout_state.addWidget(self.__lab_state)
        self.__layout_state.addWidget(self.__pbn_search)
        self.__layout_state.addWidget(self.__pbn_stop)
        self.__layout_state.setContentsMargins(0, 0, 0, 10)
        self.__lab_state_fram.setLayout(self.__layout_state)

        # top layout
        self.__layout_top = QVBoxLayout()
        self.__layout_top.addWidget(self.__lab_title_fram)
        self.__layout_top.addWidget(self.__lab_mode_fram)
        self.__layout_top.addWidget(self.__lab_pattern_fram)
        self.__layout_top.addWidget(self.__lab_path_fram)
        self.__layout_top.addWidget(self.__lab_state_fram)
        self.__layout_top.addWidget(self.__tabView)
        self.__layout_top.setSpacing(10)
        self.__widget_frame.setLayout(self.__layout_top)

        self.__layout_fram = QGridLayout()
        self.__layout_fram.addWidget(self.__widget_frame, 0, 0, 1, 1)
        self.__layout_fram.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self.__layout_fram)

        # set object name
        self.__widget_frame.setObjectName('fram')
        self.__lab_title.setObjectName('lab_title')
        self.__ln_open_tool.setObjectName('ln_open_tool')
        self.__lab_mode_fram.setObjectName('mode_fram')
        self.__ln_file_name.setObjectName('ln_pattern')
        self.__ln_file_path.setObjectName('ln_path')
        self.__lab_state.setObjectName('state')
        self.__tabView.setObjectName('tabView')
        self.__browser_result.setObjectName('browser_result')
        self.__browser_error.setObjectName('browser_error')

        self.setStyleSheet(
            '#fram{'
                'border-image: url(Images/bg);'
            '}'
            '#lab_title{'
                'color: white;'
                'font-size: 18pt;'
            '}'
            '#open_tool{'
                'color: black;'
            '}'
            '#mode_fram{'
                # 'border-top: 1px solid rgba(20, 20, 20, 100);'
                # 'border-bottom: 1px solid rgba(20, 20, 20, 100);'
                'background: rgba(0, 0, 0, 40);'
            '}'
            '#ln_open_tool, #ln_path{'
                'border-top-left-radius:    2px;'
                'border-bottom-left-radius: 2px;'
            '}'
            '#ln_pattern{'
                'border-radius: 2px;'
            '}'
            '#state{'
                'background: rgba(0, 0, 0, 40);'
                'border-radius: 2px;'
                'padding: 1px;'
                'color: rgb(240, 240, 240);'
            '}'
            'QTabBar::tab {'
                'border: 0;'
                'width:  90px;'
                'height: 20px;'
                'margin: 0 2px 0 0;'        # top right bottom left
                # 'border-top-left-radius: 5px;'
                # 'border-top-right-radius: 5px;'
                'color: rgb(200, 255, 255;);'
            '}'
            'QTabBar::tab:selected{'
                'background: rgba(25, 0, 0, 40);'
                'border-left: 1px solid rgba(255, 255, 255, 200);'
                'border-top: 1px solid rgba(255, 255, 255, 200);'
                'border-right: 1px solid rgba(255, 255, 255, 200);'
            '}'
            'QTabWidget:pane {'
                'border: 1px solid rgba(255, 255, 255, 200);'
                'background: rgba(0, 0, 0, 80);'
            '}'
            '#browser_result, #browser_error{'
                'background: rgba(0, 0, 0, 0);'
                'border: 0;'
            '}'
            'QLineEdit{'
                'background: rgba(0, 0, 0, 40);'
                'border: 1px solid rgba(220, 220, 220, 200);'
                'color: white;'
                'height: 20px;'
            '}'
            'QPushButton{'
                'background: rgba(0, 0, 0, 100);'
                'border-radius: 5px;'
                'height: 20px;'
                'color: white;'
            '}'
            'QPushButton::hover{'
                'background: rgba(0, 0, 0, 150);'
            '}'
            'QToolButton{'
                'background: rgba(0, 0, 0, 100);'
                'color: white;'
                'border-top-right-radius:    2px;'
                'border-bottom-right-radius: 2px;'
            '}'
            'QToolButton::hover{'
                'background: rgba(0, 0, 0, 150);'
            '}'
            )

        self.__ln_file_name.setFocus()
        self.__pbn_search.setShortcut(Qt.Key_Return)

        # 关联 信号/槽
        self.__pbn_file_path.clicked.connect(self.choose_path)
        self.__pbn_search.clicked.connect(self.pbn_search_clicked)
        self.__pbn_stop.clicked.connect(self.pbn_stop)
        self.__pbn_open_tool.clicked.connect(self.choose_open_tool)
        self.__browser_result.doubleClicked.connect(self.listitem_clicked)

        # 线程间共享数据队列
        queue_size = 10000
        self.__queue_result = Queue(queue_size)
        self.__queue_error = Queue(queue_size)

        # 标记搜索状态
        self.__searching = False

        # 强制结束子线程
        self.__thread_killer = False

    # 重写鼠标按下事件
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.offset = event.globalPos() - self.pos()

    # 重写鼠标移动事件
    def mouseMoveEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            self.move(event.globalPos() - self.offset)

    # 检测记事本程序
    def set_open_tool(self):
        if platform.architecture() == ('32bit', 'WindowsPE'):
            possible_dir = ['C:\\Program Files\\Sublime Text 2', 'C:\\Sublime Text 2',
                            'D:\\Program Files\\Sublime Text 2', 'D:\\Sublime Text 2',
                            'E:\\Program Files\\Sublime Text 2', 'E:\\Sublime Text 2',
                            'F:\\Program Files\\Sublime Text 2', 'F:\\Sublime Text 2',
                            'C:\\Program Files\\Notepad++', 'C:\\notepad++',
                            'D:\\Program Files\\Notepad++', 'D:\\notepad++',
                            'E:\\Program Files\\Notepad++', 'E:\\notepad++',
                            'F:\\Program Files\\Notepad++', 'F:\\notepad++',
                            'C:\\Windows\\System32']
        elif platform.architecture() == ('32bit', 'ELF'):
            possible_dir = ['/usr/bin']
        for rootdir in possible_dir:
            for root, dirs, files in walk(rootdir):
                for file in files:
                    if file == 'sublime_text.exe' or file == 'notepad++.exe' or file == 'notepad.exe':
                        self.__ln_open_tool.setText(join(root, file))
                        return
        
    # 搜索文件名
    def search_from_filename(self, filepath, filename, mode='fuzzy_search', I=True):
        # check arguments of searching
        if filepath == '' or not exists(filepath):
            return False
        if mode not in self.__search_mode.values():
            return False
        if filename == '':
            return False

        # count
        count = 0

        # fuzzy mode
        if mode == self.__search_mode['fuzzy']:
            for root, dirs, files in walk(filepath):
                for each_file in files:
                    # kill subThread
                    if self.__thread_killer == True:
                        return
                        
                    if filename in each_file:
                        count += 1
                        self.__lab_state.setText('正在搜索......已搜到 %d 个文件' % count)
                        self.__queue_result.put(join(root, each_file))
                        self.__tabView.setTabText(0, '匹配结果(%d)' % count)
        # precise mode
        elif mode == self.__search_mode['precise']:
            for root, dirs, files in walk(filepath):
                for each_file in files:
                    # kill subThread
                    if self.__thread_killer == True:
                        return
                        
                    if filename == splitext(each_file)[0] or filename == each_file:
                        count += 1
                        self.__lab_state.setText('正在搜索......已搜到 %d 个文件' % count)
                        self.__queue_result.put(join(root, each_file))
                        self.__tabView.setTabText(0, '匹配结果(%d)' % count)
        # regular expression mode
        elif mode == self.__search_mode['reg']:
            if I:
                pattern = re.compile(r'%s' % filename)
            else:
                pattern = re.compile(r'%s' % filename, re.I)

            for root, dirs, files in walk(filepath):
                for each_file in files:
                    # kill subThread
                    if self.__thread_killer == True:
                        return
                        
                    if re.search(pattern, each_file):
                        count += 1
                        self.__lab_state.setText('正在搜索......已搜到 %d 个文件' % count)
                        self.__queue_result.put(join(root, each_file))
                        self.__tabView.setTabText(0, '匹配结果(%d)' % count)
        self.__lab_state.setText('搜索完毕! 共搜到 %d 个文件' % count)     # finished
        self.__searching = False                # set serching flag

    # 搜索文件内容
    def search_from_content(self, path, content, mode='fuzzy_search', I=True):
        if path == '' or not exists(path):
            return False
        if mode not in self.__search_mode.values():
            return False
        if content == '':
            return False
        pass_file_count = 0
        error_number = 0
        current_file = ''
        processing_file = ''
        match_files_count = 0
        if mode == self.__search_mode['reg']:
            if I:
                pattern = re.compile(r'%s' % content)
            else:
                pattern = re.compile(r'%s' % content, re.I)
            for root, dirs, files in walk(path):
                for each_file in [file for file in files if file.endswith('.h') or file.endswith('.cpp') or file.endswith('.cs')]:
                    current_file = join(root, each_file)
                    pass_file_count += 1
                    self.__lab_state.setText('正在搜索......%s' % current_file)
                    try:
                        for line_number, line in enumerate(open(current_file)):
                            # kill subThread
                            if self.__thread_killer == True:
                                return
                            
                            if re.search(pattern, line):
                                if processing_file != current_file:
                                    self.__queue_result.put('\n%s' % current_file)
                                    processing_file = current_file
                                    match_files_count += 1
                                self.__queue_result.put('line %s: %s' % (line_number, line.strip()))
                    except Exception as error:
                        self.__queue_error.put("%s\n(%s)\n" % (error, current_file))
                        pass_file_count -= 1
                        error_number += 1
                        continue
                    self.__tabView.setTabText(0, '匹配结果(%d)' % match_files_count)
        else:
            for root, dirs, files in walk(path):
                for each_file in [file for file in files if file.endswith('.h') or file.endswith('.cpp') or file.endswith('.cs') or file.endswith('.txt') or file.endswith('.py')]:
                    current_file = join(root, each_file)
                    pass_file_count += 1
                    self.__lab_state.setText('正在搜索......%s' % current_file)
                    try:
                        for line_number, line in enumerate(open(current_file)):
                            # kill subThread
                            if self.__thread_killer == True:
                                return
                            
                            if content in line:                                         # 匹配成功
                                if processing_file != current_file:                     # 如果是新文件
                                    self.__queue_result.put('\n%s' % current_file)      # 文件名入队
                                    processing_file = current_file                      # 更新文件标记
                                    match_files_count += 1
                                self.__queue_result.put('line %s: %s' % (line_number, line.strip()))    # 匹配行入队
                    except Exception as error:
                        self.__queue_error.put("%s\n(%s)\n" % (error, current_file))
                        pass_file_count -= 1
                        error_number += 1
                        continue
                    self.__tabView.setTabText(0, '匹配结果(%d)' % match_files_count)
        # self.__queue_result.put()
        self.__lab_state.setText('搜索完毕!成功匹配 %d 个文件,处理 %s 个文件,失败 %s 文件。' % (match_files_count, pass_file_count, error_number))
        self.__searching = False

    # 单击选择路径按钮
    def choose_path(self):
        path = QFileDialog.getExistingDirectory()
        if path != '':
            path = sep.join(path.split('/'))
            self.__ln_file_path.setText(path)

    # 选择打开文件工具
    def choose_open_tool(self):
        path = QFileDialog.getOpenFileName()
        if path[0] != '':
            self.__ln_open_tool.setText(path[0])

    # 显示搜索结果
    def show_search_result(self):
        """将搜索结果加载到界面,供用户查看和操作"""
        line_block = []         # 定义临时列表,成批加载,避免刷新频率过高造成界面闪烁
        block_size = 10         # 一次性加载的个数
        while self.__searching or self.__queue_result.qsize():
            # kill subThread
            if self.__thread_killer == True:
                return
            
            # if self.__searching or self.__queue_result.qsize() >= block_size:     // 永远记住这个 bug (生产者-消费者 问题)
            if self.__queue_result.qsize() >= block_size:                           # 如果队列中不小于 block_size 个项
                for i in range(block_size):                                             # 取出 block_size 个项
                    line_block.append(self.__queue_result.get())                        # 出队操作
                self.__browser_result.addItems(line_block)                                     # 一次性添加 block_size 个条目
                line_block.clear()                                                      # 清空临时列表
            elif self.__queue_result.qsize() >= 0:                                                                   # 如果队列中小于 block_size 各项
                item = self.__queue_result.get()                                        # 出队一项
                self.__browser_result.addItem(QListWidgetItem(item))                           # 加载到界面
            #self.__browser.setCurrentRow(self.__browser.count()-1)                  # 设置列表中最后一项为当前项,使列表不停滚动
            sleep(0.05)                                                              # 给界面事件循环腾出时间,避免界面冻结
        #self.__pbn_search.setEnabled(True)

    # 显示出错结果
    def show_error_result(self):
        """打印略过的文件和出错原因,多为 I/O Error"""
        count = 0
        while self.__queue_error.qsize() or self.__searching:
            # kill subThread
            if self.__thread_killer == True:
                return
            
            if self.__queue_error.qsize() <= 0:
               continue
            self.__browser_error.append(self.__queue_error.get())
            count += 1
            self.__tabView.setTabText(1, '错误结果(%d)' % count)

    # 单击检索按钮
    def pbn_search_clicked(self):
        """To search allow the arguments from UI"""
        # 获取 UI 数据
        file_path = self.__ln_file_path.text()
        file_name = self.__ln_file_name.text()

        # 检查参数
        if file_path == '':
            QMessageBox(QMessageBox.Warning, '缺少参数!', '请输入搜索路径!', QMessageBox.Ok, self).exec_()
            return
        if file_name == '':
            QMessageBox(QMessageBox.Warning, '缺少参数!', '请输入匹配条件!', QMessageBox.Ok, self).exec_()
            return

        # 判断搜索模式
        mode = self.__search_mode['fuzzy']
        if self.__rbn_reg.isChecked():
            mode = self.__search_mode['reg']
        elif self.__rbn_fuzzy.isChecked():
            mode = self.__search_mode['fuzzy']
        elif self.__rbn_precise.isChecked():
            mode = self.__search_mode['precise']

        # 大小写敏感标记
        I = True
        if self.__rbn_reg_Ino.isChecked():
            I = False

        self.__browser_result.clear()
        self.__browser_error.clear()
        self.__tabView.setTabText(0, '匹配结果(0)')
        self.__tabView.setTabText(1, '错误结果(0)')
        self.__searching = True

        # 开启子线程,后台深度遍历
        self.__thread_killer = False
        if self.__rbn_search_file.isChecked():
            self.__lab_state.setText('正在搜索......已搜索到 0 个文件')
            self.__sub_thread_search = Thread(target=self.search_from_filename, args=(file_path, file_name, mode, I))
            self.__sub_thread_search.start()
        else:
            self.__lab_state.setText('正在搜索......')
            self.__sub_thread_search = Thread(target=self.search_from_content, args=(file_path, file_name, mode, I))
            self.__sub_thread_search.start()

        # 开启子线程,显示搜索结果
        self.__sub_thread_show_result = Thread(target=self.show_search_result)
        self.__sub_thread_show_result.start()

        # 开启子线程,显示错误结果
        self.__sub_thread_show_error = Thread(target=self.show_error_result)
        self.__sub_thread_show_error.start()

        # self.__pbn_search_file.setEnable(False)
        # self.__pbn_search_content.setEnable(False)

    # 单击停止按钮
    def pbn_stop(self):
        if not self.__searching:
            return
        self.__thread_killer = True
        while self.__queue_result.qsize():
            self.__queue_result.get()
        while self.__queue_error.qsize():
            self.__queue_error.get()
        self.__lab_state.setText('搜索已停止!')
        self.__searching = False

    # 双击搜索结果
    def listitem_clicked(self):
        """Double click to open the file from search result"""
        file_path = self.__browser_result.currentItem().text().strip()
        read_tool = self.__ln_open_tool.text()
        if not exists(file_path):
            QMessageBox.warning(self, '错误!', '请双击文件名\n%s 不是文件或打不开!' % file_path, QMessageBox.Ok)
            return
        if splitext(file_path)[1] in ['.jpg', '.png', '.jpeg', '.gif']:
            file_path = r'%s'.replace(' ', r'\ ') % file_path
            system('%s' % file_path)
        else:
            system('"%s" %s' % (read_tool, file_path))
示例#40
0
class QChatWidget(QWidget):

    def __init__(self, chat_window, nick, parent=None):
        QWidget.__init__(self, parent)

        self.chat_window = chat_window
        self.nick = nick

        self.disabled = False
        self.cleared = False

        self.url_regex = re.compile(URL_REGEX)

        self.chat_log = QTextBrowser()
        self.chat_log.setOpenExternalLinks(True)

        self.chat_input = QTextEdit()
        self.chat_input.textChanged.connect(self.chatInputTextChanged)

        self.send_button = QPushButton("Send")
        self.send_button.clicked.connect(self.sendMessage)

        # Set the min height for the chatlog and a matching fixed height for the send button
        chat_input_font_metrics = QFontMetrics(self.chat_input.font())
        self.chat_input.setMinimumHeight(chat_input_font_metrics.lineSpacing() * 3)
        self.send_button.setFixedHeight(chat_input_font_metrics.lineSpacing() * 3)

        hbox = QHBoxLayout()
        hbox.addWidget(self.chat_input)
        hbox.addWidget(self.send_button)

        # Put the chatinput and send button in a wrapper widget so they may be added to the splitter
        chat_input_wrapper = QWidget()
        chat_input_wrapper.setLayout(hbox)
        chat_input_wrapper.setMinimumHeight(chat_input_font_metrics.lineSpacing() * 3.7)

        # Put the chat log and chat input into a splitter so the user can resize them at will
        splitter = QSplitter(Qt.Vertical)
        splitter.addWidget(self.chat_log)
        splitter.addWidget(chat_input_wrapper)
        splitter.setSizes([int(parent.height()), 1])

        hbox = QHBoxLayout()
        hbox.addWidget(splitter)
        self.setLayout(hbox)

        self.typing_timer = QTimer()
        self.typing_timer.setSingleShot(True)
        self.typing_timer.timeout.connect(self.stoppedTyping)

    def setRemoteNick(self, nick):
        self.nick = nick

    def chatInputTextChanged(self):
        # Check if the text changed was the text box being cleared to avoid sending an invalid typing status
        if self.cleared:
            self.cleared = False
            return

        if str(self.chat_input.toPlainText())[-1:] == '\n':
            self.sendMessage()
        else:
            # Start a timer to check for the user stopping typing
            self.typing_timer.start(TYPING_TIMEOUT)
            self.sendTypingStatus(TYPING_START)

    def stoppedTyping(self):
        self.typing_timer.stop()
        if str(self.chat_input.toPlainText()) == '':
            self.sendTypingStatus(TYPING_STOP_WITHOUT_TEXT)
        else:
            self.sendTypingStatus(TYPING_STOP_WITH_TEXT)

    def sendMessage(self):
        if self.disabled:
            return
        else:
            pass

        self.typing_timer.stop()

        text = str(self.chat_input.toPlainText())[:-1]

        # Don't send empty messages
        if text == '':
            return

        # Convert URLs into clickable links
        text = self.__linkify(text)

        # Add the message to the message queue to be sent
        self.chat_window.client.getSession(self.remote_id).sendChatMessage(text)

        # Clear the chat input
        self.wasCleared = True
        self.chat_input.clear()

        self.appendMessage(text, MSG_SENDER)

    def sendTypingStatus(self, status):
        self.chat_window.client.getSession(self.remote_id).sendTypingMessage(status)

    def showNowChattingMessage(self, nick):
        self.nick = nick
        self.remote_id = self.chat_window.client.getClientId(self.nick)
        self.appendMessage("You are now securely chatting with " + self.nick + " :)",
                           MSG_SERVICE, show_timestamp_and_nick=False)

        self.appendMessage("It's a good idea to verify the communcation is secure by selecting "
                           "\"authenticate buddy\" in the options menu.", MSG_SERVICE, show_timestamp_and_nick=False)

        self.addNickButton = QPushButton('Add', self)
        self.addNickButton.setGeometry(584, 8, 31, 23)
        self.addNickButton.clicked.connect(self.addNickScreen)
        self.addNickButton.show()

    def addUser(self, user):
        nick = str(user.text()).lower()

        # Validate the given nick
        nickStatus = utils.isValidNick(nick)
        if nickStatus == errors.VALID_NICK:
            # TODO: Group chats
            pass
        elif nickStatus == errors.INVALID_NICK_CONTENT:
            QMessageBox.warning(self, errors.TITLE_INVALID_NICK, errors.INVALID_NICK_CONTENT)
        elif nickStatus == errors.INVALID_NICK_LENGTH:
            QMessageBox.warning(self, errors.TITLE_INVALID_NICK, errors.INVALID_NICK_LENGTH)
        elif nickStatus == errors.INVALID_EMPTY_NICK:
            QMessageBox.warning(self, errors.TITLE_EMPTY_NICK, errors.EMPTY_NICK)

    def addNickScreen(self):
        self.chat_log.setEnabled(False)
        self.chat_input.setEnabled(False)
        self.send_button.setEnabled(False)
        self.addNickButton.hide()
        self.addUserText = QLabel("Enter a username to add a user to the group chat.", self)
        self.addUserText.setGeometry(200, 20, 300, 100)
        self.addUserText.show()
        self.user = QLineEdit(self)
        self.user.setGeometry(200, 120, 240, 20)
        self.user.returnPressed.connect(self.addUser)
        self.user.show()
        self.addUserButton = QPushButton('Add User', self)
        self.addUserButton.setGeometry(250, 150, 150, 25)
        self.addUserButton.clicked.connect(lambda: self.addUser(self.user))
        self.addUserButton.show()
        self.cancel = QPushButton('Cancel', self)
        self.cancel.setGeometry(298, 210, 51, 23)
        self.cancel.clicked.connect(lambda: self.chat_log.setEnabled(True))
        self.cancel.clicked.connect(lambda: self.chat_input.setEnabled(True))
        self.cancel.clicked.connect(lambda: self.send_button.setEnabled(True))
        self.cancel.clicked.connect(self.addUserText.hide)
        self.cancel.clicked.connect(self.user.hide)
        self.cancel.clicked.connect(self.addUserButton.hide)
        self.cancel.clicked.connect(self.addNickButton.show)
        self.cancel.clicked.connect(self.cancel.hide)
        self.cancel.show()

    def appendMessage(self, message, source, show_timestamp_and_nick=True):
        color = self.__getColor(source)

        if show_timestamp_and_nick:
            timestamp = '<font color="' + color + '">(' + getTimestamp() + ') <strong>' + \
                        (self.chat_window.client.nick if source == MSG_SENDER else self.nick) + \
                        ':</strong></font> '
        else:
            timestamp = ''

        # If the user has scrolled up (current value != maximum), do not move the scrollbar
        # to the bottom after appending the message
        shouldScroll = True
        scrollbar = self.chat_log.verticalScrollBar()
        if scrollbar.value() != scrollbar.maximum() and source != constants.SENDER:
            shouldScroll = False

        self.chat_log.append(timestamp + message)

        # Move the vertical scrollbar to the bottom of the chat log
        if shouldScroll:
            scrollbar.setValue(scrollbar.maximum())

    def __linkify(self, text):
        matches = self.url_regex.findall(text)
        for match in matches:
            text = text.replace(match[0], '<a href="%s">%s</a>' % (match[0], match[0]))
        return text

    def __getColor(self, source):
        if source == MSG_SENDER:
            if qtUtils.is_light_theme:
                return '#0000CC'
            else:
                return '#6666FF'
        elif source == MSG_RECEIVER:
            if qtUtils.is_light_theme:
                return '#CC0000'
            else:
                return '#CC3333'
        else:
            if qtUtils.is_light_theme:
                return '#000000'
            else:
                return '#FFFFFF'

    def disable(self):
        self.disabled = True
        self.chat_input.setReadOnly(True)

    def enable(self):
        self.disabled = False
        self.chat_input.setReadOnly(False)
示例#41
0
class Sansimera(QMainWindow):
    def __init__(self, parent=None):
        super(Sansimera, self).__init__(parent)
        self.settings = QSettings()
        self.timer = QTimer(self)
        self.timer_reminder = QTimer(self)
        self.timer_reminder.timeout.connect(self.reminder_tray)
        interval = self.settings.value('Interval') or '1'
        if interval != '0':
            self.timer_reminder.start(int(interval) * 60 * 60 * 1000)
        self.tentatives = 0
        self.gui()
        self.lista = []
        self.lista_pos = 0
        self.eortazontes_shown = False
        self.eortazontes_names = ''

    def gui(self):
        self.systray = QSystemTrayIcon()
        self.icon = QIcon(':/sansimera.png')
        self.systray.setIcon(self.icon)
        self.systray.setToolTip('Σαν σήμερα...')
        self.menu = QMenu()
        self.exitAction = QAction('&Έξοδος', self)
        self.refreshAction = QAction('&Ανανέωση', self)
        self.aboutAction = QAction('&Σχετικά', self)
        self.notification_interval = QAction('Ει&δοποίηση εορταζόντων', self)
        self.menu.addAction(self.notification_interval)
        self.menu.addAction(self.refreshAction)
        self.menu.addAction(self.aboutAction)
        self.menu.addAction(self.exitAction)
        self.systray.setContextMenu(self.menu)
        self.notification_interval.triggered.connect(self.interval_namedays)
        self.exitAction.triggered.connect(exit)
        self.refreshAction.triggered.connect(self.refresh)
        self.aboutAction.triggered.connect(self.about)
        self.browser = QTextBrowser()
        self.browser.setOpenExternalLinks(True)
        self.setGeometry(600, 500, 400, 300)
        self.setWindowIcon(self.icon)
        self.setWindowTitle('Σαν σήμερα...')
        self.setCentralWidget(self.browser)
        self.systray.show()
        self.systray.activated.connect(self.activate)
        self.browser.append('Λήψη...')
        nicon = QIcon(':/next')
        picon = QIcon(':/previous')
        ricon = QIcon(':/refresh')
        iicon = QIcon(':/info')
        qicon = QIcon(':/exit')
        inicon = QIcon(':/notifications')
        self.nextAction = QAction('Επόμενο', self)
        self.nextAction.setIcon(nicon)
        self.previousAction = QAction('Προηγούμενο', self)
        self.refreshAction.triggered.connect(self.refresh)
        self.nextAction.triggered.connect(self.nextItem)
        self.previousAction.triggered.connect(self.previousItem)
        self.previousAction.setIcon(picon)
        self.refreshAction.setIcon(ricon)
        self.exitAction.setIcon(qicon)
        self.aboutAction.setIcon(iicon)
        self.notification_interval.setIcon(inicon)
        controls = QToolBar()
        self.addToolBar(Qt.BottomToolBarArea, controls)
        controls.setObjectName('Controls')
        controls.addAction(self.previousAction)
        controls.addAction(self.nextAction)
        controls.addAction(self.refreshAction)
        self.restoreState(self.settings.value("MainWindow/State", QByteArray()))
        self.refresh()

    def interval_namedays(self):
        dialog = sansimera_reminder.Reminder(self)
        dialog.applied_signal['QString'].connect(self.reminder)
        if dialog.exec_() == 1:
            print('Apply namedays reminder interval...')

    def reminder(self, time):
        self.settings.setValue('Interval', time)
        if time != '0':
            self.timer_reminder.start(int(time) * 60 * 60 * 1000)
            print('Reminder = ' + time + ' hour(s)')
        else:
            print('Reminder = None')

    def nextItem(self):
        if len(self.lista) >= 1:
            self.browser.clear()
            if self.lista_pos != len(self.lista)-1:
                self.lista_pos += 1
            else:
                self.lista_pos = 0
            self.browser.append(self.lista[self.lista_pos])
            self.browser.moveCursor(QTextCursor.Start)
        else:
            return

    def previousItem(self):
        if len(self.lista) >= 1:
            self.browser.clear()
            if self.lista_pos == 0:
                self.lista_pos = len(self.lista)-1
            else:
                self.lista_pos -= 1
            self.browser.append(self.lista[self.lista_pos])
            self.browser.moveCursor(QTextCursor.Start)
        else:
            return

    def refresh(self):
        try:
            if self.workThread.isRunning():
                return
        except AttributeError:
            pass
        self.menu.hide()
        self.browser.clear()
        self.lista = []
        self.systray.setToolTip('Σαν σήμερα...')
        self.browser.append('Λήψη...')
        self.tentatives = 0
        self.eortazontes_shown = False
        self.download()

    def activate(self, reason):
        self.menu.hide()
        state = self.isVisible()
        if reason == 3:
            if state:
                self.hide()
                return
            else:
                self.show()
                return
        if reason == 1:
            self.menu.hide()
            self.menu.popup(QCursor.pos())

    def download(self):
        self.workThread = WorkThread()
        self.workThread.online_signal[bool].connect(self.status)
        self.workThread.finished.connect(self.window)
        self.workThread.event['QString'].connect(self.addlist)
        self.workThread.names['QString'].connect(self.nameintooltip)
        self.workThread.start()

    def addlist(self, text):
        self.lista.append(text)

    def status(self, status):
        self.status_online = status

    def reminder_tray(self):
        text = self.eortazontes_names.replace('<br/>', '\n')
        urltexts = re.findall('(<a [\S]+php">)', text)
        urltexts.extend(['</a>', '<p>', '<div>'])
        show_notifier_text = text
        for i in urltexts:
            show_notifier_text = show_notifier_text.replace(i, '')
        show_notifier_text = show_notifier_text.replace('\n\n', '\n')
        show_notifier_text = show_notifier_text.replace('www.eortologio.gr)', 'www.eortologio.gr)\n')
        self.systray.showMessage('Εορτάζουν:\n', show_notifier_text)
        self.systray.setToolTip('Εορτάζουν:\n' + show_notifier_text)

    def nameintooltip(self, text):
        self.eortazontes_names = text
        for i in ['<br/>', '<div>']:
            text = text.replace(i, '')
        self.eortazontes_in_window = text
        if self.eortazontes_shown:
            return
        self.reminder_tray()
        self.eortazontes_shown = True

    def window(self):
        self.lista.append('<div class=""></div>' + self.eortazontes_in_window)
        if self.status_online:
            self.browser.clear()
            self.browser.append(self.lista[0])
            self.lista_pos = 0
            return
        else:
            if self.tentatives == 10:
                return
            self.timer.singleShot(5000, self.refresh)
            self.tentatives += 1

    def closeEvent(self, event):
        self.settings.setValue("MainWindow/State", self.saveState())

    def about(self):
        self.menu.hide()
        QMessageBox.about(self, "Εφαρμογή «Σαν σήμερα...»",
                        """<b>sansimera-qt</b> v{0}
                        <p>Δημήτριος Γλενταδάκης <a href="mailto:[email protected]">[email protected]</a>
                        <br/>Ιστοσελίδα: <a href="https://github.com/dglent/sansimera-qt">
                        github sansimera-qt</a>
                        <p>Εφαρμογή πλαισίου συστήματος για την προβολή
                        <br/>των γεγονότων από την ιστοσελίδα <a href="http://www.sansimera.gr">
                        www.sansimera.gr</a><br/>
                        Πηγή εορτολογίου: <a href="http://www.eortologio.gr">
                        www.eortologio.gr</a>, <a href="http://www.synaxari.gr">
                        www.synaxari.gr</a>
                        <p>Άδεια χρήσης: GPLv3 <br/>Python {1} - Qt {2} - PyQt {3} σε {4}""".format(
                        __version__, platform.python_version(),
                        QT_VERSION_STR, PYQT_VERSION_STR, platform.system()))