QChart log axis data not shown - c++

I have a 2Y Axis plo with a QValueAxison the y1 and QLogValueAxis on y2.
The linear plot is shown, the log plot is not shown. The data for both is the same.
I wonder how to set up the ticks and limits for the log axis?
This is the code:
chart = new QChart();
chart->legend()->hide();
chart->setTitle("Histogramm");
axisX = new QValueAxis;
axisX->setLabelFormat("%g");
chart->addAxis(axisX, Qt::AlignBottom);
series = new QLineSeries;
chart->addSeries(series);
axisY = new QValueAxis;
axisY->setTitleText("linear scale");
axisY->setLinePenColor(series->pen().color());
chart->addAxis(axisY, Qt::AlignLeft);
series->attachAxis(axisX);
series->attachAxis(axisY);
serieslog = new QLineSeries;
chart->addSeries(serieslog);
axisY3 = new QLogValueAxis();
axisY3->setTitleText("logarithmic scale");
axisY3->setBase(10.0);
axisY3->setLinePenColor(serieslog->pen().color());
chart->addAxis(axisY3, Qt::AlignRight);
serieslog->attachAxis(axisX);
serieslog->attachAxis(axisY3);
chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
// Create a layout and add Chart
QGridLayout *layout = new QGridLayout(this);
layout->addWidget(chartView);
void WidgetHistogramm::setData(const std::vector<int> data)
{
if (data.size() <= 0)
{
LOG_DEBUG() << "Histogram Data empty";
return;
}
auto max = *max_element(std::begin(data), std::end(data));
QVector<QPointF> points(data.size());
for(std::vector<int>::size_type i = 0; i != data.size(); ++i) {
points[i] = QPointF(i, data[i]*100/max);
}
series->replace(points);
serieslog->replace(points);
chart->axisX(series)->setRange(0, data.size());
chart->axisY(series)->setRange(0, 100);
chart->axisX(serieslog)->setRange(0, data.size());
chart->axisY(serieslog)->setRange(-1000, 1);
}

The range does not refer to the scaled values, but to the actual values, for example in your case it should be from epsilon to 100. On the other hand the values that are shown in the logarithmic scale must be positive, in your case I see that there is zeros so a possible solution is to add an epsilon:
void WidgetHistogramm::setData(const std::vector<int> data)
{
if (data.size() <= 0){
LOG_DEBUG() << "Histogram Data empty";
return;
}
auto max = *max_element(std::begin(data), std::end(data));
QVector<QPointF> points(data.size());
for(std::vector<int>::size_type i = 0; i != data.size(); ++i) {
points[i] = QPointF(i, data[i]*100.0/max + std::numeric_limits<qreal>::epsilon());
}
series->replace(points);
serieslog->replace(points);
chart->axisX(series)->setRange(0, points.size());
chart->axisY(series)->setRange(0, 100);
chart->axisX(serieslog)->setRange(0, points.size());
chart->axisY(serieslog)->setRange( std::numeric_limits<qreal>::epsilon(), 100);
}

Related

QGroupBox's child restricts shrink the form

