Get error messages when using QPrinter, QPainter and QTextDocument together - qt

In my Qt application, I want to create a preview page with the content that contains the Header, Footer title and a TableView.
This is the code I used:
void MainWindow::print(QPrinter *printer)
{
int xscale = 50;
int yscale = 30;
QPoint top_left = QPoint(xscale, yscale);
QPoint top_right = QPoint(xscale + 552, yscale + 20);
QPoint bottom_left = QPoint(xscale, yscale + 1020);
QPoint bottom_right = QPoint(xscale + 492, yscale + 1020);
QPainter painter(printer);
painter.setRenderHints(QPainter::Antialiasing |
QPainter::TextAntialiasing |
QPainter::SmoothPixmapTransform, true);
// Header
painter.setFont(QFont("Arial", 10));
painter.drawImage(top_left, QImage(":/images/images/logo.png"));
painter.drawText(top_right, "Header");
// Print the Table
QString strStream;
QTextStream out(&strStream);
out << "<html>\n"
"<head>\n"
"<meta content=\"text/html; charset=utf-8\">\n"
"<title>Demo MyTableView</title>\n"
"<style tyle=\"text/css\">th{font-size: 14pt}\n td{font-size: 12pt}\n table td + td + td + td{font-weight:bold}</style>"
"</head>\n"
"<body bgcolor=#ffffff link=#5000A0>\n"
"<table cellspacing=\"0\" cellpadding=\"2\" border=\"1\" width=\"100%\">\n";
// Print the headers
out << "<thead><tr bgcolor=\"#ffffff\">";
for (int column = 0; column < columnCount; column++)
if (!myTableView->isColumnHidden(column))
out << QString("<th>%1</th>").arg(myTableView->model()->headerData(column, Qt::Horizontal).toString());
out << "</tr></thead>\n";
// Print the data
for (int row = 0; row < rowCount; row++) {
out << "<tr>";
for (int column = 0; column < columnCount; column++) {
if (!myTableView->isColumnHidden(column)) {
QString data = myTableView->model()->data(myTableView->model()->index(row, column)).toString().simplified();
out << QString("<td bkcolor=0 align=center>%1</td>").arg((!data.isEmpty()) ? data : QString(" "));
}
}
out << "</tr>\n";
}
out << "</table>\n"
"</body>\n"
"</html>\n";
QTextDocument *document = new QTextDocument();
document->setHtml(strStream);
document->print(printer); // I got the error messages at here
delete document;
// Footer
painter.setFont(QFont("Arial", 10));
painter.drawText(bottom_left, "Copyright 2013");
// Get current date and time
QDateTime dateTime = QDateTime::currentDateTime();
QString dateTimeString = dateTime.toString();
painter.drawText(bottom_right, dateTimeString);
}
When I run the application, I only see Header and Footer title in the preview page, the TableView is not shown. Then I used qDebug() to check and I got the error messages
QPrinter::setDocName: Cannot be changed while printer is active
QPainter::begin: A paint device can only be painted by one painter at a time.
at the line
document->print(printer);
How can I solve this issue to print the data normally with the Header, Footer title and TableView?
Thanks for your help!

Well, if Qt complains about using multiple painters at a time, make it use only one:) In other words, just split the code in your MainWindow::print() function into the smaller routines for each part of your document:
void MainWindow::drawHeader(QPrinter *printer)
{
QPainter painter(printer);
// .. Draw the header
[..]
}
void MainWindow::drawFooter(QPrinter *printer)
{
QPainter painter(printer);
painter.setFont(QFont("Arial", 10));
painter.drawText(bottom_left, "Copyright 2013");
[..]
}
void MainWindow::drawTable(QPrinter *printer)
{
QTextDocument document;
document.print(printer);
[..]
}
And finally:
void MainWindow::print(QPrinter *printer)
{
// Init something.
drawHeader(printer);
drawTable(printer);
drawFooter(printer);
[..]
}

Related

QT: Generate a bar graph in a headless AMI Server. Cannot start X Display

