How to enable/disable button when QComboxBox and QLineEdit are activated - pyqt

I cannot get a push-button enabled when both a text box is filled and a combox box item is selected.
I have the following code, which enables the button as soon as I enter text, but have no selected combobox item:
self.combo_box.currentIndexChanged[int].connect(self.showbutton)
self.textbox.textChanged.connect(self.showbutton)
def showbutton(self,index):
self.enableNewButton.setEnabled((index != -1) and bool(self.textbox.text()))
So I then did a print(index) and I do see the proper index being printed when I select a combo box item; but I also see each character printed as well when I enter stuff in the text box.
I have no problems enabling buttons based on multiple text input boxes but this one is not working for me.

The textChanged signal sends the current text, which cannot ever be equal to -1. So rather than using the parameters emitted by the signals, you should directly check both values via the widgets themselves, like so:
class Window(QtWidgets.QWidget):
...
def showbutton(self):
self.enableNewButton.setEnabled(
self.combo_box.currentIndex() >= 0 and bool(self.textbox.text()))

Related

What is a way of re-selecting a random set of check boxes again using Selenium Python?

My scenario is there are several check boxes with the name tag starting with "CHK_(number here)". What I want to do is select 5 random check boxes, click them (to have them checked), once they are checked, click a sort button which is defined as "sort_selected_button", and finally un-select the random checked boxes. The final step is where I am having trouble with.
This is being done on Internet Explorer 11. This is my first time getting into Selenium Python for IE 11 so I would appreciate any help.
# Checks several batches, sort them with the Sort button, and then deselect
def check_sort_deselect_batches_selected(self):
select_random_batches = self.driver.find_elements_by_xpath("//*[starts-with(#name, 'CHK_')]")
for x in range(5):
option = random.choice(select_random_batches)
option.click()
return option
else:
self.driver.find_element(*LeftSidebarLocators.sort_selected_button).click()
time.sleep(2)
I have been able to be rid of any error messages; however, the only issue is on how to select the 5 randomly selected check boxes again after they have been sorted. Thanks for any help.
There is a method is_checked() that will return True if the box is checked. You can use this to determine which of the boxes are checked and then click them again to uncheck each. Before we get to the final code, I would make a couple suggestions:
One issue you might run into with your current code is that you randomly pick the same number twice in your for loop. If that happens, you will uncheck the box that you already checked leaving you with only 4 checked items.
To fix this, you can use a filter to grab only the checked boxes and repeat the loop until you get a len() of 5. If you get the same random number again, the click is skipped and you loop again.
The else statement will always get executed since you have no break in your for loop so it can be safely removed. See the docs for more info.
For the new code, you can use another filter to grab only the checked boxes and then loop through them, clicking each one to uncheck all the checkboxes.
# Checks several batches, sort them with the Sort button, and then deselect
def check_sort_deselect_batches_selected(self):
select_random_batches = self.driver.find_elements_by_xpath("//*[starts-with(#name, 'CHK_')]")
# loop until the count of checked elements is 5
while len(list(filter(lambda e: e.is_checked(), select_random_batches))) < 5
option = random.choice(select_random_batches)
# make sure that the random choice isn't already checked
if not option.is_selected()
option.click()
self.driver.find_element(*LeftSidebarLocators.sort_selected_button).click()
# refetch the checkboxes after the sorting
select_random_batches = self.driver.find_elements_by_xpath("//*[starts-with(#name, 'CHK_')]")
# loop through the list of checked elements and deselect each
for e in list(filter(lambda e: e.is_checked(), select_random_batches))
e.click()
time.sleep(2)

Automatically scroll down Listbox in Tkinter app