I have a multiple screen video player, and I just want to keep 16:9 ratio. There is a qgroupbox as a container of a qwidget which plays video in it. I also use qgroupbox to show selected frame by painting border to green. I can't do this on qwidget because rendered video overlaps that. When I have done with resize, I emit a signal with mouseup event to be able to informed about the resize operation completed. Then I calculate new bounds for qwidget to keep 16:9 ratio and apply this values for qwidget. Here is the image to show you how my app looks like:
And here is the code that I use to resize qwidgets:
void playBack::OnWindowResized()
{
float ratio = 16.0f / 9.0f;
float w = playBackplayer_contList.at(0)->size().width(); //qgroupbox's width
float h = playBackplayer_contList.at(0)->size().height();//qgroupbox's height
float currentRatio = w / h;
float newW = 0;
float newH = 0;
if (currentRatio > ratio)
{
newH = h;
newW = h*ratio;
}
else if (currentRatio < ratio)
{
newW = w;
newH = w / ratio;
}
qDebug() << "NEW WIDGET SIZE: " << (int)newW << " x " << (int)newH;
for (int i = 0; i < playBackplayer_widgtList.count(); i++)
{
playBackplayer_widgtList.at(i)->setMinimumSize(newW, newH);
//playBackplayer_widgtList.at(i)->resize(newW, newH);
}
}
This code works perfectly when I enlarge form, but When I want to shrink, It doesn't allow me to do that. Because I set a minimum value for qwidgets. If I don't use setMinimumSize, use resize(w,h) instead, than orientation problems occur. And here is a example for this issue:
This code below shows ctor and this is where I set the layout:
playBack::playBack()
{
playback_player_1_widget = new QWidget;
playback_player_2_widget = new QWidget;
playback_player_3_widget = new QWidget;
playback_player_4_widget = new QWidget;
playback_player_1_widget_cont = new QGroupBox;
playback_player_2_widget_cont = new QGroupBox;
playback_player_3_widget_cont = new QGroupBox;
playback_player_4_widget_cont = new QGroupBox;
playBackplayer_widgtList.append(playback_player_1_widget);
playBackplayer_widgtList.append(playback_player_2_widget);
playBackplayer_widgtList.append(playback_player_3_widget);
playBackplayer_widgtList.append(playback_player_4_widget);
playBackplayer_contList.append(playback_player_1_widget_cont);
playBackplayer_contList.append(playback_player_2_widget_cont);
playBackplayer_contList.append(playback_player_3_widget_cont);
playBackplayer_contList.append(playback_player_4_widget_cont);
int rowcnt = 0;
int colcnt = 0;
for (int i = 0; i < 4; i++)
{
playBackplayer_contList.at(i)->setStyleSheet(QString("border:1px solid #000;background-color:#000;"));
playBackplayer_widgtList.at(i)->setStyleSheet(QString("background-color:#f00;"));
QGridLayout* layout = new QGridLayout;
layout->setRowStretch(0, 1);
layout->setColumnStretch(0, 1);
layout->setRowStretch(2, 1);
layout->setColumnStretch(2, 1);
playBackplayer_widgtList.at(i)->setMinimumWidth(100);
playBackplayer_widgtList.at(i)->setMinimumHeight(100);
playBackplayer_widgtList.at(i)->setMaximumWidth(10000);
playBackplayer_widgtList.at(i)->setMaximumHeight(10000);
layout->addWidget(playBackplayer_widgtList.at(i),1,1);
layout->setMargin(0);
layout->setSpacing(0);
playBackplayer_contList.at(i)->setLayout(layout);
mainLayout->addWidget(playBackplayer_contList.at(i), colcnt, rowcnt);
rowcnt++;
if (rowcnt % 2 == 0)
{
rowcnt = 0;
colcnt++;
}
playBackplayer_widgtList.at(i)->setAcceptDrops(true);
}
}
I have tried various things, I have tried to set size 0 for qwidget before resize, (in mousedownevent) that didn't work, I have tried deleting layout for qgroupbox, after resize happens, create new layout and set it for groupbox, that didn't work, I have tried layout()->adjustSize(), update(), repaint(), all that stuff didn't work. What am I missing? I need helps from you. Any help would be appreciated. Thank you in advance.
Do away with the grid layout inside the container group boxes. Instead, align and resize the video widget with setGeometry
Here is a simple subclass of QGroupBox I made that keeps your desired ratio and always stays in the center:
class RatioGroupBox : public QGroupBox{
Q_OBJECT
public:
RatioGroupBox(QWidget *parent = nullptr) : QGroupBox (parent){
setFlat(true);
setStyleSheet("border:1px solid #000;background-color:#000;");
setMinimumSize(100, 100);
setMaximumSize(10000, 10000);
ratio = 16.0f/9.0f;
ratioWidget = new QWidget(this);
ratioWidget->setStyleSheet("background: #f00;");
ratioWidget->setAcceptDrops(true);
}
protected:
void resizeEvent(QResizeEvent *){//or you can use your own resize slot
float w = width();
float h = height();
float currentRatio = w/h;
float newW(0);
float newH(0);
if (currentRatio > ratio){
newH = h;
newW = h*ratio;
}
else if (currentRatio < ratio){
newW = w;
newH = w / ratio;
}
ratioWidget->setGeometry((w-newW)/2, (h-newH)/2, newW, newH);
}
private:
QWidget *ratioWidget;
float ratio;
};
Your entire ctor will become something like:
playBack::playBack()
{
for(int r=0; r<2; r++){
for(int c=0; c<2; c++){
RatioGroupBox* playback_player_cont = new RatioGroupBox;
mainLayout->addWidget(playback_player_cont, c, r);
playBackplayer_contList.append(playback_player_cont);
}
}
}
You can of course access your video widgets by exposing ratioWidget any way you like. Either by making it public or creating a getter function.

