热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

pyqt练习x3.11

#!usrbinenvpython#-*-coding:utf-8-*-######################################################

#!/usr/bin/env python

# -*- coding: utf-8 -*-

 

########################################################################################

#                                                                                      #

# Copyright (c) 2009 Jakob Kummerow                          #

#                                                                                      #

# 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.                                                                             #

#                                                                                      #

# 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.             #

#                                                                                      #

# You should have received a copy of the GNU General Public License along with         #

# this program.  If not, see .                           #

#                                                                                      #

########################################################################################

 

 

"""

Future ideas:

- auto-indenting: automatically increase/decrease indentation level. --> when?

- send further commands to Hugs without restarting --> major change, might need threads

- support GHCI --> would that be useful?

"""

 

import sys, os, re

from subprocess import Popen, PIPE

from tempfile import NamedTemporaryFile

from PyQt4.QtGui import * #@UnusedWildImport

from PyQt4.QtCore import * #@UnusedWildImport

 

fileFilter = "Haskell source files (*.hs);;All files (*.*)"

settingsFileName = ".config/hugsgui.conf"

fontfamily = "DejaVu Sans Mono"

 

class EditBox(QTextEdit):

 

def __init__(self, parent=None, defaultText=""):

QTextEdit.__init__(self)

self.setTabChangesFocus(False)

self.setAcceptRichText(False)

self.defaultText = defaultText

self.dirty = False

self.loadedFile = False

self.initialState()

self.connect(self, SIGNAL("textChanged()"), self.textChangedHandler)

# we need this to prevent the cursor from jumping back to the system‘s default font

self.connect(self, SIGNAL("currentCharFormatChanged(const QTextCharFormat&)"), self.resetCurrentCharFormat)

self.errorline = []

self.ffont = None

 

def clearInitially(self):

self.clear()

self.setTextColor(self.palette().color(QPalette.Active, QPalette.Text))

self.neverUsed = False

self.resetFont()

 

def initialState(self):

self.neverUsed = True

self.setTextColor(self.palette().color(QPalette.Disabled, QPalette.Text))

self.setPlainText(self.defaultText)

 

def highlightError(self, linenumber):

block = self.document().findBlockByLineNumber(linenumber)

format = block.blockFormat()

format.setBackground(QBrush(QColor(255, 128, 128, 255)))

cursor = self.textCursor()

cursor.setPosition(block.position())

cursor.setBlockFormat(format)

self.errorline += [block]

 

def resetErrorHighlight(self):

for line in self.errorline:

format = line.blockFormat()

format.clearBackground()

cursor = self.textCursor()

if line.position() < self.document().characterCount():

cursor.setPosition(line.position())

cursor.setBlockFormat(format)

self.errorline = []

 

def keyPressEvent(self, e):

if self.neverUsed:

self.clearInitially()

 

if e.key() == Qt.Key_Backtab:

# unindent, either current line only or all selected lines

maincursor = self.textCursor()

if not maincursor.hasSelection():

maincursor.movePosition(QTextCursor.StartOfBlock)

line = str(self.document().findBlockByNumber(maincursor.blockNumber()).text().toUtf8())

whitespace = re.match(r"(\s{0,2})", line).group(1)

for i in range(len(whitespace)): #@UnusedVariable

maincursor.deleteChar()

else:

block = self.document().findBlock(maincursor.selectionStart())

while True:

whitespace = re.match(r"(\s{0,2})", str(block.text().toUtf8())).group(1)

cursor = self.textCursor() 

cursor.setPosition(block.position())

for i in range(len(whitespace)): #@UnusedVariable

cursor.deleteChar()

if block.contains(maincursor.selectionEnd()):

break

block = block.next()

e.accept()

elif e.key() == Qt.Key_Tab:

# indent, either current line only or all selected lines

maincursor = self.textCursor()

if not maincursor.hasSelection():

maincursor.insertText("  ")

else:

block = self.document().findBlock(maincursor.selectionStart())

while True:

cursor = self.textCursor() 

cursor.setPosition(block.position())

cursor.insertText("  ")

if block.contains(maincursor.selectionEnd()):

break

block = block.next()

e.accept()

elif e.key() == Qt.Key_Return:

# copy whitespace from the beginning of the previous line

cursor = self.textCursor()

block = self.document().findBlockByNumber(cursor.blockNumber())

whitespace = re.match(r"(\s*)", str(block.text().toUtf8())).group(1)

QTextEdit.keyPressEvent(self, e)

cursor = self.textCursor()

format = cursor.blockFormat()

format.clearBackground()

cursor.setBlockFormat(format)

cursor.insertText(whitespace)

else:

QTextEdit.keyPressEvent(self, e)

 

def focusInEvent(self, e):

