Expected type-specifier before 'QwtLog10ScaleEngine'? - c++

Version: qwt 6.0.1
I've tried to develop logarithmic scaling for Spectrum.
I've used simple line to enable scaling plotspectrum->setAxisScaleEngine(QwtPlot::yLeft, new QwtLog10ScaleEngine);
Problems: the data are not drawn, so the plot is empty and the compiler returns following error:"expected type-specifier before 'QwtLog10ScaleEngine'"
Any help woulb be appreciated
Here is my code:
class SpectrumPlot : public QWidget
{
Q_OBJECT
public:
PlotSpektrum();
private:
QHBoxLayout* m_SpectrumLayout;
QwtPlot* m_SpectrumPlot;
QwtPlotCurve* m_SpectrumCurve;
QwtPlotMarker* m_Marker;
};
SpectrumPlot::SpectrumPlot()
{
m_SpectrumLayout = new QHBoxLayout();
m_SpectrumPlot = new QwtPlot();
m_SpectrumCurve = new QwtPlotCurve();
QwPlotGrid* pGrid = new QwtPlotGrid();
QPen GridPen;
GridPen.setColor(Qt::green);
GridPen.setWidthF(0.7);
GridPen.setStyle(Qt::DashLine);
QPen SpectrumPen;
SpectrumPen.setColor(Qt::white);
pGrid->setRenderHint(QwtPlotItem::RenderAntialiased);
pGrid->setPen(GridPen);
pGrid->enableXMin(true);
pGrid->attach(m_SpectrumPlot);
m_SpectrumPlot->setTitle("Spectrum");
m_SpectrumPlot->setCanvasBackground(QBrush(Qt::black));
m_SpectrumPlot->setAutoDelete(true);
m_SpectrumPlot->setAxisTitle(QwtPlot::xBottom, "Frequency Hz");
m_SpectrumPlot->setAxisScale(QwtPlot::xBottom, 100, nNyquistFrequency);
m_SpectrumPlot->setAxisScale(QwtPlot::yLeft, 0, 150);
m_SpectrumPlot->setAxisScaleEngine(QwtPlot::xBottom, new QwtLog10ScaleEngine());
m_SpectrumLayout->addWidget(m_SpectrumPlot);
this->setLayout(m_SpectrumLayout);
}

I think you should be using:
new QwtLogScaleEngine(10)
The manual for QwtScaleEngine doesn't show any classes called QwtLog10ScaleEngine.

Related

QListWidget items consistent positioning problem

