How do I make Qt graphs appear in the same window? - c++

I am working in Qt in my program. I have a widget window and I have placed a button and a list box in it. Then I have made a class called myplot which graph plotting is done. Then in my button event handler I have called the object of myplot
myplot * p1 = new myplot(session,session ,24, "session"); // send arrays in argument containing the data to be plot
p1->show();
myplot * p2 = new myplot(payload,payload ,24, "payload"); // send arrays in argument containing the data to be plot
p2->show();
It is working fine as my graph appear in new window, but what I want is that graphs should appear in my mainwidget window.
What I did next was to remove the title bar of my graphs window I wrote this
Qt Code:
p1->setWindowFlags(Qt::FramelessWindowHint);
p2->setWindowFlags(Qt::FramelessWindowHint);
Now
1) what should I do to place and append the graphs window in my main window? Also when I close main window my graph window should close.
2) when I select an other value from the list box and click button my old graph disappear and new should appear
i drag and droped a verticlalayout then write
ui->verticalLayout->addChildWidget(p1);
but got an error
/usr/include/qt4/QtGui/qlayout.h:191: error: ‘void QLayout::addChildWidget(QWidget*)’ is protected
then i draaged and droped a scrollarea and wrote
myplot * p1 = new myplot(session,session ,24, "session");
p1->setWindowFlags(Qt::FramelessWindowHint);
ui->scrollArea->addScrollBarWidget(p1,0);
p1->show();
my graphs stopped appearing kindly guide me am i doing it wrong or what the right way

Apparently, myplot is a childclass of QWidget. So you can just define a layout on your main window (e.g. using QHBoxLayout), and add those two widgets to it. This will cause them to be drawn inside the mainwindow. Also make sure that you pass the main window as the QWidget parent of the plots.
For replacing the plots, you can either remove the old plots from the layout and add new ones. But I would prefer to make the plots members of your main window and include some update method that would redraw with the new data

When you call show on widgets with no parent like that, it automatically gets wrapped in a window. What you should do is create one widget and add the graphs to it's layout. See QMainWindow examples, and section about dock widgets if that's what you want.

Basically you don't need to worry about the window they are appearing in, it is only appearing because they have no other parent.
What you need to do is to specify a parent widget when you construct them.
(This answer is based on the assumption that your plots are also QWidgets, if you could mention what class they actually are and perhaps link to the documentation it would really help us to answer you.)

Related

Application structure with three main windows

I want to build a level/game editor that looks like the Skyrim Creation Kit. On the image you can see:
the main window/frame with a menu, a toolbar and a status bar at the bottom,
the Render Window that displays the current loaded level,
the Object Window that contains every objects/entities used in the game,
and the Cell View that contains on the left a list of all the levels and on the right all the entities belonging to the current loaded level.
One thing to note is that these three windows are floating, you can move them around and should always be present while editing a level.
I'd like to have some advice on how should I structure my MFC project in order to mimic the Skyrim editor: I don't know if I should use CDialog or simply CFrames for each window. If you want to know what I've done, you can read the following paragraphs.
Here is a picture showing what I've managed to do.
With MSVC I created an MFC project "based on dialogbox" but I don't know if it is a mistake, maybe I should have chosen the SDI template because there is indeed a single document (the document is all the data for the game which consists of entities, levels, spritesheets, sounds effects, scripts, dialogues...).
For now I have managed to create the main window and the render window. The main window is derived from CDialogEx and is created by calling DoModal() in the InitInstance() of the applciation.
BOOL CGameEditorApp::InitInstance() {
// ...
CGameEditorDlg dlg; // main window derived from CDialogEx
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
// ...
}
Inside OnInitDialog() of the main window, I create the render window like so
BOOL CGameEditor1Dlg::OnInitDialog() {
// ...
m_RenderWindow.Create(IDD_DLG_RENWIN);
// ...
}
Now I have a problem when trying to create the object window. In order to replicate the one of the Skyrim editor, I want a CSplitter with one row and two columns: the left pane would have the Filter option and a CTreeCtrl and the right pane would have a CListCtrl. So I tried to use a CDialog jsut like the render window but it appears that it is not possible to split a CDialog object. Now I've found a code sample where a CFrameWnd was created inside a CDialog and then a CSplitter was possible inside this frame but I cannot make it working since my knowledge of MFC is very little.

QAction with icon displays checkbox on top

I have a menu with checkable QActions in it: (ed: these calls are within a QWidget subclass, so 'this' points to the associated widget).
QAction* action = new QAction(icon, actionName, this);
action->setCheckable(true);
action->setActionGroup(m_actionGroup);
menu->addAction(action);
This menu is attached to a tool button, which is in a QWidget with a few other tool buttons. Previously, it was part of a larger widget, but I've been refactoring to confine some things together.
When it was previously part of the larger widget, these actions and their icons displayed fine. Now, however, the icons are drawn in a dotted pattern and a box for a check box is drawn on top. When I hover over an action, the dotted action goes away entirely, and it's just the check box. When I select an action, the icon appears normally.
I've tried doing the same in a little toy program, and the menu displays correctly then, so I'm having trouble reproducing the issue outside of my rather large program. Has anyone seen behaviour like this before, or know how to fix it?
Qt 5.5 on Ubuntu 16.04 is the platform information.
Edit: It gets even stranger. The original implementation created the QMenus without parents. Which I would have avoided because of memory leak concerns. But if you create the menu with the widget holding the button as a parent, then you get this behaviour. It's something about the QMenu being constructed with a parent that is creating issues, not the QAction.

Qt/C++ Technique To Show Inline Dialog