I'm doing some processing on an Amazon Linux EC2 AWS server. When something goes wrong I need to send an email with a bar graph. I want to generate a bar graph myself, and I'm doing so by using QPainter and QImage. I'm developing an example application to simply generate the bar graph, right now. So what I do is I develop on my laptop and when I have something that works upload the code to the EC2 server and compile it there. Then run the resulting application in the server.
However, here is the hiccup. When I tried to draw text using QPainter, the program in my laptop crashes. This is because I use a QCoreApplication instead of QApplication in my main.cpp.
So I change to QApplication which fixes the problem. I upload the code to the server and compile it. Then when I try to run it, I get:
qt.qpa.screen: QXcbConnection: Could not connect to display
Could not connect to any X display.
This is, of course, because the server is headless.
My question is: is there something I can install in the server that would allow me to fully use QPainter's capabilities?
Edit:
My main.cpp
#include <QApplication>
#include "../../CommonClasses/DataAnalysis/BarGrapher/bargrapher.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// Setup
qreal W = 1024;
qreal H = 768;
// A fictional data set;
QList<qreal> ds1;
ds1 << 50 << 500 << 368 << 198;
QStringList descs;
descs << "Item 1";
descs << "A somewhat long and complex description";
descs << "Item 2";
descs << "Item Another";
// The actual bar graph
BarGrapher bg;
bg.configureGraphText(W,H,descs,"Some sort of label","The title of this damn thing");
BarGrapher::DataSet ds;
ds << ds1;
QImage result = bg.generateGraph(ds);
qWarning() << "ERROR" << bg.getError();
result.save("mytest.png");
qWarning() << "DONE";
return a.exec();
}
My bargrapher.cpp
#include "bargrapher.h"
const qreal BarGrapher::PROYECTION_FACTOR = 0.707106;
const qreal BarGrapher::LEFT_MARGIN = 0.1;
const qreal BarGrapher::RIGHT_MARGIN = 0.04;
const qreal BarGrapher::TOP_MARGIN = 0.08;
BarGrapher::BarGrapher()
{
}
void BarGrapher::configureGraphText(qreal width, qreal height, const QStringList &xItems, const QString &ylabel, const QString &title){
graphTitle = title;
W = width;
H = height;
itemDescriptions = xItems;
yAxisText = ylabel;
}
QImage BarGrapher::generateGraph(const DataSet &dataSet){
QImage graph(W,H,QImage::Format_RGB888);
error = "";
// Making sure that the data is coherent.
if (dataSet.isEmpty()){
error = "No data was presented";
return graph;
}
if (dataSet.size() > 2){
error = "Cannot have more than two data sets, passed " + QString::number(dataSet.size());
return graph;
}
qint32 numItems = dataSet.first().size();
for (qint32 i = 0; i < dataSet.size(); i++){
if (numItems != dataSet.at(i).size()){
error = "All data sets must be the same size: " + QString::number(numItems) + " however data set " + QString::number(i) + " has " + QString::number(dataSet.at(i).size());
return graph;
}
}
if (!itemDescriptions.isEmpty()){
if (numItems != itemDescriptions.size()){
error = "The number of item descriptios (" + QString::number(itemDescriptions.size()) + ") must coincide with the numer of points in the data set (" + QString::number(numItems) + ")";
return graph;
}
}
else{
for (qint32 i = 0; i < numItems; i++){
itemDescriptions << QString::number(i);
}
}
// The font to be used
QFont textFont("Mono");
textFont.setPixelSize(10);
//QFont titleFont("Mono",16,QFont::Bold);
// Calculating margins to get the effective graph area.
qreal XAxisLength = (1.0 - LEFT_MARGIN - RIGHT_MARGIN)*W;
qreal DW = XAxisLength/(qreal)(numItems);
// Calculating the effective graph area due to the text items.
qreal Th = 0.1*H;
qreal GH = (1.0-TOP_MARGIN)*H - Th;
qreal xOffset = LEFT_MARGIN*W;
qreal yOffset = TOP_MARGIN*H;
// --------------- Commence drawing -----------------------
QPainter painter(&graph);
// The background
painter.setBrush(QBrush(QColor(226,226,226)));
painter.drawRect(0,0,W,H);
// Drawing the axis;
QPen pen;
pen.setColor(QColor(0,0,0));
pen.setWidth(2);
painter.setPen(pen);
painter.setBrush(QBrush(Qt::black));
painter.drawLine(xOffset,yOffset+GH,xOffset + XAxisLength,yOffset+GH);
painter.drawLine(xOffset,yOffset,xOffset,yOffset+GH);
// Drawing the X Axis text
painter.setFont(textFont);
for (qint32 i = 0; i < numItems; i++){
QRectF rectF(xOffset + i*DW,yOffset+GH,DW,Th);
painter.drawText(rectF,itemDescriptions.at(i));
}
return graph;
}