I'm new to Qt framework. In new application I want to create list with customised items. These items are quite simple and must contain title label, thumbnail and description label (picture here)
For now I don't want to play with custom drawing and all that stuff becuase I think it's easier to do items I want with proper widget/layout so I decided to use QListwidget and subclassed QAbstractItemModel (KeyframeModel) and QListWidgetItem (TileWidgetItem).
After some coding it looks how I wanted but strange thing happens to QListWidget (grid mode) when I add some items. In my case a QListWidget is resizable (due to how it's embedded inside main layout) and number of columns should be dependent on list and items width. Items are fixed size (at least for now).
But when I resize the list one of the items at some list's width is misaligned and not I don't know what's going on. Below are te screenshots from app:
Pic. 1 List initial state (right after start)
Pic. 2 List after resizing #1
Pic. 3 List after resizing #2
Resizing #2 is a few pixels wider than resizing #1 and resizing #1 is hard to get (border case) - few pixels width less and I've got 2 columns (it's okay) but some pixels more and I end up with case #2.
In all cases number of columns is okay.
Sometimes also last item is misaligned after program start right-away like here (right after start like in pic. 1 but as you can see different result despite same list width).
I wonder why is it so inconsistent after start-up.
Do I missing something? Do I must do some parts in different way?
Or is it just some glitches in debug mode?
Below I post some code:
Application:
// Source file
QtGuiApplication1::QtGuiApplication1(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
//--------------------------------------------------------------------------------
// Add elements to the list
TileWidgetItem *item = new TileWidgetItem();
item->setData(TileWidgetItem::TileRole::TitleRole, QVariant("Long title"));
item->setData(TileWidgetItem::TileRole::DescriptionRole, QVariant("My long info"));
item->setText("My super text");
qDebug() << "Widget size hint: " << item->sizeHint();
ui.listWidget_moves->addItem(item);
item->updateView();
TileWidgetItem *item1 = new TileWidgetItem();
item1->setData(TileWidgetItem::TileRole::TitleRole, QVariant("Item #2"));
item1->setText("Tile #2");
ui.listWidget_moves->addItem(item1);
item1->updateView();
TileWidgetItem *item2 = new TileWidgetItem();
ui.listWidget_moves->addItem(item2);
item2->updateView();
TileWidgetItem *item3 = new TileWidgetItem();
ui.listWidget_moves->addItem(item3);
item3->updateView();
//--------------------------------------------------------------------------------
// Adjust cell size
QSize cellSize;
for (uint i = 0; i < ui.listWidget_moves->count(); i++)
{
int dim = ui.listWidget_moves->item(i)->sizeHint().height();
if (dim > cellSize.height())
cellSize.setHeight(dim);
dim = ui.listWidget_moves->item(i)->sizeHint().width();
if (dim > cellSize.width())
cellSize.setWidth(dim);
}
ui.listWidget_moves->setGridSize(cellSize);
}
Item widget:
// Source file
constexpr int MAX_THUMB_SIZE = 100;
TileWidgetItem::TileWidgetItem(QListWidget *listview)
: QListWidgetItem(listview, ItemType::UserType)
{
/* Prepare main widget */
QWidget *view = new QWidget();
view->setObjectName("tile");
view->setStyleSheet(
"QWidget#tile { margin: 4 8; background-color: #404040; border: 1 solid rgba(0,0,0,30%); border-radius: 4px }\n"
"QWidget#tile::hover { border: 1 solid #EEE; background-color: #484848 }\n"
"QWidget#tile[selected=true] { background-color: #00F }"
);
//-----------------------------------------------------------
/* Prepare layout */
QVBoxLayout *layout = new QVBoxLayout();
layout->setSizeConstraint(QLayout::SizeConstraint::SetFixedSize);
//-----------------------------------------------------------
/* Prepare title with icon */
QHBoxLayout *titleLayout = new QHBoxLayout();
QLabel *titleIcon = new QLabel();
titleIcon->setObjectName("titleIcon");
titleIcon->setStyleSheet("background-color: black");
titleIcon->setFixedSize(QSize(16, 16));
titleLayout->addWidget(titleIcon);
QLabel *title = new QLabel("Title");
title->setObjectName("title");
title->setMinimumWidth(60);
title->setStyleSheet("background-color: #800;");
titleLayout->addWidget(title);
QWidget *titleWidget = new QWidget();
titleWidget->setStyleSheet("background-color: #080");
titleWidget->setLayout(titleLayout);
layout->addWidget(titleWidget);
//-----------------------------------------------------------
/* Prepare thumbnail */
QLabel *thumbnail = new QLabel();
thumbnail->setObjectName("thumbnail");
thumbnail->setStyleSheet("background-color: black; border: 1 solid #F00");
thumbnail->setFixedSize(QSize(MAX_THUMB_SIZE, MAX_THUMB_SIZE * 0.7f));
thumbnail->setPixmap(QPixmap("Resources/moto.jpg").scaledToWidth(MAX_THUMB_SIZE));
layout->addWidget(thumbnail);
//-----------------------------------------------------------
/* Preparing additional info */
QLabel *description = new QLabel("Description");
description->setObjectName("description");
//description->setToolTip("Custom info tip");
description->setContentsMargins(4, 2, 4, 2);
layout->addWidget(description);
//-----------------------------------------------------------
view->setLayout(layout);
_customView = view;
_titleView = title;
_descriptionView = description;
setSizeHint(_customView->sizeHint());
updateView();
}
TileWidgetItem::~TileWidgetItem()
{
}
void TileWidgetItem::setData(int role, const QVariant &value)
{
QListWidgetItem::setData(role, value);
if (value.type() == QVariant::Type::String)
{
if (role == TileRole::TitleRole)
{
this->_titleView->setText(value.toString());
}
else if (role == TileRole::DescriptionRole)
{
this->_descriptionView->setText(value.toString());
}
setSizeHint(_customView->sizeHint());
}
}
void TileWidgetItem::updateView()
{
if (listWidget() != nullptr)
{
listWidget()->setItemWidget(this, this->_customView);
}
}
// Header file
class TileWidgetItem : public QListWidgetItem
{
public:
enum TileRole
{
TitleRole = Qt::UserRole + 1,
DescriptionRole,
ThumbnailRole
};
public:
TileWidgetItem(QListWidget *listview = nullptr);
~TileWidgetItem();
void setData(int role, const QVariant &value) override;
void updateView();
QWidget *customView() const { return _customView; };
QString getTitle() const { return _titleView->text(); };
QString getInfo() const { return _descriptionView->text(); };
private:
QWidget *_customView;
QLabel *_titleView;
QLabel *_descriptionView;
};
Platform: Windows 10
Qt version: 5.14.2
IDE: Visual Studio 2019 (with Qt VS Tools)
In the end I just used custom delegates which solved problems.
I wanted to overuse system and in I was defeated :)

