Pyside keypress event for textedit - python

I have 2 QTextEdit widgets and I need to put whatever is entered in the first to the second on a press of the enter key (Return).... I am not able to implement it please help?
I know I need to use KeyPressEvent but I don't understand how to use it only for the QTextEdit??
self.textEdit = QtGui.QTextEdit(self.widget)
self.textEdit.setMinimumSize(QtCore.QSize(201, 291))
self.textEdit.setMaximumSize(QtCore.QSize(201, 291))
self.textEdit.setObjectName("textEdit")
self.textEdit.setReadOnly(True)
self.verticalLayout.addWidget(self.textEdit)
self.textEdit_2 = QtGui.QTextEdit(self.widget)
self.textEdit_2.setMinimumSize(QtCore.QSize(201, 41))
self.textEdit_2.setMaximumSize(QtCore.QSize(201, 41))
self.textEdit_2.setObjectName("textEdit_2")
self.textEdit_2.setFocusPolicy(Qt.StrongFocus)
self.verticalLayout.addWidget(self.textEdit_2)
Any help is appreciated I am stuck.....

Use the viewportEvent (inherited from QAbstractScrollArea)
self.textEdit.viewportEvent.connect(self.copy_the_text)
def copy_the_text(self, event):
if isinstance(event, QtGui.QKeyEvent): # as viewportEvent gets *all* events
if event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter:
# copy the text from textEdit to textEdit_2
You can use Qt.Key_Enter but I think you probably want Qt.Key_Return
EDIT
If you are using an older version of PySide without new style signals and slots you'll need to use
self.connect(self.textEdit, SIGNAL("viewportEvent(event)"), self.copy_the_text)

Here is a small example that shows QLineEdit and its returnPressed signal. Upon pressing return the text in the QLineEdit will be appended to the QTextEdit:
import sys
from PySide import QtGui
class Window(QtGui.QWidget):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.output = QtGui.QTextEdit()
self.output.setReadOnly(True)
self.input = QtGui.QLineEdit()
self.input.returnPressed.connect(self.addInput)
self.input.setPlaceholderText('input here')
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.output)
layout.addWidget(self.input)
def addInput(self):
# skip empty text
if self.input.text():
self.output.append(self.input.text())
# clear the QLineEdit for new input
self.input.clear()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())

Related

How do I get the current text from a QcomboBox with PyQt5 using a button?