Draw waveform from raw data using QAudioProbe

For some strange reason QAudioRecorder::audioInputs() returns twice as much devices that I actually have
They're seem to be duplicated but not really - looks like they giving different samples, because when I'm trying to play recorded audio from first two devices it sounds twice as fast, when second two devices sounds normally.
Heres my code:
#include "MicrophoneWidget.h"
#include <QLayout>
#include <sndfile.h>
MicrophoneWidget::MicrophoneWidget(QWidget *parent) : QWidget(parent)
{
QAudioEncoderSettings settings;
settings.setCodec("audio/PCM");
settings.setQuality(QMultimedia::HighQuality);
settings.setChannelCount(1);
recorder = new QAudioRecorder(this);
recorder->setEncodingSettings(settings);
button = new QPushButton();
button->setCheckable(true);
devicesBox = new QComboBox();
connect(devicesBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onDeviceChanged(int)));
for(const QString& device : recorder->audioInputs()) devicesBox->addItem(device, QVariant(device));
label = new QLabel();
connect(button, SIGNAL(toggled(bool)), this, SLOT(onButtonToggled(bool)));
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(devicesBox);
layout->addWidget(button);
layout->addWidget(label);
setLayout(layout);
probe = new QAudioProbe();
probe->setSource(recorder);
connect(probe, SIGNAL(audioBufferProbed(QAudioBuffer)), this, SLOT(onAudioBufferProbed(QAudioBuffer)));
}
void MicrophoneWidget::resizeEvent(QResizeEvent*)
{
pixmap = QPixmap(label->size());
}
void MicrophoneWidget::onAudioBufferProbed(QAudioBuffer buffer)
{
qDebug() << buffer.byteCount() / buffer.sampleCount();
const qint32 *data = buffer.constData<qint32>();
pixmap.fill(Qt::transparent);
painter.begin(&pixmap);
int count = buffer.sampleCount() / 2;
float xScale = (float)label->width() / count;
float center = (float)label->height() / 2;
for(int i = 0; i < count; i++) samples.push_back(data[i]);
for(int i = 1; i < count; i++)
{
painter.drawLine(
(i - 1) * xScale,
center + ((float)(data[i-1]) / INT_MAX * center),
i * xScale,
center + ((float)(data[i]) / INT_MAX * center)
);
}
painter.end();
label->setPixmap(pixmap);
}
void MicrophoneWidget::onButtonToggled(bool toggled)
{
if(toggled)
{
samples.clear();
recorder->record();
}
else
{
recorder->stop();
SF_INFO sndFileInfo;
sndFileInfo.channels = 1;
sndFileInfo.samplerate = 44100;
sndFileInfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_32;
QString filePath = "customWAV-" + QString::number(QDateTime::currentMSecsSinceEpoch()) + ".wav";
SNDFILE* sndFile = sf_open(filePath.toStdString().c_str(), SFM_WRITE, &sndFileInfo);
if(sndFile != nullptr)
{
sf_count_t count = sf_write_int(sndFile, samples.data(), samples.size());
qDebug() << "Written " << count << " items; " << (samples.size() / sndFileInfo.samplerate) << " seconds";
}
sf_close(sndFile);
}
}
void MicrophoneWidget::onDeviceChanged(int index)
{
recorder->stop();
recorder->setAudioInput(devicesBox->itemData(index).toString());
if(button->isChecked())recorder->record();
}
So, how should I parse the raw data to draw correct waveform?
Firs of all check that the buffer hast exactly the sample type that you expect, to do it, check the QAudioFormat sampleType function. There are 3 alternatives:
QAudioFormat::SignedInt,
QAudioFormat::UnSignedInt,
QAudioFormat::Float
This should help you to decide the correct cast for the given samples. In my case, as the different Qt examples, I use:
const qint16 *data = buffer.data<qint16>();
And them you can normalise it easily using this function:
qreal getPeakValue(const QAudioFormat& format)
{
// Note: Only the most common sample formats are supported
if (!format.isValid())
return qreal(0);
if (format.codec() != "audio/pcm")
return qreal(0);
switch (format.sampleType()) {
case QAudioFormat::Unknown:
break;
case QAudioFormat::Float:
if (format.sampleSize() != 32) // other sample formats are not supported
return qreal(0);
return qreal(1.00003);
case QAudioFormat::SignedInt:
if (format.sampleSize() == 32)
#ifdef Q_OS_WIN
return qreal(INT_MAX);
#endif
#ifdef Q_OS_UNIX
return qreal(SHRT_MAX);
#endif
if (format.sampleSize() == 16)
return qreal(SHRT_MAX);
if (format.sampleSize() == 8)
return qreal(CHAR_MAX);
break;
case QAudioFormat::UnSignedInt:
if (format.sampleSize() == 32)
return qreal(UINT_MAX);
if (format.sampleSize() == 16)
return qreal(USHRT_MAX);
if (format.sampleSize() == 8)
return qreal(UCHAR_MAX);
break;
}
return qreal(0);
}
Now you should iterate over the vector and divide by the peak that the functions returns, this will give a range of samples from [-1, 1], so save it in a QVector array to plot it.
To plot it, you have different alternatives, Qt introduce his own QtCharts module but you can still use QCustomPlot or Qwt. An example with QCustomPlot:
QCPGraph myPlot = ui->chart->addGraph();
myPlot->setData(xAxys.data(), recorded.data()); // init an X vector from 0 to the size of Y or whatever you want
ui->chart->yAxis->setRange(QCPRange(-1,1)); // set the range
ui->chart->replot();
You can find a complete example in the Qt examples or check my little GitHub project, LogoSpeech Studio, you will find complete example of how to plot the wave form, spectrogram, pitch and different properties of a signal.