Qt Charts Bar Plot Resize Crash

Situation:
I wrote a bar plot using QtCharts, QChartView, QChart, QBarSeries, QBarSet, QValueAxis and QCategoryAxis and it works fine.
Problem:
When i resize the window or use QRubberbandon the plot, it crashes.
What i tried:
Every other plot i wrote is not affected by that problem, including the ones using QStackedBarSeries. The Problem also occured in another program i wrote in the same situation.
Code - Head:
int D_Plot::Plot_Stat_Multi_MeanMedian(
QChartView *pChartView,
vector<vector<double> > *vv_SetSta,
bool pl_mean,
bool pl_sd,
bool pl_median,
bool pl_adm,
QString name_title,
QString name_categories,
QString name_y)
Code - Body:
//Chart
QChart *chart = new QChart();
chart->setTitle(name_title);
//Sets
QBarSet set_mean("Mean");
QBarSet set_sdev("Standard Deviation");
QBarSet set_medi("Median");
QBarSet set_aadm("Average Absolute Deviation from Median");
//Categories
QStringList categories;
//Series
QBarSeries *series = new QBarSeries();
for(unsigned int set = 0; set < vv_SetSta->size(); set++)
{
if(pl_mean) set_mean.append((*vv_SetSta)[set][c_STAT_MEAN_ARITMETIC]);
if(pl_sd) set_sdev.append((*vv_SetSta)[set][c_STAT_STAN_DEV_SAMPLE]);
if(pl_median) set_medi.append((*vv_SetSta)[set][c_STAT_MEDIAN]);
if(pl_adm) set_aadm.append((*vv_SetSta)[set][c_STAT_ABS_DEV_MED]);
categories.append(QString::number(set));
}
if(pl_mean) series->append(&set_mean);
if(pl_sd) series->append(&set_sdev);
if(pl_median) series->append(&set_medi);
if(pl_adm) series->append(&set_aadm);
chart->addSeries(series);
//Axis
QBarCategoryAxis *X_axis = new QBarCategoryAxis();
X_axis->append(categories);
X_axis->setTitleText(name_categories);
chart->setAxisX(X_axis, series);
QValueAxis *Y_axis = new QValueAxis();
Y_axis->setTitleText(name_y);
chart->setAxisY(Y_axis, series);
//Showing
pChartView->setChart(chart);
return ER_Okay;
You are creating your QBarSet objects locally (i.e. not via the new operator) and passing a pointer to these sets to the QBarSet::append method which AFAIK takes ownership if the objects pointed to i.e feels obliged to de-allocate them when going out of scope. This is bound to fail with locally allocated objects.