I have QtCreator 5.5 for the Mac, using C++, and I'm new at this. I have a MainForm window. I want to show a dialog inside that but draw it separately in its own UI designer. Then, at runtime, my code will pull that other UI and show it inside that window.
Imagine for instance a main application window. You click a button and you need to see a confirmation dialog. Normally you could do that with a separate window. Instead, I want it to be inline at runtime, to show it like a widget on the main window.
Sure, I could draw my dialog on top my existing window in a widget, but that defeats the point where I want to be able to adjust it in its own designer window, and just load it as necessary in the main window when I need it.
What's the technique in QtCreator and C++ to do this?
Open QtCreator. This task can only be done through there.
Assuming you have a regular Qt Widget Application, you need to just add a QWidget control on the MainWindow's centralWidget in the UI Designer.
Next, click Edit in the UI Designer and then rightclick Forms. Choose Add New...
In the dialog that opens up, choose Qt > Qt Designer Form Class, and click Choose...
Select Widget and then go with the defaults on the rest. This creates a widget called Form, and the form.h and form.cpp will also be added to your project.
Now find the form.ui and open it in Qt Designer. Add a Stacked Widget Control on the QWidget form. Size it to the same size as the parent widget. Next, stick a Label Control on the Stacked Widget Control's first page. This label will be temporary just to prove that this works. You'll set it to the text of "Testing". Now close the designer.
Flipping back to your UI File of your Main Window, find that QWidget you added and rightclick it. Choose Promote... and a dialog box appears. In that dialog, set Promoted Class Name to Form and then set Header File to form.h. Leave everything else on defaults and click Add and then Promote.
You may be expecting to see an immediate change in your Main Window in that QWidget that you added previously. However, that's not how this works unfortunately. You only see the change at runtime. So, now you should Run your application in Qt Creator. You'll see when it runs that your widget now contains the contents of that form.ui component you created.
Now, here's where it gets interesting. You can now draw all your inline modal dialogs on that form.ui, just putting them on different pages of your Stacked Widget control. You can also set the properties of your widget so that the background of the QWidget container is opaque and dark (creating a background dimmer) and then, at runtime, resize the QWidget to the size of your Main Window. When you need to switch to a different dialog, you can use setCurrentWidget() or setCurrentIndex() on that StackedWidget item like so:
QStackedWidget *w = ui->widget->findChild<QStackedWidget *>("stackedWidget");
w->setCurrentIndex(1);
In that example, I had a QWidget control on my MainWindow named simply widget. I then found the control on it called stackedWidget. Once I had it, I used the setCurrentIndex(x) method on it to change the page of that widget to show the one I needed. Remember that this is a zero-based index. So, (1) would be page 2.
QMainWindow::setCentralWidget
Inside your QMainWindow constructor add:
MyDialogClass myDialog = new MyDialogClass();
setCentralWidget(myDialog);

How to manage QSplitter in Qt Designer

When I press a button, I bring up a dialog where user select things and press 'Ok' at the end. I want a splitter in this dialog. Left pane will show tree and right will show something else. How do I do that right?
From Qt example itself:
QSplitter *splitter = new QSplitter(parent);
QListView *listview = new QListView;
QTreeView *treeview = new QTreeView;
QTextEdit *textedit = new QTextEdit;
splitter->addWidget(listview);
splitter->addWidget(treeview);
splitter->addWidget(textedit);
So in this example, splitter is created without any dialog resource. If I have to create this way, that would mean I have to create all my controls in the code as well rather than Qt Creator.
What is the right way to do this when I need other controls on the screen?
You can simply create splitter containing items in Qt Designer :
First place your widgets on your dialog or widget in designer (They should not be in a layout)
Select the widgets that you want to be in a splitter (By holding CTL and clicking on them)
Right click on a selected widget and from Layout menu select Lay Out Horizontally in Splitter or Lay Out Vertically in Splitter.
Now apply a grid layout to the dialog and everything should be OK. You would see something like this in Object Inspector View :
Okay, I know this is ancient, but here's the complete answer.
First, within some sort of widget container, plop your pieces in. For the window I just did, I have a Widget as my window. I put two widgets inside that labeled something like topContainer and bottomContainer. I then put all the widgets they each need into them, and gave them their own layouts.
Then do NOT select the main container. Select the two widgets you want to split. You're in effect putting a splitter on them, not on the main container. So I went to the widget list window and selected both together, then right-click for the dialog window, scroll down to the Layout option, and "Lay Out Vertically in a Splitter" is NOT greyed out. Select it.
You still need a layout on the main container. A splitter is not a layout. So at that point, I just put a vertical layout on the main container.
To repeat: you are NOT setting a layout on the container holding the pieces you're trying to split. You are selecting the two widgets to split and adding a QSplitter around them. That's the trick to get it to work.
You can still create your controls in a .ui file using Qt Designer (integrated in Qt Creator). Within Qt Designer, add a QWidget object to your dialog. Then, from QDialog derived class you'll write, directly in your constructor, create your QSplitter using the QWidget object as a parent.
This way, you can create all but the splitter object from Qt Designer.
I think it's also possible to create the QSplitter (as you can create a QButton, QCheckBox...) item directly from Qt Designer.

Defining buttons in OpenGL-window

My question is, if it is possible to display buttons on an opengl-window. As you can see on the picture I have created in the main window two smaller ones. The right grey corner is designated for the buttons(marked with a red rectangle). This I created before using Qt. Now I see that Qt is always creating the buttons at the border of the window. Is it possible to place my buttons in this red rectangle?
I am using a mac.
Yes. In code, set the containing widget as the parent of the contained widget in its constructor or use setParent() after it has already been constructed.