#!/usr/bin/python
#coding=utf-8
from PySide.QtCore import *
from PySide.QtGui import *
import sys
customRightClicked = Signal()
def __init__(self, parent=None):
def eventFilter(self, obj, event):
if event.
type() == QEvent.
ContextMenu: # emit signal so that your widgets can connect a slot to that signal
self.customRightClicked.emit()
return True
else:
# standard event processing
return QObject.
eventFilter(self, obj, event
)
def __init__(self, line_edit, init_text, tab_widget, tab_index, description):
self._line_edit = line_edit
self._current_text = line_edit.text()
self._init_text = init_text
self._tab_widget = tab_widget
self._tab_index = tab_index
def undo(self):
self._line_edit.setText(self._init_text)
self._tab_widget.setCurrentIndex(self._tab_index)
self._line_edit.setFocus(Qt.OtherFocusReason)
def redo(self):
self._line_edit.setText(self._current_text)
self._tab_widget.setCurrentIndex(self._tab_index)
self._line_edit.setFocus(Qt.OtherFocusReason)
def __init__(self, parent, tab_widget, tab_index):
super(CustomLineEdit, self).__init__(parent)
self.parent = parent
self.tab_widget = tab_widget
self.tab_index = tab_index
self.init_text = self.text()
self.setContextMenuPolicy(Qt.CustomContextMenu)
undoAction.triggered.connect(self.parent.undo_stack.undo)
self.
customContextMenu = QMenu() self.customContextMenu.addAction(undoAction)
custom_clicker = CustomRightClick(self)
self.installEventFilter(custom_clicker)
self.right_clicked = False
custom_clicker.customRightClicked.connect(self.menuShow)
def menuShow(self):
self.right_clicked = True # set self.right_clicked to True so that the focusOutEvent won't push anything to the undo stack as a consequence of right-clicking
self.
customContextMenu.
popup(QCursor.
pos()) self.right_clicked = False
# re-implement focusInEvent() so that it captures as an instance variable the current value of the text *at the time of the focusInEvent(). This will be utilized for the undo stack command push below
def focusInEvent(self, event):
self.init_text = self.text()
# re-implement focusOutEvent() so that it pushes the current text to the undo stack.... but only if there was a change!
def focusOutEvent(self, event):
if self.text() != self.init_text and not self.right_clicked:
print "Focus out event. (self.text is %s and init_text is %s). Pushing onto undo stack. (Event reason is %s)" % (self.text(), self.init_text, event.reason())
command = CommandLineEdit(self, self.init_text, self.tab_widget, self.tab_index, "editing a text box")
self.parent.undo_stack.push(command)
def keyPressEvent(self, event):
if event.key() == Qt.Key_Z:
if event.modifiers() & Qt.ControlModifier:
self.parent.undo_stack.undo()
else:
elif event.key() == Qt.Key_Y:
if event.modifiers() & Qt.ControlModifier:
self.parent.undo_stack.redo()
else:
else:
def __init__(self, parent=None):
super(Form, self).__init__(parent)
self.line_edit1 = CustomLineEdit(self, self.tab_widget, 0)
self.line_edit2 = CustomLineEdit(self, self.tab_widget, 1)
tab1layout.addWidget(self.line_edit1)
tab1widget.setLayout(tab1layout)
tab2layout.addWidget(self.line_edit2)
tab2widget.setLayout(tab2layout)
self.tab_widget.addTab(tab1widget, "Tab 1")
self.tab_widget.addTab(tab2widget, "Tab 2")
layout.addWidget(self.tab_widget, 0, 0, 1, 2)
layout.addWidget(self.undo_button, 1, 0)
layout.addWidget(self.redo_button, 1, 1)
layout.
addWidget(QLabel("Undo Stack Counter"),
2,
0) layout.addWidget(self.undo_counter)
self.setLayout(layout)
self.undo_button.clicked.connect(self.undo_stack.undo)
self.redo_button.clicked.connect(self.undo_stack.redo)
self.undo_stack.indexChanged.connect(self.changeUndoCount)
def changeUndoCount(self, index):
self.undo_counter.setText("%s / %s" % (index, self.undo_stack.count()))
form = Form()
form.show()
app.exec_()
#!/usr/bin/python
#coding=utf-8
from PySide.QtCore import *
from PySide.QtGui import *
import sys
class CustomRightClick(QObject):
customRightClicked = Signal()
def __init__(self, parent=None):
QObject.__init__(self, parent)
def eventFilter(self, obj, event):
if event.type() == QEvent.ContextMenu:
# emit signal so that your widgets can connect a slot to that signal
self.customRightClicked.emit()
return True
else:
# standard event processing
return QObject.eventFilter(self, obj, event)
class CommandLineEdit(QUndoCommand):
def __init__(self, line_edit, init_text, tab_widget, tab_index, description):
QUndoCommand.__init__(self, description)
self._line_edit = line_edit
self._current_text = line_edit.text()
self._init_text = init_text
self._tab_widget = tab_widget
self._tab_index = tab_index
def undo(self):
self._line_edit.setText(self._init_text)
self._tab_widget.setCurrentIndex(self._tab_index)
self._line_edit.setFocus(Qt.OtherFocusReason)
def redo(self):
self._line_edit.setText(self._current_text)
self._tab_widget.setCurrentIndex(self._tab_index)
self._line_edit.setFocus(Qt.OtherFocusReason)
class CustomLineEdit(QLineEdit):
def __init__(self, parent, tab_widget, tab_index):
super(CustomLineEdit, self).__init__(parent)
self.parent = parent
self.tab_widget = tab_widget
self.tab_index = tab_index
self.init_text = self.text()
self.setContextMenuPolicy(Qt.CustomContextMenu)
undoAction=QAction("Undo", self)
undoAction.triggered.connect(self.parent.undo_stack.undo)
self.customContextMenu = QMenu()
self.customContextMenu.addAction(undoAction)
custom_clicker = CustomRightClick(self)
self.installEventFilter(custom_clicker)
self.right_clicked = False
custom_clicker.customRightClicked.connect(self.menuShow)
def menuShow(self):
self.right_clicked = True # set self.right_clicked to True so that the focusOutEvent won't push anything to the undo stack as a consequence of right-clicking
self.customContextMenu.popup(QCursor.pos())
self.right_clicked = False
# re-implement focusInEvent() so that it captures as an instance variable the current value of the text *at the time of the focusInEvent(). This will be utilized for the undo stack command push below
def focusInEvent(self, event):
self.init_text = self.text()
QLineEdit.focusInEvent(self, event)
# re-implement focusOutEvent() so that it pushes the current text to the undo stack.... but only if there was a change!
def focusOutEvent(self, event):
if self.text() != self.init_text and not self.right_clicked:
print "Focus out event. (self.text is %s and init_text is %s). Pushing onto undo stack. (Event reason is %s)" % (self.text(), self.init_text, event.reason())
command = CommandLineEdit(self, self.init_text, self.tab_widget, self.tab_index, "editing a text box")
self.parent.undo_stack.push(command)
QLineEdit.focusOutEvent(self, event)
def keyPressEvent(self, event):
if event.key() == Qt.Key_Z:
if event.modifiers() & Qt.ControlModifier:
self.parent.undo_stack.undo()
else:
QLineEdit.keyPressEvent(self, event)
elif event.key() == Qt.Key_Y:
if event.modifiers() & Qt.ControlModifier:
self.parent.undo_stack.redo()
else:
QLineEdit.keyPressEvent(self, event)
else:
QLineEdit.keyPressEvent(self, event)
class Form(QDialog):
def __init__(self, parent=None):
super(Form, self).__init__(parent)
self.undo_stack = QUndoStack()
self.tab_widget = QTabWidget()
self.line_edit1 = CustomLineEdit(self, self.tab_widget, 0)
self.line_edit2 = CustomLineEdit(self, self.tab_widget, 1)
self.undo_counter = QLineEdit()
tab1widget = QWidget()
tab1layout = QHBoxLayout()
tab1layout.addWidget(self.line_edit1)
tab1widget.setLayout(tab1layout)
tab2widget = QWidget()
tab2layout = QHBoxLayout()
tab2layout.addWidget(self.line_edit2)
tab2widget.setLayout(tab2layout)
self.tab_widget.addTab(tab1widget, "Tab 1")
self.tab_widget.addTab(tab2widget, "Tab 2")
self.undo_button = QPushButton("Undo")
self.redo_button = QPushButton("Redo")
layout = QGridLayout()
layout.addWidget(self.tab_widget, 0, 0, 1, 2)
layout.addWidget(self.undo_button, 1, 0)
layout.addWidget(self.redo_button, 1, 1)
layout.addWidget(QLabel("Undo Stack Counter"), 2, 0)
layout.addWidget(self.undo_counter)
self.setLayout(layout)
self.undo_button.clicked.connect(self.undo_stack.undo)
self.redo_button.clicked.connect(self.undo_stack.redo)
self.undo_stack.indexChanged.connect(self.changeUndoCount)
def changeUndoCount(self, index):
self.undo_counter.setText("%s / %s" % (index, self.undo_stack.count()))
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
To copy to clipboard, switch view to plain text mode
Bookmarks