Qt ui: speed up big table - qt

I have a QTableWidget table with more than 2000 rows. When i add QToolButton "Remove" in each row, it become a little bit slow). Why table become slow, buttons ui or signal mapper? How can i speed up my table, maybe replace buttons with something else or connect signals in other way?
My code for buttons:
// mapper for remove buttons
QSignalMapper* signalMapper = new QSignalMapper(this);
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(RemoveString(int)), Qt::UniqueConnection);
than for each row:
//remove button
QToolButton* remove_button = new QToolButton(this);
remove_button->setText("Remove");
signalMapper->setMapping(remove_button, index);
connect(remove_button, SIGNAL(clicked()), signalMapper, SLOT(map()), Qt::UniqueConnection);
ui->locale_table->setCellWidget(index, 3, remove_button);

As vahancho said you will want an item delegate. Item delegates simply display the data and information in a certain way. It mainly paints the item to look like what you want, so it doesn't necessarily create a whole widget. You will probably want to use a styled item delegate. http://qtadventures.wordpress.com/2012/02/04/adding-button-to-qviewtable/ This should have all of the information you need.
You set the item delegate to the widget with the QTableWidget methods setItemDelegate, setItemDelegateForColumn, setItemDelegateForRow.

Related

Disable (grey-out) some rows in a QTreeView

I have a (very simple yet) QTreeView showing some rows:
m_cameraModel = new QStandardItemModel(this);
QSortFilterProxyModel* cameraProxyModel = new QSortFilterProxyModel(this);
cameraProxyModel->setSourceModel(m_cameraModel);
ui.CameraTreeView->setModel(cameraProxyModel);
m_cameraModel->appendRow(new QStandardItem("Panavision"));
m_cameraModel->appendRow(new QStandardItem("Panaflex"));
Here I want to disable the first row "Panavision" so that it is still visible but can't be selected any more and is somehow greyed-out so that the user can see this entry is not active.
May be this is some kind of beginner-question, but how can this be done?
Thanks!
I would try to do that in the following way:
// Get item that corresponds to the first row
QStandardItem *item = m_cameraModel->item(0, 0);
// Disable the item.
item->setFlags(Qt::NoItemFlags);
You'd want to use the QItemDelegate class, which allows you to disable the row you want to amongst other things. There's a good question here on StackOverflow that shows how to do a very basic example: How to set a delegate for a single cell in Qt item view?

Adding tab to QTabWidget. is empty?

Well, the thing is I have a tabwidget created in qtcreator, with many tabs and in the tabs there are many lineedit and other objects.
The closeable property of the tabWidget is set to true.
I execute the program and close the tabs, but when I want to reopen the tab, it's empty, I'm using this code:
tabs->addTab(new QWidget(),"TAB 1");
I want to use the same tab create on the design of qtcreator.
Your problem is that you are adding empty widget in your code:
tabs->addTab(new QWidget(),"TAB 1");
Instead you need to keep you widgets and add them like that:
QWidget* widget; // it is stored
int index = ui->tabWidget->addTab(widget, "TAB 1");
Where to take these widgets?
It is not enough to set closable to true, you also to use signal/slot:
connect(ui->tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int)));
And finally:
void YourWindow::closeTab(int index)
{
// do something else
QWidget* widget = ui->tabWidget->widget(index);
ui->tabWidget->removeTab(index);
// here you can remember it and use later when adding tab
}

problem of adding a QPushButton using setItemWidget inside QListWidgetItem

I want to add a QPushButton inside ListItm, so I have implemented the code as given below. But the button comes in the middle of the list, actually I want it at the lower end of the list item. How is it possible. Also that button click event is not working. Actually I want to disable the item click event directly and by clicking the button inside the QListWidgetItem, I want to enable the item click event. But I am not able to perform this operation. How to do this? I have used the following code snippet:
list=new QListWidget(this);
// list->setStyleSheet("* { background-color:rgb(0,0,0); padding: 10px ; color:rgb(255,255,255)}");
list->setGeometry(0,61,360,475);
list->setSortingEnabled(true);
//connect(list,SIGNAL(itemClicked(QListWidgetItem*)),this,SLOT(ItemClicked(QListWidgetItem*)));
item=new QListWidgetItem();
item->setIcon(QIcon(":/images/Icon.png"));
item->setText("Item1");
item->setSizeHint(QSize(80,80));
item->setBackgroundColor(QColor(200,255,100));
list->addItem(item);
QPushButton *but = new QPushButton(">");
but->setMaximumSize(50,80);
but->setFlat(true);
// but->setGeometry(QRect(500,100,100,100));
but->setStyleSheet("background: transparent; border: none");
QHBoxLayout *layout= new QHBoxLayout();
layout->addWidget(but);
QWidget *widget = new QWidget();
widget->setLayout(layout);
item->setSizeHint(widget->sizeHint());
list->setItemWidget(item, widget);
connect(but, SIGNAL(clicked()), this, SLOT(ItemClicked()));
#if defined(Q_WS_S60)
list->showMaximized();
#else
list->show();
#endif
ItemClicked()
{
int Index = list->currentIndex().row();//Always getting this Index as -1
}
Please have a look on the above code and provide your suggestions.
Thanks...
Reconsider using QPushButton as "click" handle for listwidget. There is a reason why QListWidgetItem is not QObject. QObjects are somewhat "heavy", because of all metadata structures they hold. That's why Qt is not using QObjects in data oriented lists like QListWidgetItem.
About your problem. You will get always -1, until you won't select item by NOT clicking on it's button part, but on item. That's because QPushButton is taking focus away, and doesn't pass click event down to QListWidgetItem. So it may even happend, that you select item with idx = 3, click on button of item with idx = 1 and will get in your slot idx 3.
Actualy, as for me you're performing your whole taks totaly wrong. First of all, I would use QTreeWidget, for multicolumns. Secondly, I would "implement" custom item delegate, to draw "button", and I would set it as delegate for column 1. Then I would catch "click event" normally, but react only for column 1.
| column 0 (actual data exposition) | column 1 (custom delegate, draw button)