Taking screenshot of view/layout programmatically in BlackBerry10

is it possible to take a screenshot of a container like DockLayout and all of its children programmatically in BB10 (native)? I've found the Screenshot class in the docs, but it's only possible to take a display or app window screenshot...
Any tips or hints?
Thanks.
This is the basic code I use for capturing an area of the screen under program control.
Note that you can only capture a screen displayed by the program this code is in.
void ScreenCapture::capture(qreal x, qreal y, qreal width, qreal height)
{
smDebug(1) << "Capturing" << x << y << width << height;
screen_pixmap_t screen_pix;
screen_buffer_t screenshot_buf;
screen_context_t context;
char *screenshot_ptr = NULL;
int screenshot_stride = 0;
int usage, format;
int size[2];
screen_create_context(&context, 0);
screen_create_pixmap(&screen_pix, context);
usage = SCREEN_USAGE_READ | SCREEN_USAGE_NATIVE;
screen_set_pixmap_property_iv(screen_pix, SCREEN_PROPERTY_USAGE, &usage);
format = SCREEN_FORMAT_RGBA8888;
screen_set_pixmap_property_iv(screen_pix, SCREEN_PROPERTY_FORMAT, &format);
size[0] = 0;
size[1] = 0;
screen_get_window_property_iv(Application::instance()->mainWindow()->handle(), SCREEN_PROPERTY_SIZE, size);
smDebug(1) << size[0] << 'x' << size[1];
screen_set_pixmap_property_iv(screen_pix, SCREEN_PROPERTY_BUFFER_SIZE, size);
screen_create_pixmap_buffer(screen_pix);
screen_get_pixmap_property_pv(screen_pix, SCREEN_PROPERTY_RENDER_BUFFERS,
(void**)&screenshot_buf);
screen_get_buffer_property_pv(screenshot_buf, SCREEN_PROPERTY_POINTER,
(void**)&screenshot_ptr);
screen_get_buffer_property_iv(screenshot_buf, SCREEN_PROPERTY_STRIDE,
&screenshot_stride);
screen_read_window(Application::instance()->mainWindow()->handle(), screenshot_buf, 0, NULL ,0);
QByteArray array;
int nbytes = size[0] * size[1] * 4;
write_bitmap_header(nbytes, array, size);
for (int i = 0; i < size[1]; i++)
{
array.append(screenshot_ptr + i * screenshot_stride, size[0] * 4);
}
QImage image = QImage::fromData(array, "BMP");
image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
baseImage = QImage(width,height,QImage::Format_ARGB32_Premultiplied);
baseImage.painter().drawImage(0, 0, image, x, y, width, height);
if (mWaterMarkImage != NULL)
baseImage.updateToView(mWaterMarkImage);
soundplayer_play_sound("event_camera_shutter");
screen_destroy_pixmap(screen_pix);
smDebug(1) << "capture done.";
}

Why can't I get the text out of a QTableWidget cell?

