Can't set tab order after rearranging widgets
-
I have a verticalLayout in a scrollArea that I add custom widgets to. When I do this, the tab order is properly set. I then have radioButtons to change the order and sort these widgets. I've tried about 4 different ways to change the tab order to respect this new ordering, but every time it's ignored. I have a feeling I might be doing something more fundamentally wrong somewhere else, like in the way I re-order these custom widgets.
Here's the section in question, cards is a list of the custom widget:
def _sort_cards(self, cards: list) -> "Helper method to sort cards into the scrollarea. cards is the sorted list of Card objects to use." print("_sort_cards") # add all the cards and show the line: for card in reversed(cards): self.verticalLayout_player_cards.insertWidget(0, card) card.show_line() # set tab order: last_card = None for card in if last_card: self.setTabOrder(last_card, card) print("setTabOrder:", last_card, card) last_card = card self._hide_top_card_line()
The full code is here and I can also share the whole project if it's helpful: https://0x0.st/XDHU.bin
I'm new to the forums and have been eagerly using and learning qt for a little bit now :) Thanks in advance!
-
@JTHundley said in Can't set tab order after rearranging widgets:
I have a verticalLayout in a scrollArea
You usually don't do this.
It's counterproductive in aQScrollArea
and might break the scroll functionality.
UseQScrollArea::setWidget
to add your large, scrollable widget (with layout) instead.Haven't looked at your code, but when doing the above correctly,
every time it's ignored
this might work then.
-
Thanks for your response, but I'm not sure I understand. The scrolling actually does work fine the way it is, but I removed the verticalLayout from the scrollArea and found that it all works the same. Sorting and scrolling still work, but when rearranging the widgets within the scrollArea the tab order remains the way it was when the widgets were first added.
-
Hi,
You need to use setTabOrder after you moved your widgets around.
-
Sorry, I somehow did not see it.
However, your loop code seems broken or is it a copy paste error ?That said, you could use the Python zip function to create the pairs of widgets. The first list being the original minus the last one and the second list the original with the first item removed.
-
@SGaist Yes, that was a paste error, "for card in cards:" :)
So basically you're saying I should delete the widgets and recreate them so they can be freshly inserted or added into the scrollArea, right? This is my latest attempt that I'm trying, mixed results so far.
-
@JTHundley said in Can't set tab order after rearranging widgets:
@SGaist Yes, that was a paste error, "for card in cards:" :)
So basically you're saying I should delete the widgets and recreate them so they can be freshly inserted or added into the scrollArea, right? This is my latest attempt that I'm trying, mixed results so far.
Not at all, I was talking about how to build the input of your for loop.
-
Ah. Well again my code pasted in wrong and the loop does work, the widgets get rearranged into the order I want them in, but then fixing them with setTabOrder does nothing. The way I rearrange the widgets in the scrollArea is by inserting them into the layout at the beginning. This moves them instead of duplicating them. I still have no idea why setTabOrder isn't working and my days of searching haven't turned up much.
-
I figured it out! My in-progress solution is to add each of these custom widgets to a temporary layout to re-parent them and then add them back to the layout in the order I want them to tab to:
def _sort_cards(self, cards: list) -> None: "Helper method to sort cards into the scrollarea. cards is the sorted list of Card objects to use." print("_sort_cards") # create a temporary layout so we can add all cards to this and then back to the regular layout temp_parent = QtWidgets.QWidget() temp_layout = QtWidgets.QVBoxLayout(temp_parent) for card in cards: temp_layout.insertWidget(0, card) # add all the cards and show the line: for index, card in enumerate(cards): self.verticalLayout_player_cards.insertWidget(index, card) card.show_line() self._hide_top_card_line()
-
I made a full release if anyone wants the full context: https://sourceforge.net/projects/inscryption-hydra-tracker/
I hope this thread helps others who find setTabOrder not working for them. It took me a week to figure this out, never give up!Here's the finished sort method:
def _sort_cards(self, cards: list) -> None: "Helper method to sort cards into the scrollarea. cards is the sorted list of Card objects to use." # create a temporary widget and reparent all the cards to it: temp_parent = QtWidgets.QWidget() for card in cards: card.setParent(temp_parent) # add all the cards and show the line: for index, card in enumerate(cards): # for some reason adding the card to the layout makes it hidden, so capture and restore that state: hidden = card.isHidden() self.verticalLayout_player_cards.insertWidget(index, card) card.setHidden(hidden) card.show_line() self._hide_top_card_line()
Thanks to everyone who helped and responded!