How to get the objectName of a modified QSpinBox? - python

I want to keep track of the user modifying the company's forecast in my custom made app.
I created it using qt designer and PyQt4, and I'm using QSpinBox for the quantities (easy way to control range of values and masking the fields to be number only).
The problem I'm having is when I want to get the QSpinBox that triggered my function.
At this moment it's being triggered using valueChanged.connect but could be using anything else.
I can get the int in the spinbox but not the spinbox's name.
Thanks beforehand for the help!
SOLUTION
The QSpinBox element
self.Item = QtGui.QSpinBox(self.centralwidget)
self.Item.setObjectName(_fromUtf8("ItemName"))
Trigger
self.Item.valueChanged.connect(self.foo)
The function it calls
def foo(self,obj):
sender = MainWindow.sender()
print sender.objectName()
In this case "MainWindow" is my QtCore.QObject

AS the question tagged C++. I am answering in both C++ and pyQt4. I never worked in pyQt4. So please excuse me for syntax.
In the "valueChanged" slot use QObject::sender() to get the spin box which triggered it.
And then call "objectName()".
QObject* obj = sender();
QString objName = obj->objectName();
May be in python:
sender = QtCore.QObject.sender()
str = sender.objectName()

Related

How does one update a field from outside the __init__() function with pyqt5