I have searched the answer, and ui->tableWidget->item( row, col )->text(); seems to be the answer.
Now, in my code I have:
ui-> tableWidget->setItem(row-1, 1, new QTableWidgetItem("clicked"));
This works just fine. When the cell is clicked, it displays the "clicked" message. BUT, when i add this below:
QString str;
QTableWidgetItem * itm = ui->tableWidget->item( 3, 1 );
str = itm->text();
The program crashes.
Any idea how could I view the text from the cell?
All the code.Constructor:
{
ui->setupUi(this);
QDate date = QDate::currentDate();
QString dateString = date.toString();
QFont myFont;
QFontMetrics font_meter(myFont);
int line_width=0;
ui->label->setText(dateString);
QFile file(":/input.txt");
if(!file.open(QIODevice::ReadOnly))
{
QMessageBox::information(0,"info",file.errorString());
}
QTextStream in(&file);
QStringList headerLabels;
QStringList rowLabels;
QStringList rowContents;
headerLabels << "Tasks to do" ;
int row_count=0;
while (true)
{
QString line = in.readLine();
if (line.isNull())
{
file.close();
break;
}
else
{
row_count++;
rowLabels.append(QString("%1").arg(row_count));
rowContents.append(line);
if( font_meter.width(line)>line_width)
{
line_width=font_meter.width(line);
}
}
}
ui->tableWidget->setRowCount(row_count);
ui->tableWidget->setVerticalHeaderLabels(rowLabels);
ui->tableWidget->setColumnCount(1);
// ui->tableWidget->setCellWidget();
for(int i=0;i<row_count;i++)
{
ui-> tableWidget->setItem(i-1, 1, new QTableWidgetItem(rowContents.at(i)));
}
}
slot:
void MainWindow::on_tableWidget_cellDoubleClicked(int row, int column)
{
ui->pushButton->setText( QString("%1").arg(row));
ui-> tableWidget->setItem(row-1, 1, new QTableWidgetItem("clicked"));
QString str;
QTableWidgetItem * itm = ui->tableWidget->item( 3, 1 );
str = itm->text();
}
I have tried to make another program.Just with a simple table and getting the text out of a cell:
ui->setupUi(this);
ui->tableWidget->setItem(1,1,new QTableWidgetItem("lol"));
QString str= ui->tableWidget->item(1,1)->text();
.Exactly the same error
ui->setupUi(this);
ui->tableWidget->setRowCount(1);
ui->tableWidget->setColumnCount(1);
ui->tableWidget->setItem(0, 0, new QTableWidgetItem("Hello World!"));
QTableWidgetItem *temp = ui->tableWidget->item(0, 0);
QString str = temp->text();
Works for me, I only managed to crash the program when rowCount or columntCount were 0.

QNetworkAccessManager not emitting finished signal with this code

