I have created a custom menu as a Popup. When I use addAction the items are arranged vertically. Is it possible to align the QMenu items horizontally?
Yeah, it's posible. You can implement your own QWidgetAction and add QToolButton in an horizontal layout do display the action:
class MyAction : public QWidgetAction
{
public:
MyAction( QObject * parent ) :QWidgetAction(arent) {}
void releaseWidget(QWidget * widget) {widget->deleteLater();}
QWidget * requestWidget ( QWidget * parent ) {
//Then implement your own widget
QWidget* widget = new QWidget(this);
widget->setLayout(new QHBoxLayout(wdiget));
widget->layout()->addWidget(new QToolButton("Example"));
return widget;
}
};
Other way its to set up the widget manually without subclassing:
QWidgetAction * wa = new QWidgetAction(this);
wa->setDefaultWidget(new QPushButton("Default")); // Example a pushbutton
And then use it in your QMenu, you can add other actions or different widgets:
MyWidgetAction *mwa = new MyWidgetAction(this); //3
ui->menuBar->addAction( mwa ); //3 - noop. nothing added to menu bar
Related
I created a layout contain a parent widget. In that parent widget i created another widget.
My code is similarly to this:
QGridLayout *layout = new QGridLayout();
QWidget *parentWidget = new QWidget();
layout->addWidget(parentWidget );
QWidget *childWidget = new QWidget(parentWidget);
How can i center the child widget in parent widget ?
The problem is we cannot get the true size of parent widget because it's in a layout.
Move the child inside the parent's showeEvent. You can use a bool flag to do it only when the parent is shown for the first time.
void Parent::showEvent(QShowEvent *)
{
if(_first_show)
{
_first_show = false;
_child->move(this->rect().center() - _child->rect().center());
}
}
Proof that it works (red is the parent, and blue is the child):
You can do this by setting fixed size of child widget and placing it inside grid layout of parent widget.
QGridLayout *layout = new QGridLayout();
QWidget *parentWidget = new QWidget();
layout->addWidget(parentWidget );
QWidget *childWidget = new QWidget(parentWidget);
QGridLayout *parentLayout = new QGridLayout();
parentWidget->setLayout(parentLayout);
parentLayout->addWidget(childWidget);
childWidget->setFixedSize(/*some fixed size for child widget*/);
Here they tell us how to create tabs:
Create a QTabWidget.
Create a QWidget for each of the pages in the
tab dialog, but do not specify parent widgets for them.
Insert child
widgets into the page widget, using layouts to position them as
normal.
Call addTab() or insertTab() to put the page widgets into the
tab widget, giving each tab a suitable label with an optional
keyboard shortcut.
So, I created a tab widget:
class mainWindow : public QDialog
{
Q_OBJECT
QWidget* m_mainWindow;
QTabWidget* tab;
...
Then I have a Widget Class that defines a "page":
class tradeView : public QWidget
{
Q_OBJECT
QWidget* tradeWidget;
...
THis is how the c'tor of the widget (that is supposed to go into the tab as a page) looks like:
tradeView::tradeView()
{
tradeWidget = new QWidget;
tradeWidget->setWindowTitle("Trade View");
tradeWidget->setGeometry(150,18,1800,800);
m_pTableWidget = new QTableWidget(this);
m_pTableWidget->setRowCount(100);
m_pTableWidget->setColumnCount(6);
m_TableHeader<<"Client Id"<<"Symbol"<<"Quantity"<<"Strategy Id"<<"Expiry" << "Side";
m_pTableWidget->setHorizontalHeaderLabels(m_TableHeader);
m_pTableWidget->verticalHeader()->setVisible(false);
m_pTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_pTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
m_pTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
m_pTableWidget->setShowGrid(false);
m_pTableWidget->setStyleSheet("QTableView {selection-background-color: red;}");
m_pTableWidget->setGeometry(QApplication::desktop()->screenGeometry());
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(m_pTableWidget);
tradeWidget->setLayout(layout);
}
Then I did the following inside my main dialog c'tor:
mainWindow::mainWindow(QWidget* parent):QDialog(parent)
{
m_mainWindow = new QWidget;
m_mainWindow->setWindowTitle("Main Window");
QVBoxLayout *layout = new QVBoxLayout;
tradeView* tradeViewWindow = new tradeView();
orderView* orderViewWindow = new orderView();
tab = new QTabWidget(this);
tab->addTab(tradeViewWindow, "Trade");
tab->addTab(orderViewWindow, "Order");
layout->addWidget(tab);
m_mainWindow->setLayout(layout);
m_mainWindow->setGeometry(150,18,1850,900);
m_mainWindow->show();
}
I was expecting the widget to show up in the tab.
But when I run the code, the tab is created, but is completely empty.
What am I missing here ?
Your widget construction is strange. The rough object ownership of your widgets is like the following:
MainWindow (top-level QDialog)
m_mainWindow (top-level QWidget)
tab (QTabWidget)
tradeViewWindow (QWidget)
orderViewWindow (QWidget)
tradeView->tradeWidget (hidden top-level QWidget)
QTableWidget
orderView->orderWidget (hidden top-level QWidget)
QTableWidget
Do you see the problem now? You actually have 4 top-level QWidgets and two of them are hidden. You are seeing empty tabs since you create QTableWidget in another QWidget which is hidden. In other words, QTableWidget's parent is not the tab, its parent is a hidden top-evel QWidget.
The solution: tradeView is already a QWidget itself, there is no need to create another tradeWidget inside it again. You should set the layout's parent to tradeView itself:
tradeView::tradeView()
{
//tradeWidget = new QWidget; // this is a hidden top-level QWidget
//tradeWidget->setWindowTitle("Trade View");
//tradeWidget->setGeometry(150,18,1800,800);
m_pTableWidget = new QTableWidget(this);
m_pTableWidget->setRowCount(100);
m_pTableWidget->setColumnCount(6);
m_TableHeader<<"Client Id"<<"Symbol"<<"Quantity"<<"Strategy Id"<<"Expiry" << "Side";
m_pTableWidget->setHorizontalHeaderLabels(m_TableHeader);
m_pTableWidget->verticalHeader()->setVisible(false);
m_pTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_pTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
m_pTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
m_pTableWidget->setShowGrid(false);
m_pTableWidget->setStyleSheet("QTableView {selection-background-color: red;}");
m_pTableWidget->setGeometry(QApplication::desktop()->screenGeometry());
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(m_pTableWidget);
//tradeWidget->setLayout(layout);
this->setLayout(layout);
}
As a sidenote, your MainWindow which is a QDialog creates another m_mainWindow as well, are you sure this is your intention?
I know how to create a new tab and add new widgets to a new tab of QTabWidget.
My Code:
QPlainTextEdit *plainTextEdit = new QPlainTextEdit;
ui->tabWidget->addTab(plainTextEdit , "New");
When I clicked the button, new tab and its own QPlainTextEdit widget will be created.
But I don't know how to set property to different QPlainTextEdit or save their contents.
For example, I want set font size of QPlainTextEdit in tab4 and save contents of QPlainTextEdit in tab5.
How to achieve these functions?
To get the widget at a tab index you can use the widget function of QTabWidget .
In your case in which QPlainTextEdit is the only widget of every tab page :
QPlainTextEdit* plainTextEdit = (QPlainTextEdit*) ui->tabWidget->widget(0); // for the first tab
plainTextEdit->setPlainText("Hello!");
If the QPlainTextEdit is not the only widget, you need to get the children of the widget and find the QPlainTextEdit in them :
QList<QPlainTextEdit *> allTextEdits = ui->tabWidget->widget(0)->findChildren<QPlainTextEdit *>();
if (allTextEdits.count() >0)
allTextEdits[0]->setPlainText("Hello!");;
You should have pointers to your QPlainTextEdits as members of the main widget class:
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
void someFunction();
private:
QPlainTextEdit *plainTextEdit;
}
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
...
plainTextEdit = new QPlainTextEdit;
ui->tabWidget->addTab(plainTextEdit , "New");
}
void Widget::someFunction()
{
plainTextEdit->setPlainText("Hello!");
}
I'm creating a text editor and I'd like to put the QComboBox in the QMenu. I didn't find any method inside the QMenu that handled such a thing. The closest is QMenu::addAction(). I was wondering of getting around this hurdle.
Thanks!
You have to subclass QWidgetAction and then simply call the addAction to your menu.
Example code for Spin Box Action with a label
class SpinBoxAction : public QWidgetAction {
public:
SpinBoxAction (const QString& title) :
QWidgetAction (NULL) {
QWidget* pWidget = new QWidget (NULL);
QHBoxLayout* pLayout = new QHBoxLayout();
QLabel* pLabel = new QLabel (title); //bug fixed here, pointer was missing
pLayout->addWidget (pLabel);
pSpinBox = new QSpinBox(NULL);
pLayout->addWidget (pSpinBox);
pWidget->setLayout (pLayout);
setDefaultWidget(pWidget);
}
QSpinBox * spinBox () {
return pSpinBox;
}
private:
QSpinBox * pSpinBox;
};
Now simply create it and add it to your menu
SpinBoxAction * spinBoxAction = new SpinBoxAction(tr("Action Title"));
// make a connection
connect(spinBoxAction ->spinBox(), SIGNAL(valueChanged(int)),
this, SLOT(spinboxValueChanged(int)));
// add it to your menu
menu->addAction(spinBoxAction);
QWidgetAction is a QAction that contains a QWidget. You can use this to encapsulate your QComboBox and add it to your menu via QMenu::addAction.
You can always use a QWidget or QFrame as the Menu Widget, then put a QHBoxLayout on it, and insert your QWidgets inside.
How can I add a checkbox/radiobutton/combobox to a QTableWidget or a QListWidget?
There are two methods:
void QTableWidget::setCellWidget(int row, int column, QWidget* widget)
and
void QListWidget::setItemWidget(QListWidgetItem* item, QWidget* widget)
They allow to insert any widget and other controls that inherit QWidget. Checkbox/radio button/combobox do inherit from QWidget.
For a checkbox using the item's setCheckState method should do what you need both for list and table widgets. See if code below would work for you:
List widget:
QListWidgetItem *item0 = new QListWidgetItem(tr("First"), listWidget);
QListWidgetItem *item1 = new QListWidgetItem(tr("Second"), listWidget);
item0->setCheckState(Qt::Unchecked);
item1->setCheckState(Qt::Checked);
Table widget:
QTableWidgetItem *item2 = new QTableWidgetItem("Item2");
item2->setCheckState(Qt::Checked);
tableWidget->setItem(0, 0, item2);
You can use delegates (QItemDelegate) for other types of editor's widgets, example is here: Spin Box Delegate Example.
I hope this helps.
you can add checkbox like this too
#include <QCheckBox>
void addCheckBoxAt(int row_number, int column_number,int state)
{
// Create a widget that will contain a checkbox
QWidget *checkBoxWidget = new QWidget();
QCheckBox *checkBox = new QCheckBox(); // We declare and initialize the checkbox
QHBoxLayout *layoutCheckBox = new QHBoxLayout(checkBoxWidget); // create a layer with reference to the widget
layoutCheckBox->addWidget(checkBox); // Set the checkbox in the layer
layoutCheckBox->setAlignment(Qt::AlignCenter); // Center the checkbox
layoutCheckBox->setContentsMargins(0,0,0,0); // Set the zero padding
/* Check on the status of odd if an odd device,
* exhibiting state of the checkbox in the Checked, Unchecked otherwise
* */
if(state == 1){
checkBox->setChecked(true);
} else {
checkBox->setChecked(false);
}
ui->job_table_view->setCellWidget(row_number,column_number, checkBoxWidget);
// Another way to add check box as item
/*
// QTableWidgetItem *checkBoxItem = new QTableWidgetItem("checkbox string ");
QTableWidgetItem *checkBoxItem = new QTableWidgetItem();
checkBoxItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
checkBoxItem->setCheckState(Qt::Checked);
ui->job_table_view->setItem(row_number,column_number,checkBoxItem);
*/
}
// call it like
addCheckBoxAt(0,0,1); // insert checkbox it 0,0 and check status true