QListWidget::setEditTriggers(QAbstractItemView::AnyKeyPressed) not working - c++

From the book I'm reading:
By default, QListWidget is read-only. If we wanted the user to edit
the items, we could set the view's edit triggers using
QAbstractItemView::setEditTriggers(); for example, a setting of
QAbstractItemView::AnyKeyPressed means that the user can begin editing
an item just by starting to type.
So, I call the function in my code:
ui->listWidget->setEditTriggers(QAbstractItemView::AnyKeyPressed);
But when I select an item and start typing, nothing happens.

It turns out that the items themselves also have an editable flag, so after adding them I had to iterate all of them and set it. Now it's working.
// set the editable flag for each item
for (int ii = 0; ii < ui->listWidget->count(); ii++) {
ui->listWidget->item(ii)->setFlags(ui->listWidget->item(ii)->flags() | Qt::ItemIsEditable);
}
// set the editable triggers for the list widget
ui->listWidget->setEditTriggers(QAbstractItemView::AnyKeyPressed);

Related

How I can make Mandatory add at least one row in Interactive grid in apex oracle

I have two region one form and one interactive grid like a master detail(company and company contact person ) how i can make the interactive grid mandatory ,the user can't submit page ,he/she need add at least one row in interactive grid ,
I can do that or I need to change the interactive grid to collection and count the row in validation
This one is a little tricky because of the way processes and validations work with Interactive Grids (they are executed once per submitted row). To work around this, I'll use a page item and a validation that works with it.
The basic idea of this solution is based on the fact that a new row will not have a primary key value. Here are the steps to reproduce (my example was on page 14, update the following as needed).
Create an Interactive Grid (IG) region. The primary key column should be Query Only (which ensures it's null for new rows).
Create a Hidden page item named P14_NULL_FOUND. Set Type under Server-side Condition to Never so that it never renders on the page.
Create an After Submit (before Validations) process. This process will NOT be associated with the IG so it will only fire once. Set the PL/SQL Code attribute to:
:P14_NULL_FOUND := 'NO';
That will clear out the value of the page item prior to the next process.
Create another After Submit process that runs just after the previous one. Set Editable Region to the IG. Then set the PL/SQL Code to something like the following:
if :PK_COLUMN_IN_IG is null
then
:P14_NULL_FOUND := 'YES';
end if;
You'll need to replace ":PK_COLUMN_IN_IG" with the name of the primary key column in the IG, such as ":EMPNO". This process will be run once for each submitted row in the IG. If a null value is found for the primary key column, then that would mean the user added a new row and the value of P14_NULL_FOUND would be set to 'YES'.
Create a new validation. This validation will NOT be associated with the IG so it will only fire once. Set Type to PL/SQL Expression. Set PL/SQL Expression to:
:P14_NULL_FOUND != 'NO'
Then set Error Message to something relevant.
At this point, you should be able to run the page and verify that the processes and validation are working correctly.
There is an another solution;
Create a page item like PX_ROWCOUNT which will hold the data of the row count of your IG.
Assign a static ID to your IG region.
Write a JS function to count the rows of the grid then set it to the page item. Sample function;
function f_setRowCount(){
var grid = apex.region("staticIDOfYourIG").widget().interactiveGrid("getViews", "grid");
var model = grid.model;
var rowCount = 0;
model.forEach(function (record) {
rowCount ++;
});
$s("PX_ROWCOUNT",rowCount);
}
To submit your page and run this function, change your submit button's behavior to Defined by Dynamic Action. Execute your function when user clicks to that button then submit your page via DA.
Add validation to Processing section of the page and check your page item there; PLSQL Expression => :PX_ROWCOUNT > 0
The solution by Hamit works nicely, except of the case of deletion of a row.
My suggestion is to amend the above code by adding inside the loop an if statement to check whether the row is editable or no.
So the code will be
var grid = apex.region("staticIDOfYourIG").widget().interactiveGrid("getViews", "grid");
var model = grid.model;
var rowCount = 0;
model.forEach(function (record) {
if (model.allowEdit(record)) {
rowCount ++;
}
});
$s("PX_ROWCOUNT",rowCount);

Delete currently selected item from QTreeWidget

Im working with a Qt GUI application, and i have a QTreeWidget with values.
I have added each value to the tree like so:
QTreeWidgetItem *node = new QTreeWidgetItem();
node->setText(0, m_stringList[i];
node->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemisDragEnabled);
ui->sourceTreeWidget->addTopLevelItem(node);
What i am trying to implement now, is a delete button to allow the user to select one or multiple tree items by clicking them, and then pressing the delete button.
The button part is easy.
The part i need some help with, is finding out how to retrieve the string/text value of the currently selected tree item(s).
Anyone have some tips or hints?
What exactly is your problem with that? You create a SLOT for the button and retrieve a list of the selected items with
QList<QTreeWidgetItem*> sel_items = ui->sourceTreeWidget->selectedItems();
for(int i=0; i<sel_items.size(); i++){
...
}
as stated in the documentation for QTreeWidget. You may then iterate through the list and delete them directly or simply retrieve the string/text value as you asked.

Prevent selected item from going out of view in QListView

I am using a QListView with only single selection and selection changes handled by the up and down arrows. Everything is working as expected with one minor issue. If many items are added to the top of the list then the currently selected item risks moving down and out of view. Is there any way to detect when this happens? Thanks.
I found solution, but first of all I try to do dimilar thing, I run timer and every 2 second I insert new row to the begin of list and try to detect, is selected item still visible?
//somewhere in the constructor, it is not important
ListModel = new QStandardItemModel();
ui->listView->setModel(ListModel);
Now when I want to insert new row , I wrote code, which checks is the item visible
QStandardItem* Items = new QStandardItem(QString::number(qrand()%100));
ListModel->insertRow(0,Items);
// here we get rect of current selected item
QRect rec = ui->listView->visualRect(ui->listView->currentIndex());
//here we get all listView region, convert it to rect and check is our listView
//contain selected item
if(ui->listView->viewport()->visibleRegion().boundingRect().contains(rec))
{
qDebug() << "visible";//all good
}
else
{
qDebug() << "not visible";//not good, we need do something
//you want to detect it, so you get!
//now you know that item "runs away from you"
//and you can do some actions
someAction();
}
I test it on my computer, when I can see item, I get visible word, when item tries "run away from me" I get not visible
I hope it helps.

Qt: c++: QTableView does not display my Model

I am creating a model using this code:
QStandardItemModel table_model(4,4);
for(int row=0; row<4; row++){
for (int column=0; column<4; column++){
QStandardItem* item = new QStandardItem((QString("100")));
table_model.setItem(row,column,item);
}
}
Then, I am passing it to QTableView as follow:
QStandardItemModel* model = &table_model;
ui->table->setModel(model);
ui->table->show();
However something is wrong. The QTableView shows nothing, just white space all over it. yet, if, and only if, I click on the trigger button (which creates the model and links it to the QTableView) I can see the 4x4 table, and yet without any data. immediately after the "click" everything disappear (it is just the moment of clicking the button) ..
so what am I missing ? – thanks
You create your model on stack and pass a pointer which gets invalid right after you leave method where you declare it.
QStandardItemModel * table_model = new QStandardItemModel(4,4);

How do I put a checkmark on a menu item that has submenu items. (Visual studio 2008 C++/MFC)

I have a menu that contains submenus.
eg:
Item1
Item2
Item3
item A
Item B
Item3 has items under it.
At any given time 1, 2, or the items under 3 should be checked. Since I don't have an ID for Item3 I have to use the MF_BYPOSITION indicator when I try to set a check on Item3 to indicate one of its children has a checkmark. Item3 should have a checkmark if A or B are checked. I am able to check items 1 and 2 and A and B - but can't figure out item3.
I have not been able to successfully use either ::CheckMenuItem() or ModifyMenu() to set the check mark.
Can someone point me to an example that does this successfully? The docs seem to indicate it can be done, but I have been unable to do it.
EDIT
This is for a menu that is set as the menu for a dlg box. The menu bar has three items - one of which drops down to what is shown above.
Note also, it is used as a popup for a right click, but I will take any suggestions to work in either case.
I've done this before for popup menus. You will need to access the submenu by position, instead of ID. Using your example above, Item 3 would be at position 2:
CMenu popupMenu;
popupMenu.LoadMenu(IDR_MYMENU);
popupMenu.GetSubMenu(0)->CheckMenuItem(2,MF_BYPOSITION|MF_CHECKED);
.
.
.
popupMenu.GetSubMenu(0)->TrackPopupMenu(...);
However, I haven't done this with items in the menu bar.
EDIT by Tim the OP:
For completeness
To get it to work with the menu item you have to get the hmenu
// MENU_POSITION is the zero based location of the menu you want to use. (file, edit, view, help... etc)
HMENU mainMenu = ::GetMenu(m_hWnd);
HMENU subMenu = GetSubMenu( mainMenu, MENU_POSITION);
SetMenuState(subMenu);
A few moments ago I had a similar problem - a standard MFC menu bar containing at least one submenu, and the need to be able to add a check mark to the submenu parent item, when any of the submenu child items were checked.
The easiest solution (for me) turned out to be as simple as performing the update in the standard OnUpdateMenuItem(CCmdUI* pCmdUI) call. In my case I used ON_UPDATE_COMMAND_UI_RANGE() to feed a bunch of menu IDs into the same update call, but the principal is the same for a single ON_UPDATE_COMMAND_UI() map.
The code I used (edited to be more easily inserted into other people's work) is:
void CMyApp::OnUpdateMenu(CCmdUI* pCmdUI)
{
// Note, a submenu parent (which has no editable ID in the resource editor) has the SAME ID as the first child item
if (pCmdUI->m_nID == ID_FIRST_CHILD_MENU && pCmdUI->m_pSubMenu != NULL) {
// Get the child menu so we can see if any child items are checked
CMenu* pSubMenu = pCmdUI->m_pSubMenu;
BOOL fChildChecked = FALSE;
for (UINT i = 0; !fChildChecked && i < pSubMenu->GetMenuItemCount(); ++i) {
// Do something to decide if this child item should be checked...
UINT nChildID = pSubMenu->GetMenuItemID(i);
fChildChecked = IsThisChildChecked(nChildID);
}
// The POSITION of the current menu item is stored in pCmdUI->m_nIndex
CMenu* pMenu = pCmdUI->m_pMenu;
UINT flags = MF_BYPOSITION;
if (fActiveChild) flags |= MF_CHECKED;
pMenu->CheckMenuItem(pCmdUI->m_nIndex, flags);
}
// Set the enabled state of the menu item as you see fit...
pCmdUI->Enable(TRUE);
}
Et voilà the submenu item automagically gains a check mark when any of its child menu items has a check mark.
Hope this helps others looking for similar solutions!
John