so i have been browsing the previous questions before about this issue, but i could not find a solution for my code.
cpp file of dialog
------------------------------------------------
#include "everesult.h"
#include "ui_everesult.h"
everesult::everesult(QWidget *parent) :
QDialog(parent),
ui1(new Ui::everesult)
{
ui1->setupUi(this);
}
everesult::~everesult()
{
delete ui1;
}
void everesult::setmodel(QStandardItemModel *model)
{
ui1->listView->setModel(model);
}
void everesult::on_buttonBox_clicked(QAbstractButton *button)
{
EveReprocess M_;
QModelIndex Selectedindex = ui1->listView->currentIndex();
QModelIndex StationIdsindex = ui1->listView->model()->index(0, 1);
int typeID = 0;
int stationID = 0;
stationID = ui1->listView->model()->data(StationIdsindex, Qt::DisplayRole).toInt();
typeID = ui1->listView->model()->data(Selectedindex, Qt::DisplayRole).toInt();
M_.GetMaterials(typeID, stationID);
}
--------------------------------------------------
Getmaterial and replyFinished from main window.
--------------------------------------------------
void EveReprocess::GetMaterials(int typeId, int stationid)
{
//get typeid from material list
this->modelMaterial = new QSqlQueryModel();
modelMaterial->setQuery(QString("SELECT tm.quantity, tm.materialTypeID, t.typeName FROM invTypeMaterials tm INNER JOIN invTypes t ON t.TypeID = tm.materialTypeId WHERE tm.TypeID=%1 ").arg(typeId));
if (!modelMaterial->query().exec())
qDebug() << modelMaterial->query().lastError();
//Set eve Central Url with typeids
QUrl url = QUrl("http://api.eve-central.com/api/marketstat?");
QUrlQuery q;
int numRows = modelMaterial->rowCount();
for (int row = 0; row < numRows; ++row)
{
QModelIndex index = modelMaterial->index(row, 1);
q.addQueryItem( QString("typeid"), QString::number(modelMaterial->data(index, Qt::DisplayRole).toInt()));
}
q.addQueryItem( QString("usesystem"), QString::number(stationid));
//set created url and connect
url.setQuery(q);
qDebug() << url;
manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply *)));
manager->get(QNetworkRequest(url) );
}
void EveReprocess::replyFinished(QNetworkReply *reply)
{
qDebug() << "replyFinished called";
if ( reply->error() != QNetworkReply::NoError ) {
qDebug() << "Request failed, " << reply->errorString();
emit replyFinished(false);
return;
}
qDebug() << "Request succeeded";
//process with xmlreader and get values
processSearchResult( reply);
}
some of the code is here, i think it should be somewhere here, as the rest works fine.
this issue showed up after i use a dialog to let user pick a int from a list.
below is the function that calls the dialog that i have made for this. sorry about code format wil clean it up after it is working
void EveReprocess::Search_TypeId(QString ItemName, QString SystemName)
{
QList<int> TypeIdList;
QList<int> StationIdList;
modelIds = new QStandardItemModel(10,2,this);
if !(db.isOpen()) return;
this->queryItem = new QSqlQuery;
queryItem->prepare("SELECT typeID FROM invTypes WHERE invTypes.typeName LIKE ? AND invTypes.groupID NOT IN (268,269,270)AND published= 1");
ItemName.prepend("%");
ItemName.append("%");
queryItem->bindValue(0, ItemName);
this->queryStation = new QSqlQuery;
queryStation->prepare("SELECT solarSystemID FROM mapSolarSystems WHERE mapSolarSystems.solarSystemName LIKE ?");
SystemName.prepend("%");
SystemName.append("%");
queryStation->bindValue(0, SystemName);
if(!queryStation->exec() || !queryItem->exec() )
{
qDebug() << queryItem->lastError().text();
qDebug() << queryItem->lastQuery();
qDebug() << queryStation->lastError().text();
qDebug() << queryStation->lastQuery();
}
while( queryStation->next())
{
StationIdList.append(queryStation->value(0).toInt());
}
while(queryItem->next())
{
TypeIdList.append(queryItem->value(0).toInt());
}
for (int i = 0; i < StationIdList.count(); ++i)
{
modelIds->setItem(i,1,new QStandardItem(QString::number(StationIdList.at(i))));
}
for (int i = 0; i < TypeIdList.count(); ++i)
{
modelIds->setItem(i,0,new QStandardItem(QString::number(TypeIdList.at(i))));
}
//
everesult Dialog;
Dialog.setmodel(modelIds);
Dialog.exec();
}
Before you proceed any further, some of your code is allows SQL injections. Even when it's not a security hole, it'll still lead to bugs. Instead of using string substitution in SQL queries, you should be using bindings.
Your problem is here:
everesult Dialog;
Dialog.setmodel(modelIds);
Dialog.exec();
The exec() is a blocking function - it blocks the main event loop until the dialog is dismissed. Thus the signals from the threaded network access manager never get delivered to your objects.
You should display the dialog box asynchronously, like so:
everesult * dialog = new everesult;
dialog->setModel(modelIds);
dialog->show();
connect(dialog, SIGNAL(accepted()), dialog, SLOT(deleteLater());
connect(dialog, SIGNAL(rejected()), dialog, SLOT(deleteLater());
Note that it's misleading to have type names starting with lower case and variable names starting with upper case. Qt's convention is the opposite, and it's useful to retain it unless you have a good reason to do otherwise.
DO Parameter Binding in SQL Queries
QSqlQuery query("SELECT .. WHERE tm.TypeID=:typeid");
query.bindValue(":typeid", typeId);
QSqlQueryModel model;
model.setQuery(query);
DON'T DO String Substitution in SQL Queries
setQuery(QString("SELECT ... WHERE tm.TypeID=%1 ").arg(typeId));

Passing QRadioButton value from one window to another window in Qt (no matching function for call to)

I want to pass selected QRadioButton's value from one Window to another. I am confused with the function declaration to accept the text value in Second Window, here is my code.
Window1.cpp
void SelectOS :: processNextButton(){
if(ui->win32->isChecked()){
QString loc = "WIN/32Bit";
SelectSoftware *ss = new SelectSoftware (loc);
this->hide();
ss->show();
}
else
{
//QMessageBox:warning();
}
}
Window2.h
public:
SelectSoftware(const QString &text, QWidget *parent=0);
Window2.cpp
SelectSoftware::SelectSoftware(const QString &text, QWidget *parent):QMainWindow(parent),ui(new ui::SelectSoftware)
{
QString softpath = text;
qDebug << softpath;
}
But when I call
ss = new SelectSoftware();
or
ss= new SelectSoftware(const QString &text, QWidget *parent);
in Window2.cpp, I get the error : no matching function for call to SelectSoftware::SelectSoftware()
Where am I wrong?
UPDATE
Window2.cpp
#include "selectsoftware.h"
#include "ui_selectsoftware.h"
SelectSoftware *ss;
QStringList selectedModuleList;
SelectSoftware::SelectSoftware(const QString &text, QWidget *parent) :
QMainWindow(parent),
ui(new Ui::SelectSoftware)
{
ui->setupUi(this);
softpath = text;
setWindowPosition();
getSoftwareDetails();
initializeUi();
}
SelectSoftware::~SelectSoftware()
{
delete ui;
}
void SelectSoftware::setWindowPosition()
{
QDesktopWidget *desktop = QApplication::desktop();
int x = (desktop->width() - size().width())/2;
int y = (desktop->height() - size().height())/2;
move(x, y-50);
setFixedSize(size().width(), size().height());
}
void SelectSoftware::cancel()
{
qApp->exit(0);
}
void SelectSoftware::showMainPage()
{
ss = new SelectSoftware(softpath); // here its creating problem, not going forward and app is crashing!!!
for(int j = 0; j < softwareList.size(); j++){
if(checkBox[j]->isChecked()){
if(!comboBox[j]->currentIndex()){
QMessageBox::warning(this, "Select version !", "Select version number for all selected software");
return;
}
}
}
for(int i = 0; i < softwareList.size(); i++){
if(checkBox[i]->isChecked()){
ss->selectedSoftList.push_back(checkBox[i]->text());
ss->selectedVerList.push_back(comboBox[i]->currentText());
}
}
if(!ss->selectedSoftList.size()){
QMessageBox::warning(this, "No product Selected !", "Select one");
return;
}
else{
SelectionPage* sp = new SelectionPage;
this->hide();
sp->show();
}
}
void SelectSoftware::test(const int id)
{
if(checkBox[id]->isChecked()){
comboBox[id]->setEnabled(true);
comboBox[id]->addItem(" Select anyone ");
QString path = qApp->applicationDirPath() + "/products/" + checkBox[id]->text();
QDir dir;
dir.cd(path);
dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
QFileInfoList list = dir.entryInfoList();
for (int i = 0; i < list.size(); ++i) {
QFileInfo fileInfo = list.at(i);
comboBox[id]->addItem(fileInfo.fileName());
}
}else{
comboBox[id]->clear();
comboBox[id]->setDisabled(true);
}
}
void SelectSoftware::getSoftwareDetails()
{
QString fileName = qApp->applicationDirPath() + "/abc/" + SOFTWARELIST;
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){
QString msg = "Could not find the file " + fileName;
errorExit(msg);
}
QTextStream in(&file);
while (!in.atEnd()) {
QString line = in.readLine();
processLine(line.toLower());
}
}
void SelectSoftware::processLine(QString str)
{
QStringList list = str.split(",");
QDir path = qApp->applicationDirPath() + "/products/" + list[0];
if(path.exists() && (list.size() == 2)){
QString tmp = list[0];
tmp = tmp.toLower();
softwareList.push_back(tmp);
}
}
void SelectOption::initializeUi()
{
this->setWindowTitle("Window2");
QGridLayout *gridLayout1 = new QGridLayout();
gridLayout1->setMargin(5);
gridLayout1->setSpacing(5);
QSignalMapper* signalMapper = new QSignalMapper();
for(int i = 0; i < list.size(); i++){
radioButton[i] = new QRadioButton();
radioButton[i]->setText(softwareList[i]);
signalMapper->setMapping(radioButton[i], i);
gridLayout1->addWidget(radioButton[i], i/1, i%1);
connect(radioButton[i], SIGNAL(clicked()),signalMapper, SLOT(map()));
}
connect(signalMapper, SIGNAL(mapped(const int &)),this, SIGNAL(radioChecked(const int &)));
connect(this, SIGNAL(radioChecked(const int &)),this, SLOT(test(const int)));
QGridLayout *gridLayout2 = new QGridLayout();
gridLayout2->setMargin(5);
gridLayout2->setSpacing(5);
for(int j = 0; j < list.size(); j++){
comboBox[j] = new QComboBox();
comboBox[j]->setDisabled(true);
gridLayout2->addWidget(comboBox[j], j/1, j%1);
}
QPushButton *nextButton = new QPushButton("Next >");
nextButton->setDefault(true);
connect(nextButton, SIGNAL(clicked()), this, SLOT(showMainPage()));
QPushButton *backButton = new QPushButton("< Back");
backButton->setDefault(true);
connect(backButton, SIGNAL(clicked()), this, SLOT(showSelectOS()));
QPushButton *cancelButton = new QPushButton("Cancel");
cancelButton->setDefault(true);
connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancel()));
QHBoxLayout *hboxlayout;
hboxlayout = new QHBoxLayout();
hboxlayout->addLayout(gridLayout1);
hboxlayout->addLayout(gridLayout2);
QHBoxLayout *layout;
layout = new QHBoxLayout();
layout->addStretch(10);
layout->addWidget(nextButton);
layout->addWidget(backButton);
layout->addWidget(cancelButton);
layout->addStretch(10);
QVBoxLayout *mainLayout;
mainLayout = new QVBoxLayout();
mainLayout->addLayout(hboxlayout);
mainLayout->addLayout(layout);
ui->centralwidget->setLayout(mainLayout);
}
QVector<QString> SelectSoftware::getSelectedSoftware()
{
return ss->selectedSoftList;
}
QVector<QString> SelectSoftware::getSelectedVersion()
{
return ss->selectedVerList;
}
QStringList SelectSoftware::getSelectedModules()
{
return selectedModuleList;
}
First of all - use signals and slots, Luke
Second of all, you cannot call ss = new SelectSoftware();, since you haven't declared SelectSoftware constructor without parameters, and calling ss= new SelectSoftware(const QString &text, QWidget *parent); is illegal in C++.
SelectSoftware *ss = new SelectSoftware (loc); is correct, though.
1. In void SelectSoftware::processLine(QString str) addressing to list[0] without checking that list is not empty might be dangerous. I recomend you to add:
if (!list.size())
return;
right after initialization.
2. In void SelectOption::initializeUi() what is list? Are you sure list.size() <= softwareList.size()? If not, it's a potential problem.
3. What is radioButton? I don't see it's initialization. If it is QList < QRadioButton * >, than radioButton[i] = new QRadioButton(); is a bad one and you should do this:
radioButton.append(new QRadioButton());
4. Same goes to comboBox.
Each of the list can cause the crash of your application. And I could easily miss something.

Resources