Hi guys I'm making this chat app with tkinter and it works perfectly except by the fact that the text I post in my Listbox, don't shows up the way I want. Once the space in the Listbox finishes, I have to manually scroll down to see recent messages. My question is, what can I do to make the Listbox automatically scroll down when it gets fill. This is the part of the code of the Listbox
lista=Listbox(raiz,font=('Arial'))
lista.pack(side=LEFT,padx=10,pady=10,ipadx=200,fill=X,expand=True )
And this is where I posted:
def post(text,n=0):
winsound.Beep(400,150)
if n==0:
lista.insert(END,text)
campo.delete(0,1000)
else:
for i in text:
lista.insert(END,i)
If you can help me it will be great. Thanks!!!
You need add this line lista.see(tkinter.END) before lista.insert(END,text)
You should clear the Listbox widget before you display the current or insert
def post(text,n=0):
winsound.Beep(400,150)
if n==0:
lista.delete(0, END) # this to clear the listbox and display the current content in the listbox
lista.insert(END,text)
campo.delete(0,1000)
else:
for i in text:
lista.insert(END,i)
Or you can place the new content at top of Listbox like this,
def post(text,n=0):
winsound.Beep(400,150)
if n==0:
return
lista.insert(n-1, text)
campo.delete(0,1000)
else:
for i in text:
lista.insert(END,i)
Since you didn't post your full code or minimal am assuming this how it is.

Delete value(s) in the list box by click a button

[22 Feb 2016 update]
Regarding my previous questions about list box, I can move values between two listboxes and save values after I receive useful answers.
However, if I retrieve those saved values, the listboxes can display the proper values but I cannot move those values and get exception message.
I can only move values between two listboxes if I don't save them.
Therefore, I am planning to have another button for delete listboxes values. I am not sure this is a good practice/design in xpages but I don't have a better method solve the exception.
I am sorry if I caused any inconvenience in this question. Thank you.
[23 Feb 2016 update]
According to the latest comments and answer, I notice that I made a big mistake because I mixed the document and value together.
I decide to break the design into few steps to find the problem occurs.
Due to I can move values between two listboxes and save them. I use another listbox test whether I can retrieve those saved values or not.
The third list box, I use View Scope Variable(similar to listbox B) but I use another variable name to avoid vague.
Here is my code of the third listbox:
var item = getComponent("comboBox4").getValue();
if ((item == null) || (null == item))
{
return "void";
}
else if ((item != null) || (null != item))
{
var lookupItem = #DbLookup(#DbName(),"ViewName", item,3 )
return lookupItem;
}
if (!viewScope.totalItems)
{
viewScope.totalItems = [lookupItem];
}
return viewScope.totalItems;
In the combo box, I use onchange partial update and apply to the third list box . When I run the program, I select a value from the combo box, the third listbox can display the relevant values that I saved before.
That part is fine, so I keep the third listbox for testing. And I put some dummy but unique data (to prevent confusion) related to the combo box.
Here is my first attempt: I choose a value from a combo box, the third listbox can display the relevant values that I saved. I move one value from listbox A to listbox B and click save. The third list box can reflect the value that I save.
In my second attempt: after the first attempt, listbox B still contains the value from listbox A, so this time, I move that value back to listbox A and click save. In the result, in the third list box, I see that value disappear.
At this moment, there is no value in listbox B and I add another two button and write similar code to pretend move values between the third list box and listbox B.
I test it, I select the value from the combo box, the third list box shows the proper values. But when I select a value from the third list box and click the button to move it to listbox A. I think that value will move to the listbox A but the result is nothing happens.
I try the other way, I select a value from listbox A and click the button to move it to the third button. Again the result is nothing happens.
After those fail attempts, I think the problem occurs in the buttons.
Here are the code of the two buttons
Button 1 (move value to the third listbox):
if (viewScope.ALstBoxItem) {
var sel = [].concat(viewScope.ALstBoxItem);
for (var i = 0; i < sel.length; i++) {
viewScope.totalItems.add(sel[i]);
viewScope.AselectItems.remove(sel[i]);
}
viewScope.totalItems.sort();
viewScope.ALstBoxItem = "";
}
Button 2 (move value to the listbox A):
if (viewScope.TotalItemsVariable) {
var sel = [].concat(viewScope.TotalItemsVariable);
for (var i = 0; i < sel.length; i++) {
viewScope.AselectItems.add(sel[i]);
viewScope.totalInItem.remove(sel[i]);
}
viewScope.AselectItems.sort();
viewScope.TotalItemsVariable = "";
}
Recall to comments in the question, I guess I should focus on the values in the listbox, not the button. I search on the internet about hide selected value and find these websites almost can give me the idea to solve the problem:
xpages hiding/showing fields based on a combobox value
Hiding based on previous combo box choice in xpages?
https://www-10.lotus.com/ldd/ddwiki.nsf/dx/dynamical_elements_on_xpages.htm
I try to apply those summary to suit my case but I still cannot move values after I save.
Grateful if someone can give advice please. Thank you very much.
Please step back and think about what you are building. You have two list boxes. They contain values, not documents, so a deleteSelectedDocument simple action can't work. Similarly, access to delete documents isn't relevant.
Also, from previous questions of this topic, I don't think you are setting values in the listboxes, you are using the events to set options, i.e. the options are not highlighted and so selected in the listbox, they are just sitting in the listboxes as options available for selection. Look at the code you're using to add options to the listboxes and use the corresponding code to remove the options.
I've added an image that corresponds to what I think you're trying to build, and the difference between "value" and "option", except in your example it sounds like you're moving the option from ListBox 1 to ListBox 2 as soon as it's selected, not using an "Add" button. Or to break the process down further, it sounds like, when an option in ListBox 1 is selected, you are looking to remove it from the list of options in ListBox 1 and add it to the list of options in ListBox 2. On your save, it sounds like you're wanting to store the options into a NotesDocument and, when you return, set the options for your ListBoxes based on what is stored in the NotesDocument.
If so, the questions and answers on this topic have given you everything you need to code those steps in the process.