(several qdockWidget) QWidget::repaint: Recursive repaint detected kernel\qwidget.cpp: 5557

I need your help please!
I have 8 dockwidget in my Qmainwindow without a centralwidget, when I try to move, float, and undock dockwidget that contains a 3D view, the program crash with segmentation fault!
I remain at your disposal for more information, thanks a lot!
SUB_WIN_3D_VIEW.cpp
/* -----------------------
* ----------------------- */
#include "sub_win_3dview.h"
#include <QtWidgets/QAction>
#include <iostream>
#include <QDesktopServices>
SUB_WIN_3D_VIEW::SUB_WIN_3D_VIEW(Mainwindow const& p) : QDockWidget(),mainwindow_ins(p)
{
ui.setupUi(this);
this->setWindowTitle("3D view");
// Initiate the 3D scene
view.defaultFrameGraph()->setClearColor(QColor("#FFC0CBD9")); // light blue
widget = QWidget::createWindowContainer(&view);
view.renderSettings()->pickingSettings()->setPickMethod(Qt3DRender::QPickingSettings::TrianglePicking);
// Initiate the root entity (all the other entities of the scene should
// inherit it to be part of the 3D scene
rootEntity = new Qt3DCore::QEntity;
input = new Qt3DInput::QInputAspect;
view.setRootEntity(rootEntity);
view.registerAspect(input);
// Get the default camera entity from view
cameraEntity = view.camera();
// Set Z the be the vertical axis
cameraEntity->setUpVector(QVector3D(0, 0, 1));
// Initiate the camera controller
MyOrbitCameraController *camController = new MyOrbitCameraController(rootEntity);
camController->setCamera(cameraEntity);
camController->setLookSpeed(-300);
camController->setLinearSpeed(12);
// Initiate the light entity with its components below
lightEntity = new Qt3DCore::QEntity(rootEntity);
Qt3DRender::QPointLight *lightPoint = new Qt3DRender::QPointLight(lightEntity);
lightPoint->setColor("white");
lightPoint->setIntensity(1);
Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(lightEntity);
lightTransform->setTranslation(QVector3D(20, 20, 20));
lightEntity->addComponent(lightPoint);
lightEntity->addComponent(lightTransform);
// Initiate the modifier of the scene
modifier = new SceneModifier(rootEntity, cameraEntity);
modifier->pb_sl_reset();
view3d->widget->setMinimumSize(QSize(200, 100));
QSizePolicy view3d_siz(QSizePolicy::Expanding, QSizePolicy::Expanding);
widget->setSizePolicy(view3d_siz);
// Add the widget to a layout attached to the UI
ui.verticalLayout_2->addWidget(widget);
modifier->pb_sl_loadModel("simple");
connect(ui.Reload, SIGNAL(clicked(bool)),this, SLOT(reload_clicked()));
connect(ui.btn_CubeMiddle, SIGNAL(clicked(bool)),this, SLOT(cubeMiddle_clicked()));
connect(ui.btn_ObjUp, SIGNAL(clicked(bool)),this, SLOT(objUp_clicked()));
connect(ui.btn_ObjLeft, SIGNAL(clicked(bool)),this, SLOT(objLeft_clicked()));
connect(ui.btn_ObjRight, SIGNAL(clicked(bool)),this, SLOT(objRight_clicked()));
connect(ui.btn_ShowAxis, SIGNAL(clicked(bool)),this, SLOT(showAxis_clicked()));}
SUB_WIN_3D_VIEW::~SUB_WIN_3D_VIEW()
{
}
void SUB_WIN_3D_VIEW::reload_clicked()
{
// Reload's button simply load the same model again
modifier->pb_sl_loadModel("simple");
}
void SUB_WIN_3D_VIEW::cubeMiddle_clicked()
{
modifier->pb_sl_cameraMiddle();
}
void SUB_WIN_3D_VIEW::objUp_clicked()
{
modifier->pb_sl_cameraUp();
}
void SUB_WIN_3D_VIEW::objLeft_clicked()
{
modifier->pb_sl_cameraLeft();
}
void SUB_WIN_3D_VIEW::objRight_clicked()
{
modifier->pb_sl_cameraRight();
}
void SUB_WIN_3D_VIEW::showAxis_clicked()
{
modifier->pb_sl_enableRef(ui.btn_ShowAxis->isChecked());
}
#include "moc_sub_win_3dview.cpp"
Errors:
In file ....\include/QtCore/../../src/corelib/global/qglobal.h, line
770: Out of memory Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function. QWidget::repaint:
Recursive repaint detected
createDIB: CreateDIBSection failed. Invalid parameter passed to C
runtime function. Invalid parameter passed to C runtime function.
QWaitCondition: Destroyed while threads are still waiting
I solved the problem by modifying the qml code, before it was like that :
file.h
QQuickWidget *m_quickWidget_gauge_2;
QObject *object_gauge_2 ;
QQuickWidget *m_quickWidget_gauge_3;
QObject *object_gauge_3 ;
QQuickWidget *m_quickWidget_gauge_4;
QObject *object_gauge_4 ;
file.cpp
//QQuickWidget : actuator number 1
m_quickWidget_gauge_1 = new QQuickWidget(this) ;
m_quickWidget_gauge_1->setSource(QUrl("qrc:/Resources/res/gauge.qml"));
m_quickWidget_gauge_1->setResizeMode(QQuickWidget::SizeRootObjectToView);
m_quickWidget_gauge_1->setMinimumHeight(30);
m_quickWidget_gauge_1->setMinimumWidth(150);
m_quickWidget_gauge_1->setAttribute(Qt::WA_AlwaysStackOnTop);
m_quickWidget_gauge_1->setClearColor(Qt::transparent);
ui.horizontalLayout_al_1->addWidget(m_quickWidget_gauge_1, 1, Qt::AlignTop);
//QQuickWidget : actuator number 2
m_quickWidget_gauge_2 = new QQuickWidget(this) ;
m_quickWidget_gauge_2->setSource(QUrl("qrc:/Resources/res/gauge.qml"));
m_quickWidget_gauge_2->setResizeMode(QQuickWidget::SizeRootObjectToView);
m_quickWidget_gauge_2->setMinimumHeight(30);
m_quickWidget_gauge_2->setMinimumWidth(150);
m_quickWidget_gauge_2->setAttribute(Qt::WA_AlwaysStackOnTop);
m_quickWidget_gauge_2->setClearColor(Qt::transparent);
ui.horizontalLayout_al_2->addWidget(m_quickWidget_gauge_2, 1, Qt::AlignTop);
//QQuickWidget : actuator number 3
[....]
I made these changes and it works!!
file.h
QQuickView *m_qmlview_gauge_1;
QQuickView *m_qmlview_gauge_2;
QQuickView *m_qmlview_gauge_3;
file.cpp
m_qmlview_gauge_1 = new QQuickView(QUrl("qrc:/Resources/res/qml/actuator_gauge.qml"));
m_qmlview_gauge_1->setColor(QColor(Qt::white));
QWidget *container = QWidget::createWindowContainer(m_qmlview_gauge_1);
container->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Expanding);
ui.verticalLayout_11->addWidget(container);
m_qmlview_gauge_2 = new QQuickView(QUrl("qrc:/Resources/res/qml/actuator_gauge.qml"));
m_qmlview_gauge_2->setColor(QColor(Qt::white));
QWidget *container_1 = QWidget::createWindowContainer(m_qmlview_gauge_2);
container_1->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Expanding);
ui.verticalLayout_12->addWidget(container_1);
m_qmlview_gauge_3 = new QQuickView(QUrl("qrc:/Resources/res/qml/actuator_gauge.qml"));
m_qmlview_gauge_3->setColor(QColor(Qt::white));
QWidget *container_2 = QWidget::createWindowContainer(m_qmlview_gauge_3);
container_2->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Expanding);
ui.verticalLayout_13->addWidget(container_2);
i still not understand why the old code cause this crash, it worked well before !!