Help on QStackedWidget

I am using a QStackedWidget on my mainWindow. The firstPageWidget on stackedWidget contains 3 buttons. Now If I will press the first button on firstPage, I want the stackedWidget show the 2nd Page widget. Following are the details
I tried to connect like this in my mainwindow
connect(firstPageWidget->button1,SIGNAL(clicked()),stackWidget,SLOT(setCurrentIndex(int)));
Now I want to know how to pass the value of index number to stackWidget to set currentIndex?
If my question is not much clear please tell me I will explain more.
You probably need to use QSignalMapper class:
QSignalMapper mapper = new QSignalMapper(); // don't forget to set the proper parent
mapper->setMapping(firstPageWidget->button1, 2); // 2 can be replaced with any int value
connect(firstPageWidget->button1, SIGNAL(clicked()), mapper, SLOT(map()));
connect(mapper, SIGNAL(mapped(int)), stackWidget, SLOT(setCurrentIndex(int)));
Instead of buttons you could use a QListWidget containing selectable Icons. QListWidget has a method called QListWidget::currentItemChanged ( QListWidgetItem * current, QListWidgetItem * previous ). I used that method in a program I wrote some time ago... There I wrote a function on_change_widget( QListWidgetItem *current, QListWidgetItem *previous ) which I connected to the SIGNAL currentItemChanged:
connect( my_list_widget,
SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)),
this,
SLOT(on_change_widget(QListWidgetItem *, QListWidgetItem *))
);
That should do the trick.
You should have a look at the Config Dialog Example, there they use the same method to swap widgets.
Of course you can use normal buttons too, in connection with the QSignalMapper chalup mentioned.
You can also use QButtonGroup and set proper id to each button, then connect QButtonGroup signal QButtonGroup::buttonClicked(int) with stacked widget slot QStackedWidget::setCurrentIndex(int)

Is there a way to have all radion buttons be unchecked

I have a QGroupBox with a couple of QRadioButtons inside of it and in certain cases I want all radio buttons to be unchecked. Seems that this is not possible when a selection has been made. Do you know of a way I could do this or should I add a hidden radiobutton and check that onen to get the desired result.
You can achieve this effect by temporarily turning off auto exclusivity for all your radio buttons, unchecking them, and then turning them back on:
QRadioButton* rbutton1 = new QRadioButton("Option 1", parent);
// ... other code ...
rbutton1->setAutoExclusive(false);
rbutton1->setChecked(false);
rbutton1->setAutoExclusive(true);
You might want to look at using QButtonGroup to keep things tidier, it'll let you turn exclusivity on and off for an entire group of buttons instead of iterating through them yourself:
// where rbuttons are QRadioButtons with appropriate parent widgets
// (QButtonGroup doesn't draw or layout anything, it's just a container class)
QButtonGroup* group = new QButtonGroup(parent);
group->addButton(rbutton1);
group->addButton(rbutton2);
group->addButton(rbutton3);
// ... other code ...
QAbstractButton* checked = group->checkedButton();
if (checked)
{
group->setExclusive(false);
checked->setChecked(false);
group->setExclusive(true);
}
However, as the other answers have stated, you might want to consider using checkboxes instead, since radio buttons aren't really meant for this sort of thing.
If you're using QGroupBox to group buttons, you can't use the setExclusive(false) function to uncheck the checked RadioButton. You can read about it in QRadioButton section of QT docs. So if you want to reset your buttons, you can try something like this:
QButtonGroup *buttonGroup = new QButtonGroup;
QRadioButton *radioButton1 = new QRadioButton("button1");
QRadioButton *radioButton2 = new QRadioButton("button2");
QRadioButton *radioButton3 = new QRadioButton("button3");
buttonGroup->addButton(radioButton1);
buttonGroup->addButton(radioButton2);
buttonGroup->addButton(radioButton3);
if(buttonGroup->checkedButton() != 0)
{
// Disable the exclusive property of the Button Group
buttonGroup->setExclusive(false);
// Get the checked button and uncheck it
buttonGroup->checkedButton()->setChecked(false);
// Enable the exclusive property of the Button Group
buttonGroup->setExclusive(true);
}
You can disable the exclusive property of the ButtonGroup to reset all the buttons associated with the ButtonGroup, then you can enable the Exclusive property so that multiple button checks won't be possible.

Resources