QtCharts - Background, foreground display

I want to display a QGraphicsRectItem in my QChartView. But the rectangle is displayed behind the lines series in the chart.
I've tried to do a setZValue(10), for example, on my QGraphicsRectItem and setZValue(0) on my QChart but it is still displayed behind.
Obviously I want the informations in the rectangle to be displayed in front of the series of the chart.
Constructor
StatisticsChartView::StatisticsChartView(QWidget *parent, QChart *chart)
: QChartView(chart, parent)
{
/* Create new chart */
_chart = new QChart();
chart = _chart;
_chart->setAnimationOptions(QChart::AllAnimations);
/* Default granularity */
m_iGranularity = DEFAULT_GRANULARITY;
/* Creating ellipse item which will display a circle when the mouse goes over the series */
m_ellipse = new QGraphicsEllipseItem(_chart);
penEllipse.setColor(QColor(0, 0, 0));
penBorder.setWidth(1);
m_ellipse->setPen(penEllipse);
/* Creating text item which will display the x and y value of the mouse position */
m_coordX = new QGraphicsSimpleTextItem(_chart);
m_coordY = new QGraphicsSimpleTextItem(_chart);
penBorder.setColor(QColor(0, 0, 0));
penBorder.setWidth(1);
m_coordX->setPen(penBorder);
m_coordY->setPen(penBorder);
m_rectHovered = new QGraphicsRectItem(_chart);
m_rectHovered->setBrush(QBrush(Qt::yellow));
m_coordHoveredX = new QGraphicsSimpleTextItem(m_rectHovered);
m_coordHoveredY = new QGraphicsSimpleTextItem(m_rectHovered);
penBorder.setColor(QColor(0, 0, 0));
penBorder.setWidth(1);
m_coordHoveredX->setPen(penBorder);
m_coordHoveredY->setPen(penBorder);
m_lineItemX = new QGraphicsLineItem(_chart);
m_lineItemY = new QGraphicsLineItem(_chart);
penLine.setColor(QColor(0, 0, 0));
penLine.setStyle(Qt::DotLine);
m_lineItemX->setPen(penLine);
m_lineItemY->setPen(penLine);
/* Enable zooming in the rectangle drawn with the left click of the mouse, zoom out with right click */
rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
mousePressed = 0;
seriesHovered = false;
setMouseTracking(true);
_chart->setAcceptHoverEvents(true);
_chart->setZValue(50);
m_ellipse->setZValue(10); //so it is displayed over the series
m_coordHoveredX->setZValue(20); //so it is displayed over others
setRenderHint(QPainter::Antialiasing);
setChart(_chart);
}
Creation of series
void StatisticsChartView::drawCurve(bool bDrawScale)
{
int w = WIDTH;
int h = HEIGHT;
/* Creating series */
QLineSeries *lineFalse = new QLineSeries();
QLineSeries *lineAutomatic = new QLineSeries();
QLineSeries *lineOk = new QLineSeries();
QLineSeries *lineFalsePositive = new QLineSeries();
QLineSeries *lineManualTreatement = new QLineSeries();
QLineSeries *lineFalseNegative = new QLineSeries();
QList<QLineSeries*> lineSeriesList;
lineSeriesList << lineFalse << lineAutomatic << lineOk << lineFalsePositive << lineManualTreatement << lineFalseNegative;
QList<QString> nameSeriesList;
nameSeriesList << "False" << "Automatic" << "Ok" << "FalsePositive" << "ManualTreatement" << "FalseNegative";
QList<QVector<GraphPoint>> graphPointList;
graphPointList << gpFalse << gpDetected << gpOk << gpDetectedNotOk << gpManualTreatement << gpFalseNegative;
double graphX = 100.0 / (m_iGranularity);
bool pointsVisible = true;
for (int n = 0; n < lineSeriesList.count(); ++n)
{
/* Adding points to line series */
for (int i = 0; i < m_iGranularity + 1; ++i)
{
lineSeriesList[n]->append(i * graphX, (float)(graphPointList[n][i]).fValue * 100);
lineSeriesList[n]->setPointsVisible(pointsVisible);
lineSeriesList[n]->setName(nameSeriesList[n]);
}
}
_chart->legend()->setVisible(true);
_chart->legend()->setAlignment(Qt::AlignBottom);
/* Setting axis X and Y */
axisX = new QValueAxis();
axisY = new QValueAxis();
axisX->setRange(0, 100);
axisY->setRange(0, 100);
/* Adding line series to the chart and attaching them to the same axis */
for (int j = 0; j < lineSeriesList.count(); ++j)
{
_chart->addSeries(lineSeriesList[j]);
_chart->setAxisX(axisX, lineSeriesList[j]);
_chart->setAxisY(axisY, lineSeriesList[j]);
connect(lineSeriesList[j], SIGNAL(hovered(QPointF, bool)), this, SLOT(onSeriesHovered(QPointF, bool)));
}
_chart->resize(w, h);
return;
}
Drawing rectangle on chart
void StatisticsChartView::onSeriesHovered(QPointF point, bool state)
{
seriesHovered = state;
/* Updating the size of the rectangle */
if (mousePressed == 0 && seriesHovered == true)
{
/* x and y position on the graph */
qreal x = _chart->mapToPosition(point).x();
qreal y = _chart->mapToPosition(point).y();
/* x and y value on the graph from 0 to 100 for ou graph */
qreal xVal = point.x();
qreal yVal = point.y();
qreal maxX = axisX->max();
qreal minX = axisX->min();
qreal maxY = axisY->max();
qreal minY = axisY->min();
/* We don't want to display value outside of the axis range */
if (xVal <= maxX && xVal >= minX && yVal <= maxY && yVal >= minY)
{
m_coordHoveredX->setVisible(true);
m_coordHoveredY->setVisible(true);
m_rectHovered->setVisible(true);
m_ellipse->setVisible(true);
m_rectHovered->setRect(x - 31, y - 31, 30, 30);
qreal rectX = m_rectHovered->rect().x();
qreal rectY = m_rectHovered->rect().y();
qreal rectW = m_rectHovered->rect().width();
qreal rectH = m_rectHovered->rect().height();
/* We're setting the labels and nicely adjusting to chart axis labels (adjusting so the dot lines are centered on the label) */
m_coordHoveredX->setPos(rectX + rectW / 4 - 3, rectY + 1);
m_coordHoveredY->setPos(rectX + rectW / 4 - 3, rectY + rectH / 2 + 1);
/* Setting value to displayed with four digit max, float, 1 decimal */
m_coordHoveredX->setText(QString("%1").arg(xVal, 4, 'f', 1, '0'));
m_coordHoveredY->setText(QString("%1").arg(yVal, 4, 'f', 1, '0'));
m_ellipse->setRect(QRectF::QRectF(x, y, 10, 10));
m_ellipse->setPos(x, y);
m_ellipse->setBrush(QBrush(Qt::red));
}
else
{
/* We're not displaying information if out of the chart */
m_coordHoveredX->setVisible(false);
m_coordHoveredY->setVisible(false);
m_rectHovered->setVisible(false);
m_ellipse->setVisible(false);
}
}
else
{
/* We're not displaying information if series aren't hovered */
m_coordHoveredX->setVisible(false);
m_coordHoveredY->setVisible(false);
m_rectHovered->setVisible(false);
m_ellipse->setVisible(false);
}
}
You should try using a series especially for your rectangle.
Setting it as the last series, on your chart, to be above the other lines. And adding a legend or a callout for the text.