if self.neverUsed and e.reason() != Qt.ActiveWindowFocusReason:

self.clearInitially()

QTextEdit.focusInEvent(self, e)

 

def focusOutEvent(self, e):

if self.loadedFile == False and self.toPlainText() == "":

self.initialState()

QTextEdit.focusOutEvent(self, e)

 

def mousePressEvent(self, e):

if self.neverUsed:

self.clearInitially()

QTextEdit.mousePressEvent(self, e)

 

def toPlainText(self):

if self.neverUsed:

return ""

return str(QTextEdit.toPlainText(self).toUtf8())

 

def textChangedHandler(self):

if self.loadedFile == False and (self.neverUsed or self.toPlainText() == ""):

self.dirty = False

else:

self.dirty = True

 

def resetFont(self, fOnt=None):

if font != None:

self.ffont = font

newFormat = QTextCharFormat()

if self.ffont == None:

newFormat.setFontFamily(fontfamily)

else:

newFormat.setFont(self.ffont)

cursor = self.textCursor()

cursor.movePosition(QTextCursor.Start)

cursor.movePosition(QTextCursor.End, QTextCursor.KeepAnchor)

cursor.mergeCharFormat(newFormat)

self.setCurrentCharFormat(cursor.charFormat())

 

def resetCurrentCharFormat(self):

format = self.textCursor().charFormat()

if self.ffont == None:

format.setFontFamily(fontfamily)

else:

format.setFont(self.ffont)

self.setCurrentCharFormat(format)

 

 

class HugsGUI(QMainWindow):

 

def __init__(self, parent=None):

QMainWindow.__init__(self, parent)

self.setWindowTitle(‘Hugs GUI‘)

 

self.editTextBox = EditBox(self, "Function definition file")

self.commandTextBox = EditBox(self, "Commands for interactive Hugs session")

 

self.outputTextBox = EditBox(self)

self.outputTextBox.setReadOnly(True)

self.outputTextBox.neverUsed = False

 

self.splitter = QSplitter(Qt.Vertical)

self.splitter.addWidget(self.editTextBox)

self.splitter.addWidget(self.commandTextBox)

self.splitter.addWidget(self.outputTextBox)

self.setCentralWidget(self.splitter)

 

toolbar = self.addToolBar("Main")

 

newAction = QAction("New", self)

newAction.setShortcut("Ctrl+N")

newAction.setToolTip("Create a new file (Ctrl+N)")

self.connect(newAction, SIGNAL("triggered()"), self.newFile)

toolbar.addAction(newAction)

 

openAction = QAction("Open...", self)

openAction.setShortcut("Ctrl+O")

openAction.setToolTip("Open file (Ctrl+O)")

self.connect(openAction, SIGNAL("triggered()"), self.openFile)

toolbar.addAction(openAction)

 

saveAction = QAction("Save...", self)

saveAction.setShortcut("Ctrl+S")

saveAction.setToolTip("Save file (Ctrl+S)")

self.connect(saveAction, SIGNAL("triggered()"), self.saveFile)

toolbar.addAction(saveAction)

 

saveAsAction = QAction("Save as...", self)

self.connect(saveAsAction, SIGNAL("triggered()"), self.saveFileAs)

toolbar.addAction(saveAsAction)

 

toolbar.addSeparator()

runAction = QAction("Run!", self)

runAction.setShortcut("F9")

runAction.setToolTip("Run (F9)")

self.connect(runAction, SIGNAL("triggered()"), self.runHugs)

toolbar.addAction(runAction)

 

self.autoSaveAction = QAction("AutoSave before running", self)

self.autoSaveAction.setCheckable(True)

self.autoSaveAction.setToolTip("Whether the current document should automatically be saved before executing it.")

 

self.interactiveSaveAction = QAction("Save commands for interactive mode", self)

self.interactiveSaveAction.setCheckable(True)

self.interactiveSaveAction.setToolTip("Whether the current command list for the interactive session should be saved on program exit.")

 

fontAction = QAction("Choose Font...", self)

fontAction.setToolTip("Show a dialog that allows choosing the font to use")

self.connect(fontAction, SIGNAL("triggered()"), self.chooseFont)

 

optionsbutton = QToolButton()

optionsbutton.setPopupMode(QToolButton.InstantPopup)

optionsbutton.setText("Options")

options = QMenu("Options", optionsbutton)

options.addAction(self.autoSaveAction)

options.addAction(self.interactiveSaveAction)

options.addAction(fontAction)

optionsbutton.setMenu(options)

toolbar.addSeparator()

toolbar.addWidget(optionsbutton)

 

self.filename = ""

self.ffont = None

 

self.loadSettings()

 

def closeEvent(self, event):

if self.editTextBox.dirty:

reply = QMessageBox.question(self, "Question", "Would you like to save your changes before quitting?",

QMessageBox.Save, QMessageBox.Discard, QMessageBox.Cancel)

if reply == QMessageBox.Save:

self.saveFile()

elif reply == QMessageBox.Cancel:

event.ignore()

return

event.accept()

self.saveSettings()

 

def runHugs(self):

code = self.editTextBox.toPlainText()

if code != "":

if (not self.autoSaveAction.isChecked()) or self.filename == "":

hsfile = NamedTemporaryFile(delete=False)

hsfilepath = hsfile.name

hsfile.file.write(code)

hsfile.file.close()

else:

if self.editTextBox.dirty:

self.saveFile()

hsfilepath = self.filename

else:

hsfilepath = ""

self.outputTextBox.setText("")

echo = self.commandTextBox.toPlainText()

if echo == "":

echo = ":q"

else:

echo = ":set +t\n" + echo

inputfile = NamedTemporaryFile(delete=False)

inputfilepath = inputfile.name

inputfile.file.write(echo)

inputfile.file.close()

if hsfilepath != "":

execstring = str("hugs " + hsfilepath + " < " + inputfilepath)

hugs_out = Popen(execstring, shell=True, stdout=PIPE)

else:

execstring = str("hugs < " + inputfilepath)

hugs_out = Popen(execstring, shell=True, stdout=PIPE)

hugs_out.wait()

show = 0

linenumber = 0

self.editTextBox.resetErrorHighlight()

self.commandTextBox.resetErrorHighlight()

while True:

l = hugs_out.stdout.readline()

if l.rstrip().endswith("> [Leaving Hugs]"): 

break

if l.startswith("Type :? for help") or l.startswith("Haskell 98 mode"):

show = 1

elif show == 1:

show = 2

if show == 2 and re.match(r"(.*?)> \1>", l) is not None:

l = l.partition("> ")[2]

show = 3

if show >= 2:

self.outputTextBox.append(l.strip())

if l.startswith("Hugs> ") or l.startswith("Main> "):

if l.startswith("Hugs> ERROR") or l.startswith("Main> ERROR"):

self.commandTextBox.highlightError(linenumber)

linenumber += 1

if l.startswith("ERROR"):

self.highlightError(l)

# clean up

if self.filename == "" and hsfilepath != "":

os.remove(hsfilepath)

os.remove(inputfilepath)

 

def highlightError(self, line):

linenumber = int(re.match(r"ERROR \".*?\":(\d+) ", line).group(1)) - 1

self.editTextBox.highlightError(linenumber)

 

def newFile(self):

if self.editTextBox.dirty:

reply = QMessageBox.question(self, "Question", "Would you like to save your changes before creating a new file?",

QMessageBox.Save, QMessageBox.Discard, QMessageBox.Cancel)

if reply == QMessageBox.Save:

self.saveFile()

elif reply == QMessageBox.Cancel:

return

self.editTextBox.clearInitially()

self.editTextBox.dirty = False

self.editTextBox.loadedFile = False

self.filename = ""

 

def openFile(self):

if self.editTextBox.dirty:

reply = QMessageBox.question(self, "Question", "Would you like to save your changes before loading another file?",

QMessageBox.Save, QMessageBox.Discard, QMessageBox.Cancel)

if reply == QMessageBox.Save:

self.saveFile()

elif reply == QMessageBox.Cancel:

return

filename = QFileDialog.getOpenFileName(self, "Open file", QString(), fileFilter)

if filename != "":

self.filename = filename

self.editTextBox.clearInitially()

with open(filename) as f:

self.editTextBox.setPlainText("".join(f.readlines()))

self.editTextBox.dirty = False

self.editTextBox.loadedFile = True

 

def saveFileAs(self):

filename = "" + QFileDialog.getSaveFileName(self, "Save file", "untitled.hs", fileFilter).toUtf8()

if filename != "":

self.filename = filename

self.saveFile()

 

def saveFile(self):

if self.filename == "":

self.saveFileAs()

else:

with open(self.filename, ‘w‘) as f:

f.write(self.editTextBox.toPlainText())

self.editTextBox.dirty = False

 

def chooseFont(self):

(selectedfont, ok) = QFontDialog.getFont(self.editTextBox.textCursor().charFormat().font(), self)

if ok:

self.ffont = selectedfont

self.setAllFonts()

 

def setAllFonts(self):

self.editTextBox.resetFont(self.ffont)

self.commandTextBox.resetFont(self.ffont)

self.outputTextBox.resetFont(self.ffont)

 

def saveSettings(self):

settingsfile = QDir.home().absoluteFilePath(settingsFileName)

settings = QSettings(settingsfile, QSettings.IniFormat)