TouchDevelop Deleting text

The Issue:
I have two buttons, button "Apple" and button "Cookie".
When I press the "Cookie" button, text should show saying "Cookie" on screen (which it does)
THEN, when I press the "Apple" button, the text should UPDATE to "Apple" instead of "Cookie"
The problem is, with my current code, whenever I press the second button (Apple) -- the original "Cookie" text isn't removed, it appears underneath the "Apple" text.
I'd like the "Cookie" text to be removed from the screen when I press the apple button or any other button (over 10 buttons)
How would I achieve this within touchdevelop?
Current Code:
Assistance is very much appreciated.
Try this project: http://tdev.ly/ydcl.
To change what is displayed when a button is clicked, set a global variable and change its value when on tapped is called. In TouchDevelop, the page display is refreshed automatically so that any changes made when a button is tapped will occur immediately. There is no need to hide or show part of the display; just include that section in an if statement and change the if statement condition when a button is tapped. If you wanted to show one of three possible layouts, use an if statement that tests the value of a string or number for one of three values and changes that value when a certain button is tapped or condition is met.

Issue rendering the selected cell on a QTableView

I have a custom QTableView and a custom QAbstractTableModel. The view only allows single selections. I'm trying to customize the background color of the selected cell under some conditions with no success. I expected to do it by combining the data method of the model with the selectionChanged method of the view. For instance, let's suppose I want to change the color of the selected cell when it matches a given row. My code for the selectionChanged method is:
def selectionChanged(self, selected, deselected):
#QtGui.QTableView.selectionChanged(self, selected, deselected)
# Get the selected indexes from the QItemSelection object
selection = selected.indexes()
# Let the model track the selected cell
self.tmodel.selected_index = selection[0]
# Desperately try to make it work
self.tmodel.dataChanged.emit(selection[0], selection[0])
self.viewport().update()
My simplified code for the data method is:
def data(self, index, role=QtCore.Qt.DisplayRole):
if not index.isValid():
return None
# Some code here dealing with several roles
if role == QtCore.Qt.DisplayRole:
...
elif role == QtCore.Qt.BackgroundRole:
if ((index == self.selected_index) and (index.row() == 3)):
print '++++ displaying selected'
return QtGui.QColor(QtCore.Qt.yellow)
else:
return QtGui.QColor(QtCore.Qt.green)
else:
return None
The non selected cells have a green background as expected. The strange thing is that when I select a cell in the matching row, the message ++++ displaying selected is printed but the selected cell has the system default background instead of a yellow one. I must be missing something important/obvious here but I've no idea about what it is.
Update
I know I can achieve my goal using a custom delegate and implementing its paint method but I'd like to know why the code above fails.
OK, I think I got it. The think is that the default delegate uses the values returned by data in order to render the table cells. Accordingly to the docs:
By supplying appropriate item data for each role, models can provide
hints to views and delegates about how items should be presented to
the user. Different kinds of views have the freedom to interpret or
ignore this information as required.
So the behavior described in the question is explained as follow: non selected cells are rendered in the standard way by the default delegate which implies the color returned by data method will be used. However, selected cell are rendered in a different way by the default delegate, the value returned by data method is ignored in this case because it uses the background provided by the system style.

Resources