PyQt QSpinBox update range depending on the value of other spinbox - python

i am using pyqt4 to develop a GUI for the first time;
I have a spinbox, and I would like the range of values allowed in it to be dependant on the value another spinbox. for example, the maximum value allowed in the first spinbox should be equal to the value of the second spinbox.
I thought this may be possible using a valueChanged() signal to call a method that is something like:
def function
max = spinbox2.value()
spinbox1.setMaximum(max)
but that didnt work, does anyone know how to do this?
thank you

You have not shown your code where you make the connection between the 'valueChanged' signal of spinbox2 with the function. Are you making that connection ?. Also the code you have given for function seems to be incomplete.
You can try something like this:
spinbbox2.valueChanged.connect(handler)
# Or this which works for Python 3.5
spinbbox2.valueChanged[int].connect(handler)
# The function handler called is called whenever
# value in spinbox2 is changed and parameter to
# handler is the new value of spinbox2
def handler(value):
spinbox1.setMaximum(value)

Related

How do I update the data associated with a QListWidgetItem from the QListWidget in PyQt?

I have a QListWidget that has 10 QListWidgetItems. When each of those QListWidgetItems is created I do something like this:
item = QtGui.QListWidgetItem("Text to Show")
item.setData(36, "A specific value that is used later")
self.ui.my_list.addItem(item)
Now, later in the application, after a user clicks a button, I want to update the text "A specific value that is used later", for the item that is selected. I have attempted to do this
ndx = self.ui.my_list.currentRow()
self.ui.my_list.item(ndx).setData(36, "Updated!")
The problem is, this doesn't work. It doesn't throw any errors, but the data is just gone. In my button press signal I have this code to see the value before and after the reassignment:
ndx = self.ui.my_list.currentRow()
print "Before:", self.ui.my_list.item(ndx).data(36).toPyObject()
self.ui.my_list.item(ndx).setData(36, "Updated!")
print "After:", self.ui.my_list.item(ndx).data(36).toPyObject()
This outputs:
Before: A specific value that is used later
After:
How can I properly change the data so that it is saved back to the QListWidgetItem?
You may want to check that the role value your using is a valid user role, otherwise it may be altered internally. I write in c++, but I use the QListWidget and QListWidgetItem(s) frequently, and this was a problem I encountered early on. I imagen that the functionality is similar regardless of the language. According to the documentation here, the first user role that can be used is 0x0010. So to tie it to your example, you might try the following:
item.setData(0x0010, "A specific value that is used later")
For additional item roles you would use 0x0011, 0x0012, 0x0013, etc.

Unable to send signal from Button created in Python loop

