热门标签 | 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


推荐阅读
  • 深入解析Unity3D游戏开发中的音频播放技术
    在游戏开发中,音频播放是提升玩家沉浸感的关键因素之一。本文将探讨如何在Unity3D中高效地管理和播放不同类型的游戏音频,包括背景音乐和效果音效,并介绍实现这些功能的具体步骤。 ... [详细]
  • 本文由公众号【数智物语】(ID: decision_engine)发布,关注获取更多干货。文章探讨了从数据收集到清洗、建模及可视化的全过程,介绍了41款实用工具,旨在帮助数据科学家和分析师提升工作效率。 ... [详细]
  • 本文介绍了一个来自AIZU ONLINE JUDGE平台的问题,即清洁机器人2.0。该问题来源于某次编程竞赛,涉及复杂的算法逻辑与实现技巧。 ... [详细]
  • egg实现登录鉴权(七):权限管理
    权限管理包含三部分:访问页面的权限,操作功能的权限和获取数据权限。页面权限:登录用户所属角色的可访问页面的权限功能权限:登录用户所属角色的可访问页面的操作权限数据权限:登录用户所属 ... [详细]
  • 本文介绍了用户界面(User Interface, UI)的基本概念,以及在iOS应用程序中UIView及其子类的重要性和使用方式。文章详细探讨了UIView如何作为用户交互的核心组件,以及它与其他UI控件和业务逻辑的关系。 ... [详细]
  • 本文探讨了线性表中元素的删除方法,包括顺序表和链表的不同实现策略,以及这些策略在实际应用中的性能分析。 ... [详细]
  • 实现Win10与Linux服务器的SSH无密码登录
    本文介绍了如何在Windows 10环境下使用Git工具,通过配置SSH密钥对,实现与Linux服务器的无密码登录。主要步骤包括生成本地公钥、上传至服务器以及配置服务器端的信任关系。 ... [详细]
  • 本文由chszs撰写,详细介绍了Apache Mina框架的核心开发流程及自定义协议处理方法。文章涵盖从创建IoService实例到协议编解码的具体步骤,适合希望深入了解Mina框架应用的开发者。 ... [详细]
  • 本文提供了一个关于AC自动机(Aho-Corasick Algorithm)的详细解析与实现方法,特别针对P3796题目进行了深入探讨。文章不仅涵盖了AC自动机的基本概念,还重点讲解了如何通过构建失败指针(fail pointer)来提高字符串匹配效率。 ... [详细]
  • 本报告记录了嵌入式软件设计课程中的第二次实验,主要探讨了使用KEIL V5开发环境和ST固件库进行GPIO控制及按键响应编程的方法。通过实际操作,加深了对嵌入式系统硬件接口编程的理解。 ... [详细]
  • LeetCode 102 - 二叉树层次遍历详解
    本文详细解析了LeetCode第102题——二叉树的层次遍历问题,提供了C++语言的实现代码,并对算法的核心思想和具体步骤进行了深入讲解。 ... [详细]
  • 本文回顾了作者在求职阿里和腾讯实习生过程中,从最初的迷茫到最后成功获得Offer的心路历程。文中不仅分享了个人的面试经历,还提供了宝贵的面试准备建议和技巧。 ... [详细]
  • Python3爬虫入门:pyspider的基本使用[python爬虫入门]
    Python学习网有大量免费的Python入门教程,欢迎大家来学习。本文主要通过爬取去哪儿网的旅游攻略来给大家介绍pyspid ... [详细]
  • 探讨如何在映射文件中处理重复的属性字段,以避免数据操作时出现错误。 ... [详细]
  • 网络流24题——试题库问题
    题目描述:假设一个试题库中有n道试题。每道试题都标明了所属类别。同一道题可能有多个类别属性。现要从题库中抽取m道题组成试卷。并要求试卷包含指定类型的试题。试设计一个满足要求的组卷算 ... [详细]
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社区 版权所有