Updating QGridLayouts

Hi guys I'm coding game for my studies and I've big problems with that (My leg was injured and I couldn't go to lessons).
My job is to do simple Battleships game in c++, qt.
I'm in point where logic code is done, but gui is a big mess.
Here's code for gui .cpp file:
#include <QtWidgets>
#include "dialog.h"
Dialog::Dialog()
{
createGraczBox();
createKomputerBox();
createOdpowiedz();
QGridLayout *mainLayout = new QGridLayout;
mainLayout->addWidget(graczBox , 0 , 0 );
mainLayout->addWidget(komputerBox , 0 , 1 );
mainLayout->addWidget(Odpowiedz , 0 , 2 );
setLayout(mainLayout);
setFixedSize(800,400);
setWindowTitle(tr("Battleships!"));
}
void Dialog::createGraczBox()
{
graczBox = new QGroupBox(tr("Gracz"));
QGridLayout *layout = new QGridLayout;
for (int j = 0; j < NumGridRows; ++j) {
labels[j] = new QLabel(tr("%0").arg(j+1));
layout->addWidget(labels[j], 0 , j + 1 , Qt::AlignLeft);
}
for (int i = 0; i < NumGridRows; ++i) {
labels[i] = new QLabel(tr("%0").arg(i + 1));
layout->addWidget(labels[i], i + 1, 0);
}
for(int g = 1;g<10;++g)
{
layout->setColumnStretch(g,1);
}
graczBox->setLayout(layout);
}
void Dialog::createKomputerBox()
{
komputerBox = new QGroupBox(tr("Komputer"));
QGridLayout *layout = new QGridLayout;
for (int j = 0; j < NumGridRows; ++j) {
labels[j] = new QLabel(tr("%0").arg(j+1));
layout->addWidget(labels[j], 0 , j + 1 );
}
for (int i = 0; i < NumGridRows; ++i) {
labels[i] = new QLabel(tr("%0").arg(i + 1));
layout->addWidget(labels[i], i + 1, 0);
}
for(int g = 1;g<10;++g)
{
layout->setColumnStretch(g,1);
}
komputerBox->setLayout(layout);
}
void Dialog::createOdpowiedz()
{
Odpowiedz = new QGroupBox(tr("Komendy"));
QFormLayout *layout = new QFormLayout;
xLabel = new QLabel;
QPushButton *zmienna_x_przycisk = new QPushButton(tr("X"));
connect(zmienna_x_przycisk, SIGNAL(clicked()), this, SLOT(setx()));
yLabel = new QLabel;
QPushButton *zmienna_y_przycisk = new QPushButton(tr("Y"));
connect(zmienna_y_przycisk, SIGNAL(clicked()), this, SLOT(sety()));
xLabel->setText(tr("Aktualne X: %1").arg(zmienna_x));
yLabel->setText(tr("Aktualne Y: %1").arg(zmienna_y));
layout->addRow(xLabel);
layout->addRow(zmienna_x_przycisk);
layout->addRow(yLabel);
layout->addRow(zmienna_y_przycisk);
Odpowiedz->setLayout(layout);
}
void Dialog::setx()
{
bool ok_x;
x = QInputDialog::getInt(this, tr("Podaj X:"),
tr(""), 1, 1, 10, 1, &ok_x);
if (ok_x)
x=zmienna_x;
}
void Dialog::sety()
{
bool ok_y;
y = QInputDialog::getInt(this, tr("Podaj Y:"),
tr(""), 1, 1, 10, 1, &ok_y);
if (ok_y)
y=zmienna_y;
}
They way it should work:
I'm choosing x and y by clicking on it.
Choosing numbers in new window.
They should appear in "Aktualne X:/Y:".
When I've x and y, click ok button (he's not there by now).
Computer checking numbers marking it in space Komputer / Gracz.
Reset x and y to 0.
Show text "You missed. Computer missed."
Go on till one'll win.
But I don't know how to make my layout updating itself by other actions. I can't make dowhile work here.
You need to use signals and slots here. Create "OK" button and connect it to a function, that will be used to handle your x and y variables.