Funny that this isn't better documented. But basically I'm just trying to get the value of a dropdown QComboBox in PyQT5 when I click a button.
Currently, when I use the following code, it is only giving me the value after I select a value in the dropdown. I am new to PyQt.
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.lineEdit = QLineEdit(self.centralwidget)
self.lineEdit.setObjectName("lineEdit")
self.templatetype = QComboBox(self.centralwidget)
self.templatetype.setObjectName("templatetype")
self.templatetype.addItem("Tracks")
self.templatetype.addItem("Observations")
self.templatetype.activated[str].connect(self.change_text)
self.btn = QPushButton(self.centralwidget)
self.btn.setObjectName("btn")
self.btn.clicked.connect(self.change_text)
def change_text(self,text):
self.lineEdit.setText(text)
Simple solution...
self.templatetype.activated[str].connect(self.change_text)
should be
self.templatetype.highlighted[str].connect(self.change_text)
Try it:
from PyQt5 import Qt
class MainWindow(Qt.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.main_widget = Qt.QWidget()
self.setCentralWidget(self.main_widget)
layout = Qt.QVBoxLayout(self.main_widget)
self.lineEdit = Qt.QLineEdit(self)
self.templatetype = Qt.QComboBox(self)
self.templatetype.addItem("Tracks")
self.templatetype.addItem("Observations")
self.templatetype.activated[str].connect(self.combo_text)
self.text = ""
self.btn = Qt.QPushButton("Button", self)
self.btn.clicked.connect(self.change_text)
layout.addWidget(self.lineEdit)
layout.addWidget(self.templatetype)
layout.addWidget(self.btn)
layout.setAlignment(Qt.Qt.AlignCenter)
def combo_text(self,text):
self.text = self.templatetype.currentText()
def change_text(self):
self.lineEdit.setText(self.text)
if __name__ == '__main__':
import sys
app = Qt.QApplication(sys.argv)
ex = MainWindow()
ex.show()
sys.exit(app.exec_())
I am not sure if I completely understood your question. You just want to get the text that is in the QComboBox when you click on the button? If that is the case then it's pretty simple. First you need to get the current text in the QComboBox then put it in the QLineEdit. Your don't need the to use a Signal here. So you can remove the following line:
self.templatetype.activated[str].connect(self.change_text)
And update your change_text method like this.
def change_text(self):
current_value = self.templatetype.currentText()
self.lineEdit.setText(current_value)

PyQt is executing my function multiple times after signal

I'm building a pyqt Qwidget with multiple QcomboBox in which the user can add items at will. But I also want to give the user the option to delete any of the items by clicking a QPushbutton.
Because I can't know in advance which comboBox and item the user will want to delete, I created an event filter to find which object is being activated, and which item is being selected.
The code below works as expected, but the function printevent is being called an increasingly number of times, which will eventually turn my program very slow.
I tried to define #QtCore.pyqtSlot() to no avail.
What did I do wrong?
My code (for this example, I'm only showing one of the ComboBoxes):
from PyQt4 import QtCore, QtGui
import sys, os, json
class Ui_MainWindow(QtGui.QWidget):
def __init__(self, parent=None):
super(Ui_MainWindow,self).__init__(parent=parent)
### MAIN WINDOW ####
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(1016, 790)
MainWindow.move(200,30)
self.centralwidget = QtGui.QWidget()
self.gridLayout_2 = QtGui.QGridLayout()
self.gridLayout_2.setVerticalSpacing(0)
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
self.comboBox_nationality = QtGui.QComboBox(self.centralwidget)
self.comboBox_nationality.setEditable(True)
self.gridLayout_2.addWidget(self.comboBox_nationality, 1, 0, 1, 1)
self.comboBox_nationality.installEventFilter(self)
def eventFilter(self,obj, event):
if event.type() == QtCore.QEvent.FocusIn:
objt=str(obj.objectName())
exec('self.' + objt + '.activated[str].connect(self.printevent)')
return super(Ui_MainWindow,self).eventFilter(obj,event)
#QtCore.pyqtSlot(QtCore.QString) # Doesn't change anything
#QtCore.pyqtSlot() # TypeError: printevent() takes exactly 2 arguments (1 given)
def printevent(self,item):
print item
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ex = Ui_MainWindow()
ex.__init__(MainWindow)
MainWindow.show()
sys.exit(app.exec_())

PySide how to toggle visibility of QTextBrowser

I want to show/hide QTextBrowser widget by pressing a single button. Is there any mean to toggle it? Now I have two buttons; one for displaying the textbrowser and another for hiding it. Buttons are also hided depending on the visibility of the textbrowser. This implementation works as expected, but I think there should/must be a more sophisticated way to implement it. Any suggestions?
def __init__(self, parent=None):
super(Program, self).__init__(parent)
...code...
self.connect(self.showDetailsButton, SIGNAL("clicked()"), self.showTextBrowser)
self.textBrowser.hide() #hide the textbrowser by default
self.resize(461, 200)
self.connect(self.hideDetailsButton, SIGNAL("clicked()"), self.hideTextBrowser)
self.hideDetailsButton.hide() #hide the hideDetailsButton by default
...code...
def showTextBrowser(self):
self.textBrowser.show()
self.hideDetailsButton.show()
self.showDetailsButton.hide()
self.resize(461, 444)
def hideTextBrowser(self):
self.textBrowser.hide()
self.showDetailsButton.show()
self.hideDetailsButton.hide()
self.resize(461, 200)
...code...
Dialog is resized whenever the QTextBrowser widget is shown or hided.
You only need one button, and one handler. Change the text of the button when it's clicked, and use the current visibility of the browser to toggle between the two states.
Here's a working demo:
from PySide import QtCore, QtGui
class Program(QtGui.QWidget):
def __init__(self):
super(Program, self).__init__()
self.textBrowser = QtGui.QTextBrowser(self)
self.button = QtGui.QPushButton('Hide', self)
self.button.clicked.connect(self.toggleTextBrowser)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.textBrowser)
layout.addWidget(self.button)
def toggleTextBrowser(self):
if self.textBrowser.isHidden():
self.button.setText('Hide')
self.textBrowser.show()
self.resize(461, 444)
else:
self.button.setText('Show')
self.textBrowser.hide()
self.resize(461, 200)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Program()
window.setGeometry(500, 300, 461, 444)
window.show()
sys.exit(app.exec_())
Just save the current state and use it to toggle the visibility:
def toggleVisibleTextBrowser(self):
isVisible= !isVisible # declared somewhere else
self.textBrowser.setVisible(isVisible)
if isVisible:
self.resize(461, 444)
else
self.resize(461, 200)
...

Pyside QTreeWidget Double-clicking on multiple items

I've got a qTreeWidget-based interface where I double click on individual items to toggle them on and off. However, I'd like to be able to bulk-toggle them by selecting multiple objects and double clicking them, but when you double click on any item you immediately lose the multi-selection.
Does anyone know a way around this?
Many thanks for your time,
Nick
The first step would be to setup an event that fires whenever an item is double clicked, like so:
treeWidget.itemDoubleClicked.connect(onClickItem)
where onClickItem is:
def onClickItem(item):
print('Text of first column in item is ', item.text(0))
Of course you'll want to do something a bit more fancy inside onClickItem().
The selection/deselection of items is controlled by the mouse-press event, which obviously happens before the double-click is registered. So you need to "eat" the mouse-press at the appropriate moment.
This example allows double-clicking when the meta-key is pressed:
from PySide import QtGui, QtCore
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
self.tree = QtGui.QTreeWidget(self)
for text in 'One Two Three Four'.split():
parent = QtGui.QTreeWidgetItem(self.tree, [text])
for text in 'Red Blue Green'.split():
child = QtGui.QTreeWidgetItem(parent, [text])
parent.setExpanded(True)
self.tree.setSelectionMode(QtGui.QAbstractItemView.MultiSelection)
self.tree.viewport().installEventFilter(self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.tree)
def eventFilter(self, source, event):
if (source is self.tree.viewport() and
isinstance(event, QtGui.QMouseEvent) and
event.modifiers() == QtCore.Qt.MetaModifier):
if event.type() == QtCore.QEvent.MouseButtonDblClick:
print('meta-double-click')
return True
if event.type() == QtCore.QEvent.MouseButtonPress:
# kill selection when meta-key is also pressed
return True
return super(Window, self).eventFilter(source, event)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(800, 300, 300, 300)
window.show()
sys.exit(app.exec_())

PyQt ComboBox widget not signalling when empty

I have a comboBox and the contents need to change dynamically. I also need to know when the user clicks on the comboBox. When the comboBox has content, it will fire signals, but when it's empty I don't see any signals fired at all. The following code is a toy example demonstrating that for an empty comboBox, no signal will fire.
from PyQt4 import QtCore, QtGui
import sys
class Ui_Example(QtGui.QDialog):
def setupUi(self, Dialog):
self.dialog = Dialog
Dialog.setObjectName("Dialog")
Dialog.resize(300,143)
self.comboBox = QtGui.QComboBox(Dialog)
self.comboBox.setGeometry(QtCore.QRect(60,20,230,20))
self.comboBox.setObjectName("comboBox")
class Ui_Example_Logic(QtGui.QMainWindow):
def __init__(self):
super(Ui_Example_Logic, self).__init__()
def create_main_window(self):
self.ui = Ui_Example()
self.ui.setupUi(self)
self.ui.comboBox.highlighted.connect(self.my_highlight)
self.ui.comboBox.activated.connect(self.my_activate)
def my_highlight(self):
print "Highlighted"
def my_activate(self):
print "Activated"
if __name__ == '__main__':
APP = QtGui.QApplication([])
WINDOW = Ui_Example_Logic()
WINDOW.create_main_window()
WINDOW.show()
sys.exit(APP.exec_())
So for example, if the line below is added to the create_main_window function, "activated" and "highlighted" will print out on expected events, but as the code is now (with the comboBox empty) nothing will print.
self.ui.comboBox.addItems(['a', 'b'])
How can I detect if the user has interacted with the comboBox when it is empty?
If your combobox is empty, no signal will be emitted. But you can installEventFilter for your combobox and reimplement eventfilter (link). First, create filter:
class MouseDetector(QtCore.QObject):
def eventFilter(self, obj, event):
if event.type() == QtCore.QEvent.MouseButtonPress and obj.count() == 0:
print 'Clicked'
return super(MouseDetector, self).eventFilter(obj, event)
It will be print Clicked when user press mouse button on empty comboBox, created inside Ui_Example. Then, install event:
class Ui_Example(QtGui.QDialog):
def setupUi(self, Dialog):
self.dialog = Dialog
Dialog.setObjectName("Dialog")
Dialog.resize(300,143)
self.comboBox = QtGui.QComboBox(Dialog)
self.comboBox.setGeometry(QtCore.QRect(60,20,230,20))
self.comboBox.setObjectName("comboBox")
self.mouseFilter = MouseDetector()
self.comboBox.installEventFilter(self.mouseFilter)

Categories

Resources