How to undock tab with osgViewer from QTabWidget? - qt

I want to undock a QWidget from a QTabWiget (is set as centralWidget). The tab contains some Open Scene Graph content (OpenGL Window). When removing the Tab from the list and putting it into a new Dialog Window (=> undocking from tab) the scene data seems to be corrupt. It works with "standard widgets" but the osg seems to forget the scene.
Surprisingly, undocking works when using a QDockWidget (scene is visible after undocking the window).
Anyone knows how to undock a tab without corrupting the osgViewer?
Code called for to undock from tab and show in new dialog window:
QWidget* gv = // points to an osgViewer in a qt widget
QDialog* dlg = new QDialog(this);
dlg->setWindowTitle("hello earth");
QHBoxLayout* pMainLay = new QHBoxLayout;
gv->setMinimumSize(100,100);
gv->setGeometry(100,100,300,300);
pMainLay->addWidget(gv);
dlg->setLayout(pMainLay);
ui->tabWidget->removeTab(0); // removes the tab at position 0 (docked window)
dlg->show(); // should show the undocked dialog
There is nothing to see in the new dialog. Did I missed something?
How to "copy" the osg view properly into a new widget/dialog? Should I use a composite viewer for this kind of task? It seems there is not even the empty osg view visible (no blue canvas)...

It could be that something's going screwy when you add the osgViewer to another widget before removing it from the QTabWidget. Changing the order might help.
QWidget* gv = // points to an osgViewer in a qt widget
ui->tabWidget->removeTab(0); // removes the tab at position 0 (docked window)
QDialog* dlg = new QDialog(this);
dlg->setWindowTitle("hello earth");
QHBoxLayout* pMainLay = new QHBoxLayout;
pMainLay->addWidget(gv);
dlg->setLayout(pMainLay);
dlg->show(); // should show the undocked dialog

Related

QAction doesn't show QMenu

