How to add widget to entire column in a QTableWidget? - pyqt5

New to PyQt5. I'm trying to create a Table using QTableWidget where certain columns are spin box or drop down widgets. I am able to add create a widget and it to a particular cell. I have the following questions:
How do I automatically add these widgets when a user add a new row to a table? From reading the documentation, it seems I can use itemDelegateForRow, but I'm not sure which methods to implement from the QAbstractItemDelegate class. Can someone point me to a small example on how to use this?
The column Parent is a combo box whose values need to get updated with a list of all other values in column Block. By default, it has a single item 'top'. When a row is added with say, Block=A, then in the 2nd row the list of valid choices for Parent shoudl be A, top, etc. What signal should I monitor/connect to update the combox box and how?
Right now, I have the following code to create a 5x5 table.
hier_blocks = QTableWidget(5, 5)
hier_blocks.verticalHeader().setDefaultSectionSize(25)
hdrs = ['Block', 'Parent', 'Library', 'Freq (MHz)', 'Qty']
hier_blocks.setHorizontalHeaderLabels(hdrs)
parent_box = QComboBox(hier_blocks)
parent_box.addItem('top')
hier_blocks.setCellWidget(0, 1, parent_box)
lib_box = QComboBox(hier_blocks)
hier_blocks.setCellWidget(0, 2, lib_box)
freq_box = QSpinBox(hier_blocks)
freq_box.setRange(1, 4000)
hier_blocks.setCellWidget(0, 3, freq_box)
qty_box = QSpinBox(hier_blocks)
qty_box.setRange(1, 20)
hier_blocks.setCellWidget(0, 4, qty_box)
hier_layout = QVBoxLayout()
hier_layout.addWidget(hier_blocks)

Related

HighRadius Ivoice prediction Challenges

Generate a new column "avgdelay" from the existing columns
Note - You are expected to make a new column "avgdelay" by grouping "name_customer" column with reapect to mean of the "Delay" column.
This new column "avg_delay" is meant to store "customer_name" wise delay
groupby('name_customer')['Delay'].mean(numeric_only=False)
Display the new "avg_delay" column
Can Anyone guide me
Let df be your main data frame
avgdelay = df.groupby('name_customer')['Delay'].mean(numeric_only=False)
You need to add the "avg_delay" column with the maindata, mapped with "name_customer" column
Note - You need to use map function to map the avgdelay with respect to "name_customer" column
df['avg_delay'] = df['name_customer'].map(avgdelay)

Python selenium get table values into List of Lists