Scrollable view as TabWidget

Here is my problem, I display Buttons and Labels manually with setGeometry() method.
MyClass which inherits from QWidget
Here is my code :
void MyClass::function() {
QLabel *imgP;
QLabel *name;
QPushButton *newConv;
QPixmap *profilPic;
std::stringstream ss;
int j = 0;
int i = 0;
for (int tmp = 0; tmp < 15; tmp++)
{
if (i % 7 == 0 && i != 0)
{
i = 0;
j++;
}
ss << "Username " << tmp;
name = new QLabel(tr(ss.str().c_str()), this);
name->setAlignment(Qt::AlignCenter);
name->setGeometry((30 * (i + 1) + 240 * i), (30 + 390 * j),
240, 60);
profilPic = new QPixmap("./gui/img/avatar1.png");
imgP = new QLabel(this);
imgP->setPixmap(profilPic->scaled(240, 240));
imgP->setGeometry((30 * (i + 1) + 240 * i), (90 + 390 * j),
240, 240);
newConv = new QPushButton(tr("Chat"), this);
newConv->setGeometry((30 * (i + 1) + 240 * i), (330 + 390 * j),
240, 60);
newConv->setFocusPolicy(Qt::NoFocus);
connect(newConv, SIGNAL(released()), this, SLOT(addTab()));
ss.str("");
ss.clear();
i++;
}
}
It may be a bit more complicated than it should, but it works just the way I wanted ..
it looks like this :
As you can see, the result is good, I have my contacts displayed, but the 15th element is hidden because the window is too small. So my question is :
How can I make a ScrollView when this happens ?
I already know QScrollArea, but I would have to work with QBoxLayout, and I don't think this will do the job.
Thanks for your help !
EDIT
This is my MainWidget class which displays the window :
class QTabBar;
MainWidget::MainWidget(QWidget *parent) : QWidget(parent)
{
setFixedSize(1920, 1200);
setWindowTitle(tr("Babel"));
QVBoxLayout *mainLayout = new QVBoxLayout;
QTabBar *tb;
UiContact *contact = new UiContact(this);
QScrollArea *contactScrollArea = new QScrollArea();
contactScrollArea->setWidget(contact);
_tabWidget = new QTabWidget;
tb = _tabWidget->tabBar();
_tabWidget->addTab(new Home(), tr("Home"));
_tabWidget->addTab(contactScrollArea, tr("Contact"));
std::ostringstream oss;
_tabWidget->setTabsClosable(true);
connect(_tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int)));
tb->tabButton(0, QTabBar::RightSide)->hide();
tb->tabButton(1, QTabBar::RightSide)->hide();
_tabWidget->setFocusPolicy(Qt::NoFocus);
mainLayout->addWidget(_tabWidget);
setLayout(mainLayout);
}
QScrollArea is certainly the way to go. It is not necessary to use a layout, it's only necessary to force the widget to be the size it needs to be. A QScrollArea can handle any QWidget derived class, and it will display its scrollbars as needed.
Practically: if you can calculate how much space you need (which I think you can do), and set the size constraints of the containing widget accordingly, the QScrollArea will show the scrollbars automatically. You can use QWidget::setMinimumSize for that purpose, a simple setMinimumSize(itemWidth*7,itemHeight*(count%7)) should suffice.
This method does allow the widget to grow as large as to fill the QScrollArea. Also, it's possible to disable the frame around the QScrollArea if preferred.
edit:
You probably have something like this:
MyClass *myClass = new MyClass();
...
tabs->insertTab(1,myClass,"Contact");
An example implementation in that situation would be:
MyClass *myClass = new MyClass();
...
QScrollArea* contactScrollArea = new QScrollArea();
contactScrollArea->setWidget(myClass);
tabs->insertTab(1,contactScrollArea,"Contact");
It will place a scroll area inside the tab widget and put the instance of MyClass inside it
A QScrollArea is used as a relatively high container class. Think of a QScrollArea as a widget which can embed another widget inside it. By default it creates an empty widget, which can get a layout. But by using setWidget, you can literally place anything you want in it. A possible "combination" is a QLabel with a large licence text or any other widget that can potentially grow too large (like your widget).
Now, just some extra information:
When you draw stuff yourself (not creating several widgets and code your own layout stuff), you may use QAbstractScrollArea. It would give you full control. It gives scrollbars and a separate middle widget to which you can draw during paintEvent. But I think that's beyond the scope of this.
Now, for sake of clean coding. I would actually suggest you create a separate class ContactItem. It would consist of that label, image and pushbutton, held together with a QVBoxLayout (which makes them neatly packed above eachother). This "item" can be put inside a QGridLayout. This way, you don't need to concern yourself with arranging the items. If you set a minimum size on the picture, it will make sure the items are your preferred width/height. The label size constraints make sure that font differences don't affect the presentation (same goes for the buttons). Last but not least, your list is suddenly resizable. (By using setRowStretch and setColumnStretch you can make sure your list is centered, or top aligned, in case the window is larger than your list takes up.
Functional interpretation
Here I have a possible implementation (it isn't my best code) from what I got from the screenshot and given code.
It consists of a 'Widget' which is responsible for the tab layout:
mainwidget.h
#include <QWidget>
#include "uicontact.h"
class QTabWidget;
class MainWidget : public QWidget
{
Q_OBJECT
QTabWidget *_tabWidget;
public:
MainWidget(QWidget *parent = 0);
~MainWidget();
public slots:
void addChatTab();
};
mainwidget.cpp
#include "mainwidget.h"
#include <QScrollArea>
#include <QTabWidget>
#include <QTabBar>
#include <QVBoxLayout>
#include "home.h"
MainWidget::MainWidget(QWidget *parent)
: QWidget(parent)
{
setFixedSize(1920,1200);
setWindowTitle(tr("Babel"));
QVBoxLayout *mainLayout = new QVBoxLayout;
QTabBar *tb;
UiContact *contact = new UiContact(this);
QScrollArea *contactScrollArea = new QScrollArea();
contactScrollArea->setWidget(contact);
_tabWidget = new QTabWidget;
tb = _tabWidget->tabBar();
_tabWidget->addTab(new Home(), tr("Home"));
_tabWidget->addTab(contactScrollArea, tr("Contact"));
_tabWidget->setTabsClosable(true);
connect(_tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int)));
tb->tabButton(0, QTabBar::RightSide)->hide();
tb->tabButton(1, QTabBar::RightSide)->hide();
_tabWidget->setFocusPolicy(Qt::NoFocus);
mainLayout->addWidget(_tabWidget);
setLayout(mainLayout);
}
MainWidget::~MainWidget()
{
}
void MainWidget::addChatTab()
{
_tabWidget->addTab(new QWidget, tr("Number %1").arg(_tabWidget->count()-2));
}
The class MyClass is responsible for creating the 'contact' tab:
uicontact.cpp
#include "uicontact.h"
#include "mainwidget.h"
#include <QLabel>
#include <QPushButton>
UiContact::UiContact(MainWidget *owner,QWidget *parent) : QWidget(parent)
{
QLabel *imgP;
QLabel *name;
QPushButton *newConv;
QPixmap *profilPic;
int j = 0;
int i = 0;
for (int tmp = 0; tmp < 15; tmp++)
{
if (i % 7 == 0 && i != 0)
{
i = 0;
j++;
}
name = new QLabel(tr("Username %1").arg(tmp), this);
name->setAlignment(Qt::AlignCenter);
name->setGeometry((30 * (i + 1) + 240 * i), (30 + 390 * j),
240, 60);
profilPic = new QPixmap("./gui/img/avatar1.png");
imgP = new QLabel(this);
imgP->setPixmap(profilPic->scaled(240, 240));
imgP->setGeometry((30 * (i + 1) + 240 * i), (90 + 390 * j),
240, 240);
newConv = new QPushButton(tr("Chat"), this);
newConv->setGeometry((30 * (i + 1) + 240 * i), (330 + 390 * j),
240, 60);
newConv->setFocusPolicy(Qt::NoFocus);
connect(newConv, SIGNAL(clicked(bool)), owner, SLOT(addChatTab()));
i++;
}
setMinimumSize(270*7,420*(15/7+1));
}
The uicontact.h file is very trivial so omitted.
A few things to note: MyClass receives an 'owner' pointer, this allows it to talk directly to the top level widget responsible for adding tabs. Probably you want to look at QSignalMapper to be able to map the individual QPushButtons to a more known value. With QSignalMapper, you can map the button to an integer, string, QWidget* or QObject*.
Also note the tr("Contact %1").arg(tmp) which is the correct way to make your program locale aware.