Could I thread this for loop

for(unsigned int mBlock = 0; mBlock < coords.size(); mBlock++)
{
WidgetType widgetType;
height = macBlockWidth + coords[mBlock].y;
width = macBlockHeight + coords[mBlock].x;
macBlockParent = new QWidget;
cooefsLink = new QPushButton(macBlockParent);
macBlock = new QWidget(macBlockParent);
widgetType.widget = macBlock;
widgetType.type = (macBlocks[mBlock][2] != 'S')
? (macBlocks[mBlock][0]) : (macBlocks[mBlock][2]);
blockWidgetTypes.push_back(widgetType);
connect(cooefsLink, SIGNAL(released()),
this, SLOT(showCoefficients()));
buttonSignals[cooefsLink] = mBlock;
constructMotionVector(mBlock);
macBlockLayout->addWidget(macBlockParent, height - 16, width - 16);
styleMacroBlocks(mBlock);
}
could I make a function out of this for loop where I could parallel the operation by splitting it into two different for loops both operating on the vector at the same time. One working on the first half items and the second thread building the second half. So for example
Thread 1
for(unsigned int mBlock = 0; mBlock < coords.size() / 2; mBlock++)
{
WidgetType widgetType;
height = macBlockWidth + coords[mBlock].y;
width = macBlockHeight + coords[mBlock].x;
macBlockParent = new QWidget;
cooefsLink = new QPushButton(macBlockParent);
macBlock = new QWidget(macBlockParent);
widgetType.widget = macBlock;
widgetType.type = (macBlocks[mBlock][2] != 'S')
? (macBlocks[mBlock][0]) : (macBlocks[mBlock][2]);
blockWidgetTypes.push_back(widgetType);
connect(cooefsLink, SIGNAL(released()),
this, SLOT(showCoefficients()));
buttonSignals[cooefsLink] = mBlock;
constructMotionVector(mBlock);
macBlockLayout->addWidget(macBlockParent, height - 16, width - 16);
styleMacroBlocks(mBlock);
}
Thread 2
for(unsigned int mBlock = coords.size() / 2; mBlock < coords.size(); mBlock++)
{
WidgetType widgetType;
height = macBlockWidth + coords[mBlock].y;
width = macBlockHeight + coords[mBlock].x;
macBlockParent = new QWidget;
cooefsLink = new QPushButton(macBlockParent);
macBlock = new QWidget(macBlockParent);
widgetType.widget = macBlock;
widgetType.type = (macBlocks[mBlock][2] != 'S')
? (macBlocks[mBlock][0]) : (macBlocks[mBlock][2]);
blockWidgetTypes.push_back(widgetType);
connect(cooefsLink, SIGNAL(released()),
this, SLOT(showCoefficients()));
buttonSignals[cooefsLink] = mBlock;
constructMotionVector(mBlock);
macBlockLayout->addWidget(macBlockParent, height - 16, width - 16);
styleMacroBlocks(mBlock);
}
Because its a real bottleneck for my system and I notice its only using one CPU and its maxing out that CPU. Any help would be great thanks.
Hm... If you have constructions like this: blockWidgetTypes.push_back(widgetType); in both threads, it's seems very dangerous for multithreaded execution.