Skip to content

Commit 1a540f9

Browse files
committed
Extend Python Example
1 parent e011608 commit 1a540f9

10 files changed

Lines changed: 694 additions & 51 deletions

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
/build
2-
/__pycache__
2+
/**/__pycache__
33
/.venv

python/example/example.py

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
#!/usr/bin/env python
2+
3+
import sys
4+
5+
try:
6+
from PyQt5 import QtWidgets, QtCore, QtGui
7+
except:
8+
from PyQt5 import QtWidgets, QtCore, QtGui
9+
10+
from QHexEdit import QHexEdit
11+
12+
import qhexedit_rc
13+
14+
15+
class MainWindow(QtWidgets.QMainWindow):
16+
17+
def __init__(self, fileName=None):
18+
super(MainWindow, self).__init__()
19+
self.init()
20+
self.setCurrentFile('')
21+
22+
def about(self):
23+
QtWidgets.QMessageBox.about(self, "About HexEdit",
24+
"The HexEdit example is a short Demo of the QHexEdit Widget.");
25+
26+
def closeEvent(self, event):
27+
self.writeSettings()
28+
self.close()
29+
30+
def createActions(self):
31+
self.openAct = QtWidgets.QAction(QtGui.QIcon(':/images/open.png'),
32+
"&Open...", self, shortcut=QtGui.QKeySequence.Open,
33+
statusTip="Open an existing file", triggered=self.open)
34+
35+
self.saveAct = QtWidgets.QAction(QtGui.QIcon(':/images/save.png'),
36+
"&Save", self, shortcut=QtGui.QKeySequence.Save,
37+
statusTip="Save the document to disk", triggered=self.save)
38+
39+
self.saveAsAct = QtWidgets.QAction("Save &As...", self,
40+
shortcut=QtGui.QKeySequence.SaveAs,
41+
statusTip="Save the document under a new name", triggered=self.saveAs)
42+
43+
self.saveReadable = QtWidgets.QAction("Save as &Readable...", self,
44+
statusTip="Save in a readable format", triggered=self.saveToReadableFile)
45+
46+
self.exitAct = QtWidgets.QAction("E&xit", self, shortcut="Ctrl+Q",
47+
statusTip="Exit the application", triggered=self.close)
48+
49+
self.undoAct = QtWidgets.QAction(QtGui.QIcon(':/images/undo.png'),
50+
"&Undo", self, shortcut=QtGui.QKeySequence.Undo, triggered=self.hexEdit.undo)
51+
52+
self.redoAct = QtWidgets.QAction(QtGui.QIcon(':/images/redo.png'),
53+
"&Redo", self, shortcut=QtGui.QKeySequence.Redo, triggered=self.hexEdit.redo)
54+
55+
self.saveSelectionReadable = QtWidgets.QAction("Save Selection Readable...", self,
56+
statusTip="Save selection in a readable format",
57+
triggered=self.saveSelectionToReadableFile)
58+
59+
self.aboutAct = QtWidgets.QAction("&About", self,
60+
statusTip="Show the application's About box", triggered=self.about)
61+
62+
self.findAct = QtWidgets.QAction("&Find/Replace", self, shortcut=QtGui.QKeySequence.Find,
63+
statusTip="Show the Dialog for finding and replacing", triggered=self.showSearchDialog)
64+
65+
self.findNextAct = QtWidgets.QAction("Find &next", self, shortcut=QtGui.QKeySequence.FindNext,
66+
statusTip="Find next occurrence of the searched pattern", triggered=self.findNext)
67+
68+
self.optionsAct = QtWidgets.QAction("&Options", self,
69+
statusTip="Show the options dialog", triggered=self.showOptionsDialog)
70+
71+
def createMenus(self):
72+
self.fileMenu = self.menuBar().addMenu("&File")
73+
self.fileMenu.addAction(self.openAct)
74+
self.fileMenu.addAction(self.saveAct)
75+
self.fileMenu.addAction(self.saveAsAct)
76+
self.fileMenu.addAction(self.saveReadable)
77+
self.fileMenu.addSeparator()
78+
self.fileMenu.addAction(self.exitAct)
79+
80+
self.editMenu = self.menuBar().addMenu("&Edit")
81+
self.editMenu.addAction(self.undoAct)
82+
self.editMenu.addAction(self.redoAct)
83+
self.editMenu.addAction(self.saveSelectionReadable)
84+
85+
self.helpMenu = self.menuBar().addMenu("&Help")
86+
self.helpMenu.addAction(self.aboutAct)
87+
88+
def createStatusBar(self):
89+
# Address Label
90+
self.lbAddressName = QtWidgets.QLabel()
91+
self.lbAddressName.setText("Address:")
92+
self.statusBar().addPermanentWidget(self.lbAddressName)
93+
self.lbAddress = QtWidgets.QLabel()
94+
self.lbAddress.setFrameShape(QtWidgets.QFrame.Panel)
95+
self.lbAddress.setFrameShadow(QtWidgets.QFrame.Sunken)
96+
self.lbAddress.setMinimumWidth(70)
97+
self.statusBar().addPermanentWidget(self.lbAddress)
98+
self.hexEdit.currentAddressChanged.connect(self.setAddress)
99+
100+
# Address Size
101+
self.lbSizeName = QtWidgets.QLabel()
102+
self.lbSizeName.setText("Size:")
103+
self.statusBar().addPermanentWidget(self.lbSizeName)
104+
self.lbSize = QtWidgets.QLabel()
105+
self.lbSize.setFrameShape(QtWidgets.QFrame.Panel)
106+
self.lbSize.setFrameShadow(QtWidgets.QFrame.Sunken)
107+
self.lbSize.setMinimumWidth(70)
108+
self.statusBar().addPermanentWidget(self.lbSize)
109+
self.hexEdit.currentSizeChanged.connect(self.setSize)
110+
111+
# Overwrite Mode label
112+
self.lbOverwriteModeName = QtWidgets.QLabel()
113+
self.lbOverwriteModeName.setText("Mode:")
114+
self.statusBar().addPermanentWidget(self.lbOverwriteModeName)
115+
self.lbOverwriteMode = QtWidgets.QLabel()
116+
self.lbOverwriteMode.setFrameShape(QtWidgets.QFrame.Panel)
117+
self.lbOverwriteMode.setFrameShadow(QtWidgets.QFrame.Sunken)
118+
self.lbOverwriteMode.setMinimumWidth(70)
119+
self.statusBar().addPermanentWidget(self.lbOverwriteMode)
120+
self.setOverwriteMode(self.hexEdit.overwriteMode())
121+
122+
self.statusBar().showMessage("Ready")
123+
124+
def createToolBars(self):
125+
self.fileToolBar = self.addToolBar("File")
126+
self.fileToolBar.addAction(self.openAct)
127+
self.fileToolBar.addAction(self.saveAct)
128+
self.fileToolBar.addAction(self.undoAct)
129+
self.fileToolBar.addAction(self.redoAct)
130+
131+
def init(self):
132+
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
133+
self.isUntitled = True
134+
135+
self.hexEdit = QHexEdit()
136+
self.setCentralWidget(self.hexEdit)
137+
self.hexEdit.overwriteModeChanged.connect(self.setOverwriteMode)
138+
139+
self.createActions()
140+
self.createMenus()
141+
self.createToolBars()
142+
self.createStatusBar()
143+
144+
self.readSettings()
145+
146+
def loadFile(self, fileName):
147+
file = QtCore.QFile(fileName)
148+
if not file.open( QtCore.QFile.ReadOnly | QtCore.QFile.Text):
149+
QtWidgets.QMessageBox.warning(self, "QHexEdit",
150+
"Cannot read file %s:\n%s." % (fileName, file.errorString()))
151+
return
152+
153+
QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)
154+
self.hexEdit.setData(file.readAll())
155+
QtWidgets.QApplication.restoreOverrideCursor()
156+
157+
self.setCurrentFile(fileName)
158+
self.statusBar().showMessage("File loaded", 2000)
159+
160+
def open(self):
161+
fileName, _filter = QtWidgets.QFileDialog.getOpenFileName(self)
162+
if fileName:
163+
self.loadFile(fileName)
164+
165+
def optionsAccepted(self):
166+
self.writeSettings()
167+
self.readSettings()
168+
169+
def findNext(self):
170+
self.searchDialog.findNext()
171+
172+
def readSettings(self):
173+
settings = QtCore.QSettings()
174+
175+
pos = settings.value('pos', QtCore.QPoint(200, 200))
176+
size = settings.value('size', QtCore.QSize(610, 460))
177+
self.hexEdit.setAddressArea(settings.value("AddressArea")=='true')
178+
self.hexEdit.setAsciiArea(settings.value("AsciiArea")=='true')
179+
self.hexEdit.setHighlighting(settings.value("Highlighting")=='true')
180+
self.hexEdit.setOverwriteMode(settings.value("OverwriteMode")=='true')
181+
self.hexEdit.setReadOnly(settings.value("ReadOnly")=='true')
182+
183+
self.hexEdit.setHighlightingColor(QtGui.QColor(settings.value("HighlightingColor")))
184+
self.hexEdit.setAddressAreaColor(QtGui.QColor(settings.value("AddressAreaColor")))
185+
self.hexEdit.setSelectionColor(QtGui.QColor(settings.value("SelectionColor")))
186+
self.hexEdit.setFont(QtGui.QFont(settings.value("WidgetFont", QtGui.QFont(QtGui.QFont("Courier New", 10)))))
187+
188+
self.hexEdit.setAddressWidth(int(settings.value("AddressAreaWidth")));
189+
self.move(pos)
190+
self.resize(size)
191+
192+
def save(self):
193+
if self.isUntitled:
194+
return self.saveAs()
195+
else:
196+
return self.saveFile(self.curFile)
197+
198+
def saveAs(self):
199+
fileName, _filter = QtWidgets.QFileDialog.getSaveFileName(self, "Save As", self.curFile)
200+
if not fileName:
201+
return False
202+
return self.saveFile(fileName)
203+
204+
def showOptionsDialog(self):
205+
self.optionsDialog.show()
206+
207+
def showSearchDialog(self):
208+
self.searchDialog.show()
209+
210+
def setAddress(self, address):
211+
self.lbAddress.setText('%x' % address)
212+
213+
def setOverwriteMode(self, mode):
214+
settings = QtCore.QSettings()
215+
settings.setValue("OverwriteMode", mode)
216+
if mode:
217+
self.lbOverwriteMode.setText("Overwrite")
218+
else:
219+
self.lbOverwriteMode.setText("Insert")
220+
221+
def setSize(self, size):
222+
self.lbSize.setText('%d' % size)
223+
224+
def saveFile(self, fileName):
225+
file = QtCore.QFile(fileName)
226+
if not file.open( QtCore.QFile.WriteOnly | QtCore.QFile.Truncate):
227+
QtWidgets.QMessageBox.warning(self, "HexEdit",
228+
"Cannot write file %s:\n%s." % (fileName, file.errorString()))
229+
return False
230+
231+
file.write(self.hexEdit.data())
232+
233+
self.setCurrentFile(fileName)
234+
self.statusBar().showMessage("File saved", 2000)
235+
return True
236+
237+
def saveToReadableFile(self):
238+
fileName, _filter = QtWidgets.QFileDialog.getSaveFileName(self, "Save To Readable File")
239+
if fileName != "":
240+
file = open(str(fileName), "w")
241+
file.write(str(self.hexEdit.toReadableString()))
242+
self.statusBar().showMessage("File saved", 2000);
243+
244+
def saveSelectionToReadableFile(self):
245+
fileName, _filter = QtWidgets.QFileDialog.getSaveFileName(self, "Save To Readable File")
246+
if fileName != "":
247+
file = open(str(fileName), "w")
248+
file.write(str(self.hexEdit.selectionToReadableString()))
249+
self.statusBar().showMessage("File saved", 2000);
250+
251+
def setCurrentFile(self, fileName):
252+
self.curFile = fileName
253+
self.isUntitled = (fileName == "")
254+
self.setWindowModified(False)
255+
self.setWindowTitle("%s[*] - QHexEdit" % self.strippedName(self.curFile))
256+
257+
def strippedName(self, fullFileName):
258+
return QtCore.QFileInfo(fullFileName).fileName()
259+
260+
def writeSettings(self):
261+
settings = QtCore.QSettings()
262+
settings.setValue('pos', self.pos())
263+
settings.setValue('size', self.size())
264+
265+
if __name__ == '__main__':
266+
app = QtWidgets.QApplication(sys.argv)
267+
app.setApplicationName("QHexEdit");
268+
app.setOrganizationName("QHexEdit");
269+
mainWin = MainWindow()
270+
mainWin.show()
271+
sys.exit(app.exec())

python/example/example_pyqt5.py

Lines changed: 0 additions & 25 deletions
This file was deleted.

python/example/example_pyqt6.py

Lines changed: 0 additions & 25 deletions
This file was deleted.

python/example/images/open.png

2.02 KB
Loading

python/example/images/redo.png

985 Bytes
Loading

python/example/images/save.png

1.16 KB
Loading

python/example/images/undo.png

962 Bytes
Loading

python/example/qhexedit.qrc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<!DOCTYPE RCC><RCC version="1.0">
2+
<qresource>
3+
<file>images/open.png</file>
4+
<file>images/redo.png</file>
5+
<file>images/save.png</file>
6+
<file>images/undo.png</file>
7+
</qresource>
8+
</RCC>

0 commit comments

Comments
 (0)