I'm creating my UI from Qt Designer and it generares this code:
toolBar = new QToolBar(MainWindow);
QIcon icon;
icon.addFile(QStringLiteral(":/main"), QSize(), QIcon::Normal, QIcon::Off);
MainWindow->addToolBar(Qt::TopToolBarArea, toolBar);
actionConvert = new QAction(MainWindow);
actionConvert->setObjectName(QStringLiteral("actionConvert"));
actionConvert->setIcon(icon);
toolBar->addAction(actionConvert);
Now, back in my frame code:
QMenu *menuAdd = new QMenu (this);
menuAdd->addAction (tr("&Files..."));
menuAdd->addAction (tr("&Directory..."));
ui->actionConvert->setMenu (menuAdd);
When I run the application I can see the qaction in the toolbar even the arrow pointing down, which indicates that there is a menu, but when I click it, the menu doesn't appear...any ideas?
There does not seem to be anything wrong with your example code.
It's possible that the reason you aren't seeing the menu is that you need to press and hold the button for a few seconds in order for the menu to appear. A single click will just execute the button's normal action.
See: QToolButton::ToolButtonPopupMode.
You should add menu with menuBar() method as in my case:
void MainWindow::ueInitMenu()
{
this->ueSetCodeRegisterPlacesAction(new QAction(tr("Places"),
this));
this->ueCodeRegisterPlacesAction()->setShortcut(tr("Ctrl+P"));
this->ueCodeRegisterPlacesAction()->setStatusTip(tr("Shows places code register"));
connect(this->ueCodeRegisterPlacesAction(),
SIGNAL(triggered()),
this,
SLOT(ueSlotShowPlacesView()));
this->ueSetCodeRegisterMenu(this->menuBar()->addMenu(tr("Code register")));
this->ueCodeRegisterMenu()->addAction(this->ueCodeRegisterPlacesAction());
} // ueInitMenu
especialy the line:
this->ueSetCodeRegisterMenu(this->menuBar()->addMenu(tr("Code register")));
so in your case:
this->menuBar()->addMenu(tr("System menu");
and then add actions. Also take a look at Menus Example.

close button on qDialog only closing on second click

I'm trying to generate a dialog that contains an ad-on tool that is separate from my main program, it its triggered from an action within the menus.
I've got the following code:
void MainWindow::on_actionCalibration_Tool_triggered()
{
QGridLayout *grid = new QGridLayout;
NewDialog.setLayout(grid);
NewDialog.setMinimumHeight(500);
NewDialog.setMinimumWidth(800);
QLabel *label = new QLabel;
QFont sansFont("MS Shell Dlg 2",22, QFont::Bold);
label->setText("Test");
label->setFont(sansFont);
QPushButton *okbutton = new QPushButton;
QPushButton *closebutton = new QPushButton;
okbutton->setText("Ok");
closebutton->setText("Close");
QTimer *timer = new QTimer;
connect(okbutton,SIGNAL(clicked()),this,SLOT(on_ScanpB_clicked()));
connect(closebutton,SIGNAL(clicked()),this,SLOT(CloseDialog()));
grid->addWidget(label);
grid->addWidget(okbutton);
grid->addWidget(closebutton);
NewDialog.exec();
NewDialog.show();
}
void MainWindow::CloseDialog()
{
NewDialog.close();
}
With NewDialog being defined in main window.h as a QDialog.
My issue is when I click the close button, the dialog will close for a split second then reopen, after I click the close button for a second time it closes for good.
Is there any better implementation or way around this?
Thanks
You should not call QDialog::show and QDialog::exec. Instead, pick one to call.
Use exec if you want to block user interaction with the dialog's parent while the dialog is open. The user will not be play with anything else in the application until they dismiss the dialog. This is called a modal.
Use show if you want to allow the user to work with the dialog and the rest of the application at the same time.
Usually you'd choose exec. It is easier to work with. In your case, you displayed the dialog twice by calling both functions.

Creating a Symbian's like application menu at S60

I wanted to make an app which is when started it shows a menu. It is just like when you open a Messaging app in S60. Here is a screenshot.
How do I make it? I have tried to make the centralWidget of the QMainWindow as QMenu, and adding QAction to the QMenu. But when I'm running it, the app don't show anything. And I have tried to make the QMenu using QMenuBar. And it is show okay. But I can't use the up/down key to select menu in the device. And when I press the options key (Qt::PositiveSoftKey), the menubar shows up too. And I didn't even add that to menuBar() which is owned by QMainWindow.
Here is my first code:
QAction* act1= new QAction(tr("act1"),this);
QObject::connect(tes,SIGNAL(triggered()),this,SLOT(close()));
QAction* act2= new QAction(tr("act2"),this);
QObject::connect(tes,SIGNAL(triggered()),this,SLOT(close()));
QMenu* menu = new QMenu(this);
menu->addAction(act1);
menu->addAction(act2);
setCentralWidget(menu);
And it shows nothing at the apps.
And here is my second try:
Qt Code: Switch view
QAction* act1= new QAction(tr("act1"),this);
QObject::connect(tes,SIGNAL(triggered()),this,SLOT(close()));
QAction* act2= new QAction(tr("act2"),this);
QObject::connect(tes,SIGNAL(triggered()),this,SLOT(close()));
QMenuBar* menubar = new QMenuBar(this);
QMenu* menu = menubar->addMenu(tr("menu"));
menu->addAction(act1);
menu->addAction(act2);
setCentralWidget(menu);
It shows the menu. But when I deploy to the device, I can't use the keypad to select the menu. And at the simulator, if I click other place than the QAction item, the menu lost.
I am using another approach by using QPushButton with Vertical Layout. Here is the code:
QWidget* centralWidget = new QWidget(this);
QScrollArea* scrollArea = new QScrollArea(this);
scrollArea->setWidget(centralWidget);
scrollArea->setWidgetResizable(true);
setCentralWidget(scrollArea);
QVBoxLayout* centralLayout = new QVBoxLayout(centralWidget);
QPushButton* button1 = new QPushButton(tr("button 1"));
QPushButton* button2 = new QPushButton(tr("button 2"));
centralLayout->addWidget(button1);
centralLayout->addWidget(button2);
centralLayout->setContentsMargins(0,0,0,0);
button1->setFocus();
Here it's look:
Okay, and that's look good enough. But if that's have 8 button. If it is only have 2 button, it looks like this:
looks kind of weird, huh? Any way to prevent this?
For me, the UI that you're trying to replicate is a list of options, so, why don't try to create the UI based on a list widget?
Asumming that you're going to use a list, you have to options from which you have to choose based on your needs and your app requirements:
Qt Widgets: Available in all the Qt supported Plataforms. Created for desktop and works great on it, but in feel strange on mobile devices. Take a look to the QListWidget and QListView.
Qt Quick: It isn't available for S40 phones or S60 3rd edition, not available for non-touch phones, basically. Created for "touch enabled UI's", it doesn't offer a stable set of widgets (buttons, comboboxes) yet, but it offers a set of primitives (like rectangles or images) that gives you a lot of freedom to create your UI's and it looks pretty good. I think that this is what Lucian used to create the UI from his answer.
This examples could be of particular interest: http://doc.qt.io/archives/qt-4.7/all-examples.html
Run the QtDemo to see all the examples live!
Hope it helps!
EDIT: Adding example of QListWidget
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
for(int i=0; i<10; i++) {
QListWidgetItem *item = new QListWidgetItem(QIcon("Qt.png"), QString("Item %1").arg(i));
ui->listWidget->insertItem(i, item);
}
ui->listWidget->setIconSize(QSize(64, 64));
connect(ui->listWidget, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(onItemClicked(QListWidgetItem*)));
}
void MainWindow::onItemClicked(QListWidgetItem *item)
{
QMessageBox::information(this, "", QString("%1 pressed").arg(item->text()));
}
You have all the freedom in the world to create your layout the way you like. Want those buttons closer together? Want them centered in the view?
The attached image took me 30 seconds to create and looks already decent (according to my pour designer skills).