settings.setValue("View/Size", self.size())

settings.setValue("View/Split", self.splitter.sizes())

settings.setValue("Settings/SaveOnRun", self.autoSaveAction.isChecked())

settings.setValue("Settings/SaveInteractive", self.interactiveSaveAction.isChecked())

if self.interactiveSaveAction.isChecked():

settings.setValue("Interactive/Commands", self.commandTextBox.toPlainText())

if self.ffont != None:

settings.setValue("Settings/Font", self.ffont)

 

def loadSettings(self):

settingsfile = QDir.home().absoluteFilePath(settingsFileName)

settings = QSettings(settingsfile, QSettings.IniFormat)

self.resize(settings.value("View/Size", QSize(800, 500)).toSize())

splits = settings.value("View/Split", [154, 154, 154]).toList()

for i in range(len(splits)):

(splits[i], ok) = splits[i].toInt() #@UnusedVariable

if splits[i] < 10:

splits[i] = 10

self.splitter.setSizes(splits)

self.autoSaveAction.setChecked(settings.value("Settings/SaveOnRun", True).toBool())

self.interactiveSaveAction.setChecked(settings.value("Settings/SaveInteractive", False).toBool())

if self.interactiveSaveAction.isChecked():

self.commandTextBox.clearInitially()

self.commandTextBox.setPlainText(settings.value("Interactive/Commands", "").toString())

settingsfont = settings.value("Settings/Font", None)

if not settingsfont == QVariant(None):

self.ffont = QFont(settingsfont)

self.setAllFonts()

 

if __name__ == ‘__main__‘:

app = QApplication(sys.argv)

 

mainwin = HugsGUI()

mainwin.show()

 

sys.exit(app.exec_())

 技术分享

pyqt练习x3.11


推荐阅读
  • 本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • QUIC协议:快速UDP互联网连接
    QUIC(Quick UDP Internet Connections)是谷歌开发的一种旨在提高网络性能和安全性的传输层协议。它基于UDP,并结合了TLS级别的安全性,提供了更高效、更可靠的互联网通信方式。 ... [详细]
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • CSS 布局:液态三栏混合宽度布局
    本文介绍了如何使用 CSS 实现液态的三栏布局,其中各栏具有不同的宽度设置。通过调整容器和内容区域的属性,可以实现灵活且响应式的网页设计。 ... [详细]
  • Linux 系统启动故障排除指南:MBR 和 GRUB 问题
    本文详细介绍了 Linux 系统启动过程中常见的 MBR 扇区和 GRUB 引导程序故障及其解决方案,涵盖从备份、模拟故障到恢复的具体步骤。 ... [详细]
  • 导航栏样式练习:项目实例解析
    本文详细介绍了如何创建一个具有动态效果的导航栏,包括HTML、CSS和JavaScript代码的实现,并附有详细的说明和效果图。 ... [详细]
  • 国内BI工具迎战国际巨头Tableau,稳步崛起
    尽管商业智能(BI)工具在中国的普及程度尚不及国际市场,但近年来,随着本土企业的持续创新和市场推广,国内主流BI工具正逐渐崭露头角。面对国际品牌如Tableau的强大竞争,国内BI工具通过不断优化产品和技术,赢得了越来越多用户的认可。 ... [详细]
  • 在 Windows 10 中,F1 至 F12 键默认设置为快捷功能键。本文将介绍几种有效方法来禁用这些快捷键,并恢复其标准功能键的作用。请注意,部分笔记本电脑的快捷键可能无法完全关闭。 ... [详细]
  • 本文总结了2018年的关键成就,包括职业变动、购车、考取驾照等重要事件,并分享了读书、工作、家庭和朋友方面的感悟。同时,展望2019年,制定了健康、软实力提升和技术学习的具体目标。 ... [详细]
  • 在计算机技术的学习道路上,51CTO学院以其专业性和专注度给我留下了深刻印象。从2012年接触计算机到2014年开始系统学习网络技术和安全领域,51CTO学院始终是我信赖的学习平台。 ... [详细]
  • 本文介绍了如何使用jQuery根据元素的类型(如复选框)和标签名(如段落)来获取DOM对象。这有助于更高效地操作网页中的特定元素。 ... [详细]
  • 本文介绍如何在 Xcode 中使用快捷键和菜单命令对多行代码进行缩进,包括右缩进和左缩进的具体操作方法。 ... [详细]
  • 本文介绍了如何使用JQuery实现省市二级联动和表单验证。首先,通过change事件监听用户选择的省份,并动态加载对应的城市列表。其次,详细讲解了使用Validation插件进行表单验证的方法,包括内置规则、自定义规则及实时验证功能。 ... [详细]
author-avatar
平凡快乐的girl_819
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有