I am reading a sensor and want to display its output as a decimal number in a GUI using PyQt5. I have found a number of tutorials that point out the label.setText('myStr') function. This does not work for my setup, however, because I need to update the field based on the input from another function. I'm not very familiar with PyQt5 yet, and I would appreciate any insight into how this problem ought to be approached.
Note: (I am using LCM to acquire data from a Raspberry Pi. I'm not sure that that is relevant to the problem, but it helps explain my code below.)
Here is what I am trying to do:
class Home_Win(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
loadUi("sensor_interface.ui", self)
self.label_temp.setText('temperature') #Just to verify that I can change it from here
def acquire_sensors(self):
temp = 0 #Make variable available outside nested function
def listen(channel, data):
msg=sensor_data.decode(data)
temp = msg.temperature
lc = lcm.LCM()
subscription = lc.subscribe("sensor_data_0", listen)
while True:
lc.handle()
self.label_temp.setText(str(temp))
Any thoughts on how I can update the GUI to display the readings I am getting from my sensors?
Thanks!
You're almost there. All you need to do is to save the ui in an instance variable in __init__:
self.ui = loadUi("sensor_interface.ui", self)
Then, assuming label_temp is the name of your QLabel widget, just do:
self.ui.label_temp.setText(str(temp))
It turned out that I needed to add repaint(). I also switched to a QLineEdit as this seemed to work better for me. So inside the while loop I now have:
self.ui.lineEdit_temp.setText(str(temp))
self.ui.lineEdit_temp.repaint()
This now outputs live updates to the GUI while reading the data stream.

Init screen in kv on button release using ScreenManager

I'm a beginner Kivy developer and I need some advice from you guys.
I'm using ScreenManager to jump between screens and as far as I noticed, all the screens are initialized just after the application starts, and I need them to be initialized with certain attributes from previous screens, like, selecting the category or stuff. Is there any way to do that?
I have two buttons in CategorySelectScreen both representing certain category, I want them to send a string attribute to DictScreen, where it will be used as an argument in CategorySelect method, which filters the items list, but the thing is, the application need that argument on start and without it the interpreter would just throw errors.
Also, I think I'm using kivy in a very bad way, could you please look into my code and give me some pro tips? Thanks in advance, cheers :)
kv file: http://pastebin.com/UdvGS7Wv
py files: http://pastebin.com/gJn9Mrip
When declaring your screens decide what object would be it's input. Then make this object a property. After that, setup on_... callback where you build your screen with widgets with values based on this input object. For example:
class DictScreen(Screen):
category_selected = ObjectProperty(None)
def on_category_selected(self, instance, value):
category_selected = value
self.clear_widgets()
self.add_widget(Button(text=category_selected.name))
And in previous screen, before you switch to DictScreen get its instance from app.root.ids, then assign category_selected to it and then set new current screen with ScreenManager. This way your DictScreen will be immediately build with choosen category right before you switch to it.
"before you switch to DictScreen get its instance" how this can be done? It's well explained here:
https://kivy.org/docs/api-kivy.uix.widget.html?highlight=widget#kivy.uix.widget.Widget.ids

PyQt4 Getting the name of QTableWidget that user last clicked from multiple QTableWidgets

I have 10 QTablewidgets. Each of the QTableWidget display different data. I want to get the name of the table widget that the last time user clicked ( on any of the cells).
Currently i tried putting all the tables in a list:
table1 = QtGui.QTableWidget()
table2 = QtGui.QTableWidget()
...
...
mytablelist = [table1,table2,....]
Using Signal and Slots I tried this:
for item in mytablelist:
self.connect(item,QtCore.SIGNAL("cellClicked()"),self.Identify)
My Identify function is as below:
def Identify(self):
sender = self.sender()
print sender
As far as i understand, the sender() method should tell me which Qobject the signal is coming from.
I don't seems to get any output from Identify function. What is causing the problem and how do i fix it?
Is there any better approach to this problem?
I think i found the problem. It was the problem with the signal cellClicked() i used (i have no idea why).
So, I tried to use itemSelectionChanged() signal instead of cellClicked() i used in my question. It works fine now. After that i just used index() method to get the position of table in the tablelist.
tableindex = mytablelist.index(sender)

PyQt4 - list widget click event?

im having a problem on my mini project.
i have a method here
def PrintClick(self,name = ""):
print name
then i have a list widget named lstStudents
how do i call the method PrintClick when i click an item inside lstStudents?
also how do i pass the parameters?
i tried
self.connect(self.ui.lstStudents,QtCore.SIGNAL("clicked()"), self.PrintClick)
but i doest work.
please help me :(
You usually call the event when the list selection changes. Also, I'd use the new-style event signals. They look nicer:
self.ui.lstStudents.currentItemChanged.connect(self.PrintClick)

Getting visible text from a QTextEdit in PyQt

This is related to another question I found here that seems to be inactive for a few months, so I think it's worth asking again.
I have created a simple QDialog that has a QTextEdit and a QPushButton. This pops up in my application when a user right-clicks and selects the option to "add comments". I want them to be able to write free-form text and I'll just save whatever they write as a long string with no concern for new lines, etc.
When the user clicks the button, it executes code like this:
self.connect(accept_button,QtCore.SIGNAL('clicked()'),lambda arg=str(view_textedit.toPlainText()): self.updateGroupComments(arg))
def updateGroupComments(self,new_comment_str):
print "Updating user comment to have new string: " + new_comment_str
self.group_entry.list_of_user_comments[self.currentFrameCounter] = new_comment_str
This is not detecting the TextEdit text that is visible (it only detects whatever the text edit text is set to when it is created). How do I make a simple command that returns the currently visible text from a QTextEdit. Again, the function
toPlainText()
is not working correctly... it doesn't find the currently visible text, only whatever text was on screen before changes or additions started being made by the user.
If this can't be done without subclassing and appealing to cursor positions, it makes the whole thing seem worthless... so please keep suggestions only to those implemented without subclassing or manipulating cursors. It should be really simple and straightforward to just return all currently visible text... what am I missing?
Objects that are being bound to default arguments are evaluated at the definition time. The function is working correctly, it returns whatever was in the text field when it was executed. Your code simply calls it at the wrong moment. If you want to use lambda, then do:
self.connect(
accept_button, QtCore.SIGNAL('clicked()'),
lambda: self.updateGroupComments(str(view_textedit.toPlainText()))
)
Or make view_textedit an instance attribute instead, and do simply
self.connect(
accept_button, QtCore.SIGNAL('clicked()'), self.updateGroupComments
)
And change updateGroupComments to call self.view_textedit.toPlainText instead of taking an argument.
BTW, this is not PyQt specific, this is how Python works in general.
To illustrate my last comment, that lambda can very well be replaced with:
def slot():
self.updateGroupComments(str(view_textedit.toPlainText()))
self.connect(accept_button, QtCore.SIGNAL('clicked()'), slot)

Categories