Qt - Symbian Mobile - Soft key menus not displaying correctly

I create and show a QWebView with soft key options at the bottom. When I click "Options", a menu shows up, but it's tiny, black, and in the upper left hand corner (it should look like the standard blue soft keys and be directly above them). I followed this example.
//create webview
webView = new QWebView;
webView->setUrl(QString(":html/internal.html"));
//create menu
QAction *option1 = new QAction(tr("Back"), webView);
option1->setSoftKeyRole(QAction::PositiveSoftKey);
connect(option1, SIGNAL(triggered()), this, SLOT(deleteView()));
//create right softkey action to launch the "options" menu
QAction *option2 = new QAction(tr("Options"), webView);
option2->setSoftKeyRole(QAction::NegativeSoftKey);
connect(option2, SIGNAL(triggered(), this, SLOT(showMenu()));
QMenu *menuOptions = new QMenu(webView);
menuOptions->addAction(tr("Sub Menu 1"), this, SLOT(aboutView()));
menuOptions->addAction(tr("Sub Menu 2"), this, SLOT(aboutView()));
option2->setMenu(menuOptions);
//add softkey menus
QList < QAction* > softKeys;
softKeys.append(option1);
softKeys.append(option2);
webView->addActions(softKeys);
webView->show();
This example works well on simulator and also in phone. It is included in the QTDIR/examples/widgets folder since Qt 4.6.x

Connect custom widget to QWidgetTab for sizing

I'm trying to get every widget to scale with change in window size. I have a main window which has a QTabWidget with a QWidget holder for each tab. I then have a custom widget with a seperate .ui file that I set to fill the QWidget space of the tab. The problem is, I can't get the contents of the QWidget to expand, only the tab and QWidget of the main window. Also, I noticed if i change the ui->setupUi( ) argument for the custom widget from "this" to "parent" the problem is fixed, and the custom widget will scale correctly. The only problem with this is none of the buttons work when I do that. The application output reads out "No Slot" found errors for the buttons. What is the correct way to make this connection?
Edit: Example code
MainWindow:: ...
{
//assign customWidget to widget placeholder on tabWidget.
//holder is just a blank widget set in gridLayout on tab widget.
CustomWidget * customWidget = new CustomWidget(ui->customWidgetHolder);
setCentralWidget(ui->tabWidget);
//This gets the sizing I want with the tabs, but
//doesn't pass it past the customWidgetHolder.
}
From what I undertand, you need to use a layout, for your custom widget inside your tab
QTabWidget* tabWidget = new QTabWidget();
QWidget* tab = new QWidget();
QVBoxLayout* verticalLayout = new QVBoxLayout(tab);
YourWidget* widget = new YourWidget(tab);
verticalLayout->addWidget(widget);
tabWidget->addTab(tab, QString());
But you'll need to be more specific (code sample ?) about the SIGNAL/SLOT connection you've made if you want answer about it.

Resources