I am trying to create a series of buttons in a loop. Each button gets an id number as it's text and when the button is clicked it is supposed to send the id number to a function that will open an archived order. At this time I just want to print the order number to prove that the signal works and each button is connected to the correct order number.
ui.cmdOpen = QtWidgets.QPushButton(ui.frOrdHist)
ui.cmdOpen.setGeometry(QtCore.QRect(269, line1Y, 61, 22))
ui.cmdOpen.setText(iOrderId)
ui.cmdOpen.setObjectName("cmdOpen")
ui.cmdOpen.clicked.connect(lambda button=ui.cmdOpen:displayOrder(ui, button))
def displayOrder(ui, button):
i = button.text()
print(i)
When I click the button, I get an error message that says "boolean object has no text attribute"
I tried passing the order number directly and it would print "False" so still a boolean. I don't know where the boolean is coming from, it must be something wrong in the signal.
The clicked signal always sends the checked state of the button. So this will overwrite your default button argument with a boolean value, which is why you get the AttributeError (i.e. because bool doesn't have that method). You should instead make the connection like this:
ui.cmdOpen.clicked.connect(
lambda checked, button=ui.cmdOpen: displayOrder(ui, button))
PS: another common source of this issue is the triggered signal of QAction. If you ever find your slots receiving unexpected inputs, it's always worth checking the Qt Docs to see if the signature of the signal has any parameters with default values - i.e. that look something like this:
void QSomeClass::someSignal(bool param = false)

How to setup 2 QDoubleSpinBox depending on each other?

The first combobox holds a number in a currency A and the second one holds the same amount but in currency B. What I want : When I enter a number in the 1st one, the 2nd one must be set automatically to the number converted in the other currency and vice-versa.
I use Ubuntu 16.04, Python 3.5.1, Qt 4.8.7. The 2 QComboBox are created with Qt Designer
Code :
#pyqtSignature("double")
def on_dspPuAchEur_valueChanged(self, double):
""" updaye prAchatDT according to prAchatEur"""
self.dspPuAchDT.setValue(2.2*self.dspPuAchEur.value())
#pyqtSignature("double")
def on_dspPuAchDT_valueChanged(self, double):
""" update prAchatEur according to prAchatDT"""
self.dspPuAchEur.setValue(self.dspPuAchDT.value()/2.2)
2.2 is the conversion factor which will be a variable in the future.
min is 0 for the 2 combobox, max is 50000 (far above the real max), step is 1.0.
It works fine from dspPuAchEur to dspPuAchDT but it does not work in the opposite sense : the step is 0.99 in place of 1. When I try to edit manually the field, the displayed digit is not the one I've just entered. It's always minus 1 (If I press the '5' key, I get a '4').
Does somebody have any idea about this behavior ? Thanks.
I think this could be due to both spin boxes playing "ping pong". A change of value of dspPuAchDT causes it's valueChanged() singal to be emitted, which in turn updates dspPuAchEur, which in turn emits it's valueChanged() signal with in turn leads to an update of dspPuAchDT. Due to rounding, the value you enter seems to change immediately.
As a workaround, you could block emitting signals while updating the peer widget:
#pyqtSignature("double")
def on_dspPuAchEur_valueChanged(self, double):
""" updaye prAchatDT according to prAchatEur"""
self.dspPuAchDT.blockSignals(True);
self.dspPuAchDT.setValue(2.2*self.dspPuAchEur.value())
self.dspPuAchDT.blockSignals(False);
#pyqtSignature("double")
def on_dspPuAchDT_valueChanged(self, double):
""" update prAchatEur according to prAchatDT"""
self.dspPuAchEur.blockSignals(True);
self.dspPuAchEur.setValue(self.dspPuAchDT.value()/2.2)
self.dspPuAchEur.blockSignals(False);

PyQt : get a value from combobox when a button pressed

I use qt designer and convert it from *.ui to *.py, I want to make application for send and receive serial data,,
i use combobox to alow user for setting serial comŲ©unication
self.ui.comboBox_2.addItems(['2400','4800','9600','19200'])
my question is how can i get value from combobo_2 to fill serial buadrate when I click a button
this is my code
self.connect(self.ui.comboBox_2, QtCore.SIGNAL('activated(QString)'),ser.baudRate())
and get an error
File "mainw.py", line 18, in press_2 self.connect(self.ui.comboBox_2,
QtCore.SIGNAL('activated(QString)'),ser.baudRate()) AttributeError:
'Serial' object has no attribute 'baudRate'
Your question about using a button to get the value from the combo box is different than what you are currently doing which is using a signal directly from when an value in the combo box was selected.
Your error is related to something else, it looks like in your signal you are calling a function "ser.baudRate()" but you have to pass in a function object, as it will pass in whatever "ser.buadRate()" returns. Which probably isn't a function. I'm not sure what that function returns. In any case, here is some ideas:
Using a button
If you want to use a button, then you would write something like this:
self.connect(self.ui.myButton, QtCore.SIGNAL('clicked()'), self.updateBaudRate)
def updateBaudRate(self):
# get value from combo box
rate = str(self.ui.comboBox_2.currentText()) # convert to string otherwise you will get a QString which is sometimes not friendly with other tools
ser.baudRate(rate)
Using the combo box signal
self.connect(self.ui.comboBox_2, QtCore.SIGNAL('currentIndexChanged(QString)'), self.updateBaudRate)
def updateBaudRate(self, rate):
ser.baudRate(str(rate)) # again convert to string as it my not accept a QString
You could use partial from the functools module or use a lambda instead of writing a function for the signal, but this is just for example.
You probably also want to use the "currentIndexChanged" signal instead of "activated" as "currentIndexChanged" will only emit when the value has changed, otherwise it will signal even if the user didn't select a different value in the combo box.

How to add event listener to dynamic QTableWidgetItem in PyQt4?

I am a Python and Qt newbie...
I am working on a GUI program that shows a list of data using QTableWidget at the beginning.
The rows are inserted into the table using the setItem() method. They are QTableWidgetItem objects.
Now I want to allow users to click-select a certain row (the QTableWidgetItem), and my program will populate a secondary QTableWidget.
I have learnt that there is a thing called Signal and Slot. Am I going to use that?
There are also examples of using installEventFilter(), but it is not appropiate for the QTableWidgetItem.
The easiest way for this would just be to use the itemClicked-signal of the QTableWidget:
def handle_item_clicked(tableItem):
#the callback, called when an item is clicked, with the item as an argument
#populate the secondary table in some way
#register the callback with the QTableWidget
yourTableWidget.itemClicked.connect(handle_item_clicked)
You could also use the currentItemChanged signal which gives you the current and previous selection (e.g. so you can clear or hide your secondary widget if the user deselects an item, in which case the current item will be None).
Qt doesn't have "event listeners". As you mentioned, you do such things by connecting signals to slots.
For example:
QObject.connect(myTableWidget, QtCore.SIGNAL("clicked()"), self.foobar)
This will cause the method self.foobar() to be called when you click on myTableWidget. The foobar function could retrieve which item is selected and populate the second widget based on that.
Take note that in the last argument of connect, you don't use the parentheses (foobar()), just the method name!

Categories

Resources