I want to react on a mouseclick on a QLabel.
To achieve this I have redefined the method mouseReleaseEvent of QLabel.
I want to pass two arguments to the slot:
- the QtGui.QMouseEvent
- an ID of the clicked QLabel
But I can only pass one parameter. Either QtGui.QMouseEvent or the ID.
The combination does not work.
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import pyqtSignal
class ExtendedQLabel(QtGui.QLabel):
#labelClickSignal_1 = pyqtSignal(QtGui.QMouseEvent)
labelClickSignal_1 = pyqtSignal(QtGui.QMouseEvent, int)
labelClickSignal_2 = pyqtSignal()
def __init(self, parent):
QtGui.QLabel.__init__(self, parent)
# redefinition
def mouseReleaseEvent(self, event):
#self.labelClickSignal_1.emit(event)
self.labelClickSignal_1.emit(event, 0)
self.labelClickSignal_2.emit()
class Test(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.names = ['Test1', 'Test2', 'Test3']
self.centralWidget = QtGui.QWidget()
self.setCentralWidget(self.centralWidget)
self.grid = QtGui.QGridLayout(self.centralWidget)
row = 0
for name in self.names:
self.addLabel(name, row)
row = row + 1
def addLabel(self, name, row):
label = ExtendedQLabel(name)
# QtGui.QMouseEvent is automatically passed to the slot
label.labelClickSignal_1.connect(self.onLabelClicked_1)
# The row ID is passed to the slot
label.labelClickSignal_2.connect(lambda id = row:
self.onLabelClicked_2(id))
# *This does not work*
label.labelClickSignal_1.connect(lambda id = row:
self.onLabelClicked_3(QtGui.QMouseEvent, id))
self.grid.addWidget(label, row, 1)
row = row + 1
def onLabelClicked_1(self, event):
if event.button() == QtCore.Qt.RightButton:
print('right')
else:
print('left')
def onLabelClicked_2(self, id):
print('Label {0} clicked'.format(id))
def onLabelClicked_3(self, event, id):
# *This does not work*
if event.button() == QtCore.Qt.RightButton:
print('right {0}'.format(id))
else:
print('left {0}'.format(id))
def main():
app = QtGui.QApplication(sys.argv)
t = Test()
t.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Ok, since your code had several pieces that did not work I rewrote the important Parts to achieve what you want. Please Note that I use PySide and not PyQt. This means you have to change the importe Statements and the Signal back to PyQt Notation.
The rest is explained in the code.
import sys
from PySide import QtGui, QtCore
class ExtendedQLabel(QtGui.QLabel):
#Signal that emits on MouseRelease
labelClickSignal_1 = QtCore.Signal(QtGui.QMouseEvent, int)
# init to -1
labelId = -1
# This is the new Constructor, Please note the double underscore
# before and behind `init`
def __init__(self, parent, labelId):
self.labelId = labelId
QtGui.QLabel.__init__(self, parent)
# emit labelClickSignal
def mouseReleaseEvent(self, event):
self.labelClickSignal_1.emit(event, self.labelId)
class Test(QtGui.QMainWindow):
def __init__(self, parent=None):
# same as yours [...]
def addLabel(self, name, row):
# please note the added argument
label = ExtendedQLabel(name,row)
# connect the signal
label.labelClickSignal_1.connect(self.onLabelClicked_1)
self.grid.addWidget(label, row, 1)
row = row + 1
def onLabelClicked_1(self, event,labelId):
if event.button() == QtCore.Qt.RightButton:
print('right')
print(labelId)
else:
print('left')
print(labelId)
OLD ANSWER
You have to define your Signal to support your two arguments:
labelClickSignal_1 = pyqtSignal(QtGui.QMouseEvent,int)
See here for additional information.
Example from the docs:
from PyQt4.QtCore import QObject, pyqtSignal
class Foo(QObject):
# This defines a signal called 'closed' that takes no arguments.
closed = pyqtSignal()
# This defines a signal called 'rangeChanged' that takes two
# integer arguments.
range_changed = pyqtSignal(int, int, name='rangeChanged')
# This defines a signal called 'valueChanged' that has two overloads,
# one that takes an integer argument and one that takes a QString
# argument. Note that because we use a string to specify the type of
# the QString argument then this code will run under Python v2 and v3.
valueChanged = pyqtSignal([int], ['QString'])
I think I solved it. Your lambda with the comment *and this does not work* took only one argument, though the slot is defined to take two. So I just skipped the first argument.
Next issue: It is difficult to pass Events that have been generated by system. I think they are destroyed after they have been handled. So I copied the data of the event into a namedtuple and passed this instead. (I also tried to copy the event, but this did not work somehow.)
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import pyqtSignal
from collections import namedtuple
class ExtendedQLabel(QtGui.QLabel):
MouseEventTuple = namedtuple('MouseEventTuple', 'type pos button buttons modifiers')
#labelClickSignal_1 = pyqtSignal(QtGui.QMouseEvent)
labelClickSignal_1 = pyqtSignal(MouseEventTuple, int)
labelClickSignal_2 = pyqtSignal()
def __init(self, parent):
QtGui.QLabel.__init__(self, parent)
# redefinition
def mouseReleaseEvent(self, event):
eventTuple = ExtendedQLabel.MouseEventTuple(type = event.type(), pos = event.pos(), button = QtCore.Qt.RightButton, buttons = event.buttons(), modifiers = event.modifiers())
self.labelClickSignal_1.emit(eventTuple, 0)
self.labelClickSignal_2.emit()
class Test(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.names = ['Test1', 'Test2', 'Test3']
self.centralWidget = QtGui.QWidget()
self.setCentralWidget(self.centralWidget)
self.grid = QtGui.QGridLayout(self.centralWidget)
row = 0
for name in self.names:
self.addLabel(name, row)
row = row + 1
def addLabel(self, name, row):
label = ExtendedQLabel(name)
# QtGui.QMouseEvent is automatically passed to the slot
label.labelClickSignal_1.connect(self.onLabelClicked_1)
# The row ID is passed to the slot
label.labelClickSignal_2.connect(lambda id = row:
self.onLabelClicked_2(id))
# *This works now*
label.labelClickSignal_1.connect(lambda _unused_, id = row:
self.onLabelClicked_3(QtGui.QMouseEvent, id))
self.grid.addWidget(label, row, 1)
row = row + 1
def onLabelClicked_1(self, eventTuple):
if eventTuple.button == QtCore.Qt.RightButton:
print('right')
else:
print('left')
def onLabelClicked_2(self, id):
print('Label {0} clicked'.format(id))
def onLabelClicked_3(self, eventTuple, id):
# *This does not work*
if eventTuple.button == QtCore.Qt.RightButton:
print('right {0}'.format(id))
else:
print('left {0}'.format(id))
def main():
app = QtGui.QApplication(sys.argv)
t = Test()
t.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Related
With PyQt4, I am using a QtableView with more than 10 columns. The user must have the choice of showing/hiding a column.
This is generally done by adding a small button in the top-right of the table's header. The button shows a menu with checked/unchecked Checkboxes allowing to hide/show columns.
This is an example from Sqlite-Manager Table.
So, I wonder how can I do the same with PyQt's QtableView?
Thanks,
Thank you Kitsune Meyoko, it was a great Idea.. ;)
I found another solution pretty much like yours by using QMenu with Checkable QActions instead of a QPushButton: Let's Go:
import sys
import string
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Header(QHeaderView):
def __init__(self, parent=None):
super(Header, self).__init__(Qt.Horizontal, parent)
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.ctxMenu)
self.setup()
#pyqtSlot(bool)
def printID(self, i):
print("id")
if i == False:
self.hideSection(0)
else:
self.showSection(0)
#pyqtSlot(bool)
def printNAME(self, i):
print("name")
if i == False:
self.hideSection(1)
else:
self.showSection(1)
#pyqtSlot(bool)
def printUSERNAME(self, i):
print("username")
if i == False:
self.hideSection(2)
else:
self.showSection(2)
def setup(self):
self.id = QAction("id",self)
self.id.setCheckable(True)
self.id.setChecked(True)
self.connect(self.id, SIGNAL("triggered(bool)"), self, SLOT("printID(bool)"))
self.name = QAction("name",self)
self.name.setCheckable(True)
self.name.setChecked(True)
self.connect(self.name, SIGNAL("triggered(bool)"), self, SLOT("printNAME(bool)"))
self.username = QAction("username",self)
self.username.setCheckable(True)
self.username.setChecked(True)
self.connect(self.username, SIGNAL("triggered(bool)"), self, SLOT("printUSERNAME(bool)"))
def ctxMenu(self, point):
menu = QMenu(self)
self.currentSection = self.logicalIndexAt(point)
menu.addAction(self.id)
menu.addAction(self.name)
menu.addAction(self.username)
menu.exec_(self.mapToGlobal(point))
class Table(QTableWidget):
def __init__(self, parent=None):
super(Table, self).__init__(parent)
self.setHorizontalHeader(Header(self))
self.setColumnCount(3)
self.setHorizontalHeaderLabels(['id', 'name', 'username'])
self.populate()
def populate(self):
self.setRowCount(10)
for i in range(10):
for j,l in enumerate(string.ascii_letters[:3]):
self.setItem(i, j, QTableWidgetItem(l))
if __name__ == '__main__':
app = QApplication(sys.argv)
t = Table()
t.show()
app.exec_()
sys.exit()
In QTableView not have kind of button just like "Sqlite-Manager Table". But your can custom widget by using QtGui.QPushButton and work with QtGui.QMenu together to get column from user. And use QTableView.hideColumn (self, int column) & QTableView.showColumn (self, int column) to hide show your column;
Full example;
import sys
import random
from functools import partial
from PyQt4 import QtGui
class QCustomTableViewWidget (QtGui.QWidget):
def __init__ (self, myQStandardItemModel, *args, **kwargs):
super(QCustomTableViewWidget, self).__init__(*args, **kwargs)
# Layout setup
self.localQTableView = QtGui.QTableView()
self.rightCornerQPushButton = QtGui.QPushButton()
menuQHBoxLayout = QtGui.QHBoxLayout()
menuQHBoxLayout.addStretch(1)
menuQHBoxLayout.addWidget(self.rightCornerQPushButton)
allQVBoxLayout = QtGui.QVBoxLayout()
allQVBoxLayout.addLayout(menuQHBoxLayout)
allQVBoxLayout.addWidget(self.localQTableView)
self.setLayout(allQVBoxLayout)
# Object setup
self.localQTableView.setModel(myQStandardItemModel)
self.rightCornerQPushButton.setText('Show column')
currentQMenu = QtGui.QMenu()
for column in range(myQStandardItemModel.columnCount()):
currentQAction = QtGui.QAction('Column %d' % (column + 1), currentQMenu)
currentQAction.setCheckable(True)
currentQAction.setChecked(True)
currentQAction.toggled.connect(partial(self.setColumnVisible, column))
currentQMenu.addAction(currentQAction)
self.rightCornerQPushButton.setMenu(currentQMenu)
def setColumnVisible (self, column, isChecked):
if isChecked:
self.localQTableView.showColumn(column)
else:
self.localQTableView.hideColumn(column)
def tableView (self):
return self.localQTableView
# Simulate data
myQStandardItemModel = QtGui.QStandardItemModel()
for _ in range(10):
myQStandardItemModel.appendRow([QtGui.QStandardItem('%d' % random.randint(100, 999)), QtGui.QStandardItem('%d' % random.randint(100, 999)), QtGui.QStandardItem('%d' % random.randint(100, 999))])
# Main application
myQApplication = QtGui.QApplication(sys.argv)
myQCustomTableViewWidget = QCustomTableViewWidget(myQStandardItemModel)
myQCustomTableViewWidget.show()
sys.exit(myQApplication.exec_())
I have a QToolTip on a QLineEdit and the tooltip contains variables in the text. The tooltip code is contained in the init. The problem is that the variable values in the tooltip do not update automatically when they are changed in the operation of the program. For example, I hover over the line edit and values appear in the tooltip. I change the program, go back to the line edit, and variables in the tooltip have not changed.
I can fix the issue by moving the .setToolTip to a function and calling the function EACH time ANYTHING is changed in the program, but that seems like overkill, especially when 99% of the program changes have nothing to do with this particular tooltip).
Are variables supposed to update automatically? Here is the tooltip setup code contained in the init.
self.ui.YourSSAmount.setToolTip(
'<span>Click Reports/Social Security to see your<br>SS income at each start age'
'<br><br>Your inf adj FRA amt at age {}: ${:,.0f}'
'<br>Age adjustment: {:.0f}%'
'<br>SS Income at age {}: ${:,.0f}</span>'.format(
self.generator.YouSSStartAge, self.generator.your_new_FRA_amt,
self.generator.SS66.get(self.generator.YouSSStartAge, 1.32) * 100, self.generator.YouSSStartAge,
self.generator.YourSSAmount))
The setToolTip method takes the text and stores it, and is not notified if any of the variables used to form the text change.
Given this there are 2 possible solutions:
Update the tooltip every time a variable changes:
from PyQt5 import QtCore, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.le = QtWidgets.QLineEdit()
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.le)
self.foo = QtCore.QDateTime.currentDateTime().toString()
self.update_tooltip()
timer = QtCore.QTimer(self, timeout=self.on_timeout)
timer.start()
def on_timeout(self):
self.foo = QtCore.QDateTime.currentDateTime().toString()
# every time any variable used to build the tooltip changes
# then the text of the tooltip must be updated
self.update_tooltip()
def update_tooltip(self):
# update tooltip text
self.setToolTip("dt: {}".format(self.foo))
if __name__ == "__main__":
app = QtWidgets.QApplication([])
w = Widget()
w.show()
app.exec_()
Override the toolTip to take the text using the variables:
from PyQt5 import QtCore, QtWidgets
class LineEdit(QtWidgets.QLineEdit):
def __init__(self, parent=None):
super().__init__(parent)
self._foo = ""
#property
def foo(self):
return self._foo
#foo.setter
def foo(self, foo):
self._foo = foo
def event(self, e):
if e.type() == QtCore.QEvent.ToolTip:
text = "dt:{}".format(self.foo)
QtWidgets.QToolTip.showText(e.globalPos(), text, self, QtCore.QRect(), -1)
e.accept()
return True
return super().event(e)
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.le = LineEdit()
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.le)
self.le.foo = QtCore.QDateTime.currentDateTime().toString()
timer = QtCore.QTimer(self, timeout=self.on_timeout)
timer.start()
def on_timeout(self):
self.le.foo = QtCore.QDateTime.currentDateTime().toString()
if __name__ == "__main__":
app = QtWidgets.QApplication([])
w = Widget()
w.show()
app.exec_()
Forgive me if the question has already been asked, but I couldn't find the answer anywhere.
I am trying to test a small gui that contains a QListWidget and a QTreeWidget.
More specifically, I want to test the drag and drop behavior from one of the QListWidgetItem of the QListWidget to the QTreeWidget.
The ui works as intented but the problem comes when testing the drag and drop behavior as I am attempting to use QTest.mousePress() on the item, as this method only takes a QWidget as an input, and not a QListWidgetItem.
import sys
from PySide2 import QtWidgets, QtGui, QtCore
def startup():
app = QtWidgets.QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())
class MainWindow(QtWidgets.QDialog):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
main_layout = QtWidgets.QHBoxLayout(self)
self.source = SourceList()
main_layout.addWidget(self.source)
self.destination = DestinationTree()
main_layout.addWidget(self.destination)
self.add_items(self.source)
def add_items(self, list_widget):
items = ['apple', 'banana']
for item in items:
list_widget_item = QtWidgets.QListWidgetItem(item)
list_widget.addItem(list_widget_item)
def item_count(self):
number_of_items = 0
iterator = QtWidgets.QTreeWidgetItemIterator(self)
while iterator.value():
number_of_items += 1
iterator += 1
return number_of_items
class SourceList(QtWidgets.QListWidget):
def __init__(self, parent=None):
super(SourceList, self).__init__(parent)
self.setViewMode(QtWidgets.QListWidget.IconMode)
self.setDragEnabled(True)
def startDrag(self, supportedActions):
items = self.selectedItems()
name = items[0].text()
drag = QtGui.QDrag(self)
ba = bytearray(name, 'utf-8')
drag_mime_data = QtCore.QMimeData()
drag_mime_data.setData('MoveQComponentItem', QtCore.QByteArray(ba))
drag.setMimeData(drag_mime_data)
drag.exec_(QtCore.Qt.MoveAction)
class DestinationTree(QtWidgets.QTreeWidget):
def __init__(self, parent=None):
super(DestinationTree, self).__init__(parent)
self.setAcceptDrops(True)
def dragEnterEvent(self, drag_event):
mime_data = drag_event.mimeData()
if mime_data.hasFormat('MoveQComponentItem'):
drag_event.acceptProposedAction()
def dragMoveEvent(self, drag_event):
return
def dragLeaveEvent(self, drag_event):
return
def dropEvent(self, drop_event):
print('Entering Drop event')
byte_array = drop_event.mimeData().data('MoveQComponentItem')
name = byte_array.data().decode('utf8')
print(name)
item = QtWidgets.QTreeWidgetItem()
item.setText(0, name)
self.addTopLevelItem(item)
def item_count(self):
number_of_items = 0
iterator = QtWidgets.QTreeWidgetItemIterator(self)
while iterator.value():
number_of_items += 1
iterator += 1
return number_of_items
if __name__ == '__main__':
startup()
I'd like to test this with something similar to this :
def test_shouldAddOneWidgetToTheTree_whenDragingFromListItemToTree(self):
my_q_list_widget_item = main_window.source.item(0)
tree_widget = main_window.destination
QtTest.QTest.mousePress(my_q_list_widget_item, QtCore.Qt.LeftButton)
QtTest.QTest.mouseMove(tree_widget)
QtTest.QTest.mouseRelease(tree_widget, QtCore.Qt.LeftButton)
count = tree_widget.item_count()
assert count == 1
Ideally I'd need a solution that works both on python 2 and 3, also if that helps, I'm using pytest.
Any idea would be greatly appreciated :)
I am working with a custom QMenu which executes some methods. The menu has three options: a delete row option, a toggle variable option and a debug option, which prints the value of the toggleing variable. The code is not properly executed. Sometimes the debug button doesnt work and it suddely gets executed many times. The toggle option needs to be clicked twice to work, i dont know why. This is my MRE:
# -*- coding: utf-8 -*-
from PyQt5.QtCore import Qt, QRect, pyqtSlot
from PyQt5.QtGui import QCursor
from PyQt5.QtWidgets import QWidget, QPushButton, QHBoxLayout, QMainWindow, QLabel, QMenu, \
QApplication, QVBoxLayout, QListWidgetItem, QListWidget, QAction
class Punto(QWidget):
def __init__(self, parent, internal_id, name):
QWidget.__init__(self)
# Toggle variable
self.render = True
self.customContextMenuRequested.connect(self.context_menu)
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.menu = QMenu()
self.borrar = QAction("Delete")
self.ver = QAction("Toggle")
self.debug = QAction("Debug")
self.ver.setCheckable(True)
self.ver.setChecked(True)
self.parent = parent
self.id = internal_id
label = QLabel(name)
hbox = QHBoxLayout()
hbox.addWidget(label)
hbox.addStretch(1)
self.setLayout(hbox)
def context_menu(self):
self.menu.addAction(self.borrar)
self.borrar.triggered.connect(self.delete)
self.menu.addAction(self.ver)
self.ver.triggered.connect(self.change)
self.menu.addAction(self.debug)
self.debug.triggered.connect(self.debugg)
self.menu.exec(QCursor.pos())
#pyqtSlot()
def debugg(self):
print(f"Render: {self.render}")
#pyqtSlot()
def change(self):
if self.ver.isChecked():
self.ver.setChecked(False)
self.render = False
else:
self.ver.setChecked(True)
self.render = True
#property
def itemid(self):
return self.id
#pyqtSlot()
def delete(self):
self.parent.delete_point(self.id)
class Ventana(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setFixedSize(200, 200)
widget_central = QWidget(self)
boton_punto = QPushButton(widget_central)
boton_punto.setGeometry(QRect(0, 0, 200, 20))
boton_punto.clicked.connect(self.crear_punto)
boton_punto.setText("Create")
widget_punto = QWidget(widget_central)
widget_punto.setGeometry(QRect(0, 20, 200, 200))
vertical_punto = QVBoxLayout(widget_punto)
vertical_punto.setContentsMargins(0, 0, 0, 0)
self.lista_puntos = QListWidget(widget_punto)
vertical_punto.addWidget(self.lista_puntos)
self.id_punto = 0
self.setCentralWidget(widget_central)
def crear_punto(self):
# Add placeholder item to List
item = QListWidgetItem()
self.lista_puntos.addItem(item)
# Create Custom Widget
punto = Punto(self, self.id_punto, "A")
self.id_punto += 1
item.setSizeHint(punto.minimumSizeHint())
# Set the punto widget to be displayed within the placeholder item
self.lista_puntos.setItemWidget(item, punto)
def delete_point(self, idd):
for indx in range(self.lista_puntos.count()):
item = self.lista_puntos.item(indx)
widget = self.lista_puntos.itemWidget(item)
if widget.id == idd:
self.lista_puntos.takeItem(self.lista_puntos.row(item))
break
if __name__ == "__main__":
MainEvent = QApplication([])
main_app = Ventana()
main_app.show()
MainEvent.exec()
You have 2 errors:
By default a QAction already makes the change of state so it is not necessary that you implement it, but you are doing it, that is, by default the QAction changes from on to off (or vice versa) but you by code change it from off a on (or vice versa) that when done in ms the change is not observed. So instead of connecting the triggered signal, use the toggled signal and just change the render.
When you connect a signal to the same slot "n" times the slot is invoked "n" times, and in your case you are connecting it every time the context_menu method is invoked, there are at least 2 solutions: make the connection only once or use the type of connection Qt::UniqueConnection, in my solution I will use the first one.
Considering the above, the solution is:
class Punto(QWidget):
def __init__(self, parent, internal_id, name):
QWidget.__init__(self)
# Toggle variable
self.render = True
self.customContextMenuRequested.connect(self.context_menu)
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.menu = QMenu()
self.borrar = QAction("Delete")
self.ver = QAction("Toggle")
self.debug = QAction("Debug")
self.ver.setCheckable(True)
self.ver.setChecked(True)
self.parent = parent
self.id = internal_id
label = QLabel(name)
hbox = QHBoxLayout(self)
hbox.addWidget(label)
hbox.addStretch(1)
self.borrar.triggered.connect(self.delete)
self.ver.toggled.connect(self.change)
self.debug.triggered.connect(self.debugg)
self.menu.addAction(self.borrar)
self.menu.addAction(self.ver)
self.menu.addAction(self.debug)
def context_menu(self):
self.menu.exec(QCursor.pos())
#pyqtSlot()
def debugg(self):
print(f"Render: {self.render}")
#pyqtSlot(bool)
def change(self, state):
self.render = self.ver.isChecked()
#property
def itemid(self):
return self.id
#pyqtSlot()
def delete(self):
self.parent.delete_point(self.id)
Using PyQt 4.8 and Python 3.3
I'm using a modified version of this example: whereas this example emits a signal on tab press and adds arbitrary text to the second QLineEdit, I want my script to emit a signal on any keypress, add arbitrary signal text to the 2nd QLineEdit, and add the typed character to the 1st QLineEdit (assuming it's a valid ASCII character).
Whenever I try to use any keypress as a signal, I can no longer grab that text to input into QLineEdit. Here's what I have so far and where I'm stuck:
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
####################################################################
def main():
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
####################################################################
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
# create objects
self.la = QLabel("Type in this box:")
self.le = MyLineEdit()
self.la2 = QLabel("\nLook here:")
self.le2 = QLineEdit()
self.char = MyLineEdit.char # HOW CAN I GET THIS WORKING?
# layout
layout = QVBoxLayout()
layout.addWidget(self.la)
layout.addWidget(self.le)
layout.addWidget(self.la2)
layout.addWidget(self.le2)
self.setLayout(layout)
# connections
self.connect(self.le, SIGNAL("keyPressed"),
self.update)
def update(self):
newtext1 = self.le.text() + self.char
newtext2 = self.le2.text() + "kP "
self.le.setText(newtext1)
self.le2.setText(newtext2)
####################################################################
class MyLineEdit(QLineEdit):
def __init__(self, *args):
QLineEdit.__init__(self, *args)
def event(self, event):
if (event.type() == QEvent.KeyPress):
self.emit(SIGNAL("keyPressed"))
self.char = "%c" % (event.key())
return True
return QLineEdit.event(self, event)
####################################################################
if __name__ == "__main__":
main()
Any and all help is greatly appreciated. Is there something within PyQt4 that allows me to use a keypress as both a signal and input text, or is my Python off?
Problem1: you are emitting the signal before setting self.char:
class MyLineEdit(QLineEdit):
def __init__(self, *args):
QLineEdit.__init__(self, *args)
self.char = ""
def event(self, event):
if (event.type() == QEvent.KeyPress):
self.char = "%c" % (event.key()) #this line above the next
self.emit(SIGNAL("keyPressed"))
return True
return QLineEdit.event(self, event)
Problem 2: use the char value in your MyLineEdit object:
def update(self):
newtext1 = self.le.text() + self.le.char
newtext2 = self.le2.text() + "kP "
self.le.setText(newtext1)
self.le2.setText(newtext2)
Finally you don't need self.char on MyWindow