pyqt练习x3.11

#!/usr/bin/env python

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

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

#                                                                                      #

# Copyright (c) 2009 Jakob Kummerow <[email protected]>                         #

#                                                                                      #

# 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 <http://www.gnu.org/licenses/>.                           #

#                                                                                      #

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

"""

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_())

时间: 2024-08-03 16:53:15

pyqt练习x3.11的相关文章

pyqt练习x3

# -*- coding: utf-8 -*- __author__ = 'Administrator' from PyQt4 import QtCore,Qt,QtGui import sys,time,datetime,os,sched,psutil,wmi from tools import Ui_Form class ExTools(QtGui.QDialog): def __init__(self,parent=None): super(ExTools,self).__init__(p

pyqt练习x3.12

import sys from PyQt4.QtGui import * class Browser(QWidget): def __init__(self): super(Browser, self).__init__() self.resize(700, 600) self.setWindowTitle("File Browser") self.treeView = QTreeView() self.fileSystemModel = QFileSystemModel(self.t

pyqt练习x3.20

#_*_ coding: utf-8 _*_ from PyQt4.QtCore import * from PyQt4.QtGui import * import sys QTextCodec.setCodecForTr(QTextCodec.codecForName("utf8")) class FindDialog(QDialog): def __init__(self,parent = None): super(FindDialog, self).__init__(parent

pyqt练习x3.14

import sys from PyQt4.QtCore import * from PyQt4.QtGui import * from PyQt4.QtWebKit import * class MyBrowser(QWidget): def __init__(self, parent = None): super(MyBrowser, self).__init__(parent) self.createLayout() self.createConnection() def search(s

pyqt练习x3.13

import time import ctypes import ctypes.wintypes SEE_MASK_NOCLOSEPROCESS = 0x00000040 SEE_MASK_INVOKEIDLIST = 0x0000000C class SHELLEXECUTEINFO(ctypes.Structure): _fields_ = ( ("cbSize",ctypes.wintypes.DWORD), ("fMask",ctypes.c_ulong),

pyqt练习x3.21

#!/usr/bin/env python2 "A web browser that will never exceed 128 lines of code. (not counting blanks)" import sys, os, json, tempfile from PyQt4 import QtGui, QtCore, QtWebKit, QtNetwork settings = QtCore.QSettings("ralsina", "dev

pyqt练习x3。1

# -*- coding: cp936 -*- import sys from PyQt4 import QtGui class MessageBox(QtGui.QWidget): def __init__(self,parent=None): QtGui.QWidget.__init__(self,parent) self.setGeometry(300,300,250,150) self.setWindowTitle(u'你想关闭?') def closeEvent(self,event)

pyqt练习x3.3

# -*- coding: cp936 -*- import sys from PyQt4 import QtGui class Tooltip(QtGui.QWidget): def __init__(self,parent=None): QtGui.QWidget.__init__(self,parent) self.setGeometry(300,300,250,150) self.setWindowTitle(u'屏幕提示内容') self.setToolTip(u'这是什么呢?') Q

pyqt练习x3.7

# -*- coding: cp936 -*- import sys from PyQt4 import QtGui,QtCore class GridLayout(QtGui.QWidget): def __init__(self,parent=None): QtGui.QWidget.__init__(self) self.setWindowTitle('grid layout') title=QtGui.QLabel('Titel:') authot=QtGui.QLabel('Auhot