How to access widgets in different tabs of QTabWidget? - c++

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!");
}

Related

When QDockWidget with QWebEngineView is undocked, other docked widgets don't respond to user action

I have multiple dockwidgets in my main window and everything works fine until I add a dockedwidget with QwebEngineView as the widget.
When a dockwidget with QwebEngineView as a child is undocked, user inputs such as scroll bars in the other docked widgets are ignored. When the dockwidget with QWebEngineView is docked, it works fine.
The code I am testing with is the example project in
..\Qt 5.6\widgets\mainwindows\dockwidgets
with minor modification to add one more dockedwidget with QWebEngineView (see below).
///// added this in void MainWindow::createDockWindows()
WebView* w_view = new WebView(nullptr);
dock = new QDockWidget(tr("WebView"), this);
dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
dock->setWidget(w_view);
addDockWidget(Qt::LeftDockWidgetArea, dock);
viewMenu->addAction(dock->toggleViewAction());
/// the widget with QWebEngineView
class WebView : public QWidget {
Q_OBJECT
public:
WebView(QWidget* parent = 0)
:QWidget(parent)
{
setObjectName("WebView");
m_webEngineView = new QWebEngineView(this);
m_webEngineView->load(QUrl("http://qt-project.org/"));
}
~WebView() {}
private:
QWebEngineView* m_webEngineView;
};
///////////////////////////
Any help?

Arranging QMenu items horizontally

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

Creating tabs in Qt using QTabWidget

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?

Replace page of a QTabWidget with a new widget

Basically I have a QTabWidget. At first it has a form widget, widget1. After that form is done being interacted with, the new widget2 form should take over that same tab.
I thought tabWidget->setCurrentWidget(new widget2()); would work, but it's basically an overload for setCurrentIndex(int).
Does anyone know of a way to do this?
You can use a QStackedWidget for this type of thing, in a tab or elsewhere.
Put all the widgets you'll want to display in that tab inside a single QStackedWidget, and place that stacked widget in a tab.
Here's a quick'n'dirty demo:
#include <QtGui>
class W: public QWidget
{
Q_OBJECT
public:
W(QWidget *parent=0): QWidget(parent)
{
// stacked widget displays one of its "children" at a time
QStackedWidget *sw = new QStackedWidget;
QPushButton *b1 = new QPushButton("hello");
sw->addWidget(b1);
QPushButton *b2 = new QPushButton("world");
sw->addWidget(b2);
// tab widget and simplistic layout
QTabWidget *tw = new QTabWidget(this);
tw->addTab(sw, "tab");
QHBoxLayout *l = new QHBoxLayout;
l->addWidget(tw);
setLayout(l);
// signal mapper to demo the widget switching
QSignalMapper *m = new QSignalMapper(this);
connect(b1, SIGNAL(clicked()), m, SLOT(map()));
m->setMapping(b1, 1);
connect(b2, SIGNAL(clicked()), m, SLOT(map()));
m->setMapping(b2, 0);
connect(m, SIGNAL(mapped(int)), sw, SLOT(setCurrentIndex(int)));
}
};

Is there a way to add a QWidget to a QMenu in QtCreator

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.