Widget not shown in QMainWindow

Good evening,
the aim is to have a mainwindow (created without Designer but by coding) with three sections next to each other:
a list of data points (vector)
statistics about the data points
a graphical summary (histogram)of the data
I have started to create my own widget do draw a diagram (just a line for test purposes so far).
However, while the tableview widget is shown, the "diagram" widget (instance of class histogram) is not shown (should be a third vertical column).
A very similar problem in Stackoverflow gave me some direction. But while it helped me to display the widget with the table, I did not figure out how to show my custom widget.
post: widgets not shown in qt main window
I have also checked literature (Summerfield and Qt4 Hui Entwicklung mit C++ by Jürgen Wolff), but they only have examples with only one central widget.
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
MainWindow::MainWindow(QMainWindow *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags)
{
mainWidget = new QWidget(this);
setCentralWidget(mainWidget);
tableWidget = new QTableWidget(mainWidget); // QTableWidget to display the data vector
//...
// here comes code to fill the table...
//...
// result labels
lbl_sampleSize = new QLabel("sample size");
lbl_meanValue = new QLabel("mean");
lbl_sigma = new QLabel("sigma");
lbl_andersonDarling = new QLabel("Anderson Darling");
lbl_pValue = new QLabel("p-value for Anderson-Darling");
rightLayout = new QVBoxLayout(); // a vertical layout to contain labels
rightLayout->addWidget(lbl_sampleSize);
rightLayout->addWidget(lbl_meanValue);
rightLayout->addWidget(lbl_sigma);
rightLayout->addWidget(lbl_andersonDarling);
rightLayout->addWidget(lbl_pValue);
rightLayout->addStretch();
//diagram
diagram = new Histogram(mainWidget);
mainLayout = new QHBoxLayout(mainWidget);
mainLayout->addWidget(tableWidget,0);
mainLayout->addLayout(rightLayout,0);
mainLayout->addWidget(diagram, 0);
//mainWidget->setLayout(mainLayout);
}
screenshot:
remark:
with this code
//diagram
diagram = new Histogram();
mainLayout = new QHBoxLayout(mainWidget);
mainLayout->addWidget(tableWidget,0);
mainLayout->addLayout(rightLayout,0);
//mainLayout->addWidget(diagram, 0);
//mainWidget->setLayout(mainLayout);
diagram->show();
I was able to create a separate Widget with the test diagram.
(removed the parent information and called diagram->show())
Just set the minimum size (QWidget::setMinimumSize()):
diagram->setMinimumSize(100, 100);
More control over the widget sizing can be achieved through its size policy.