I'm just trying to get the data from this table:
https://www.listcorp.com/asx/sectors/materials
and put all the values (the TEXT) into a list of lists.
I've tried so many different methods using--> xpath, getByClassName, By.tag
------------
rws = driver.find_elements_by_xpath("//table/tbody/tr/td")
---------------
table = driver.find_element_by_class_name("v-datatable v-table theme--light")
--------------
findElements(By.tagName("table"))
--------------
# to identify the table rows
l = driver.find_elements_by_xpath ("//*[#class= 'v-datatable.v-
table.theme--light']/tbody/tr")
# to get the row count len method
print (len(l))
# THIS RETURNS '1' which cant be right because theres hundreds of rows
And nothing seems to work to get the values in an easy way to understand the manner.
(EDIT SOLVED)
before doing the SOLVED solution below.
First do: time.sleep(10) this will allow the page to load so that the table can actually be retrieved. then just append all the cells to a new list. YOU WILL NEED MULTIPLE LISTS to fit all the rows.
So basically you can use find_elements_by_tag_name
and use this code
row = driver.find_elements_by_tag_name("tr")
data = driver.find_elements_by_tag_name("td")
print('Rows --> {}'.format(len(row)))
print('Data --> {}'.format(len(data)))
for value in row:
print(value.text)
Have proper wait to populate the data.

Append all stock.move ID's to list from all chain of related records

I have records in the stock.move table that has One2many relation to stock.move.reconcile with column move_to_id which is the ID of another record in stock.move table. So this chain can be thousands of records.
As you can see in my example I loop trough all records and go down tier by tier, but as I said before there could be thousands of linked records so my approach will not work here.
I do know that probably I need to use a while loop here, something like while there is move_to_ids, then I should loop through records and keep adding IDs to list, but I just can't figure it out how to do it.
move1(stock.move ID = 10) record that has One2many relation with 2 records inside: move_to_ids (stock.move.reconcile)
each of move_to_ids has move_to_id(many2one, 'stock.move' ID = 11)
each of this move_to_id(stock.move, ID=11) records have again any number of move_to_ids (stock.move.reconcile) and each of thismove_to_idsrecords havemove_to_id('stock.move', ID=12)` and so on.
So basically I want to add to list all move_to_id IDs 10, 11, 12, etc. to list for all related move_to_ids.
moves_to_recalculate = [10,11,12] and so on until when there is 0 move_to_ids to get move_to_id from.
class StockMove(models.Model):
_name = 'stock.move'
move_to_ids = fields.One2many(
'stock.move.reconcile', 'move_from_id', string='Move to')
move_from_ids = fields.One2many(
'stock.move.reconcile', 'move_to_id', string='Move From'
)
class StockMoveReconcile(models.Model):
_name = 'stock.move.reconcile'
_description = 'Stock Move Reconcile'
move_to_id = fields.Many2one('stock.move', string='Move To')
move_from_id = fields.Many2one('stock.move', string='Move From')
def recalculate(self):
moves = self.browse(('active_ids'))
moves_to_recalculate = []
for move1 in moves:
#I add my first move in chain to list
moves_to_recalculate.append(move1.id)
#First move have 2 moves_to_ids so i make another loop to add it ID to list
for second_tier_move in move.move_to_ids:
moves_to_recalculate.appen(second_tier_move.move_to_id.id)
# secont tier move has 1 move_to_ids so i do another loop, and add it's ID to list.
for third_tier_move in second_tier_move.move_to_ids:
moves_to_recalculate.appen(third_tier_move.move_to_id.id)
#third_tier_move has another move_to_ids , and so on.
I got answer from other resource but I think i need to post it here because the answer is excellent.
def recalculate_fifo(self):
moves = self.browse(self._context.get('active_ids'))
moves_to_recalculate = moves
current_moves = moves
while current_moves:
current_moves = current_moves.mapped('move_to_ids.move_to_id')
current_moves -= moves_to_recalculate
moves_to_recalculate |= current_moves

What is the cleanest way to create a new column based on a conditional of an existing column?

In pandas I currently have a data frame containing a column of strings: {Urban, Suburban, Rural}. The column I would like to create is conditional of the first column (i.e. Urban, Suburban, Rural are associated with the corresponding colors) {Coral, Skyblue, Gold}
I tried copying the first column and then using .replace but my new column seems to return NaN values now instead of the colors.
new_column = merge_table["type"]
merge_table["color"] = new_column
color_df = merge_table["color"].replace({'Urban': 'Coral', 'Suburban': 'Skyblue', 'Rural': 'Gold'})
data = pd.DataFrame({'City Type': type,
'Bubble Color': color_df
})
data.head()
You can do
merge_table['New col']=merge_table["color"].replace({'Urban': 'Coral', 'Suburban': 'Skyblue', 'Rural': 'Gold'})
Okay. in the future, its worth typing the codes using 'Code Samples' so that we can view your code easier.
Lots of areas can improve your code. Firstly you do the entire thing in one line:
merge_table["color"] = merge_table["type"].map(mapping_dictionary)
Series.map() is around 4 times faster than Series.replace() for your information.
also other tips:
never use type as a variable name, use something more specific like city_type. type is already a standard built-in method
data = pd.DataFrame({'City Type': city_type, 'Bubble Color': color_df})
if make a copy of a column, use:
a_series = df['column_name'].copy()

JQuery Datatables disable/remove row count options depending on number of records

By default, datatables has 4 sizes of records to show: 10,25,50,100.
All the option are available by default no matter how many records in table.
If table has 18 entries is there any option to disable or remove 50 and 100 from the dropdown.
or if disable row count if records are less than 10.
I can't find either of these in the documentation.
You modify the length menu by the aLengthMenu setting
$('#example').dataTable({
aLengthMenu : [5, 10, 25, 50]
});
To dynamically change the menu, you must access the generated <select> box in code. It has a name, which always is table id + _length, so a table with the id example will have a length menu with the name example_length
Here an example, dynamically changing the length menu to hold 5 and 10 only
var dataTable = $('#example').dataTable();
var newLength = [5, 10];
var aLengthMenu = $('select[name=example_length]');
$(aLengthMenu).find('option').remove();
for (var i=0;i<newLength.length;i++) {
$(aLengthMenu).append('<option value="'+newLength[i]+'">'+newLength[i]+'</option>');
}
To disable the menu, simply add the disabled attribute
$(aLengthMenu).prop('disabled', 'disabled');
working demo with the code above http://jsfiddle.net/Mz5WZ/