How to create an object in C++/Qt? - c++

void MainWindow::on_actionformattedActivity_triggered()
{
// todo: Button=> file reading
Activity* act = new Activity("name",0,1,40,20,true,actNum);
qDebug() << "actNum" <<actNum;
activities.append(*act) ;
qDebug()<< "list element";
foreach (Activity a, activities) {
//qDebug() << a.actListWidgetItem->text();
qDebug() << a.actIsVisible;
qDebug() << a.actID;
}
qDebug()<< "list size";
qDebug()<<activities.size();
//timeline->AddTimeLineElement(act->ActStartingPoint() , act->ActRect(), penBlack, brushBlue);
// ui->listWidgetActivities->addItem(act->actListWidgetItem);
actNum++;
}
Activity Constructor
Activity::Activity(QString name, int err, int war,int startTime,int length, bool isVisible,int numberID)
{
// QListWidgetItem* actListItemWidget = new QListWidgetItem();
// actListItemWidget->setText(name + "___" + QString::number(err) + "___" + QString::number(war));
//QPointF* actStartingPoint = new QPointF((numberID -1) * rectHeight, startTime );
//QRect* actRect = new QRect (0,0,length,rectHeight);
bool actIsVisible = isVisible;
int actID = numberID;
}
I want to create an object from the class Activities which contains a bunch of data I need to display. whenever I click the button that call this function the system crashes. I decided to check the content of the
QList activities
the output show the correct actNum and List size but random values...
actNum 0
list element
true
0
list size
1
actNum 1
list element
true
0
true
0
list size
2
How can I create and access an object from Activity class?

Related

'std::bad_alloc' when trying to delete priority_queue elements C++

When returning a ship to the port, speed becomes 0.0 and user inputs shield and fuel.
–If fuel is 0.0, the ship gets destroyed
–Ships still in the priority_queue take 10 shield damage and lose 15 fuel
–If shield or fuel become less than 0.0, the ship gets destroyed
Trying to implement these instructions for my final project. The ships are pointer types and they are in a priority queue named 'battlefield'. The ships also exist in a list of pointers called 'port'. I'm trying to destroy the ships that receive lethal damage but when I try to show them, the Qt program crashes and I get bad_alloc error. This is the last thing I have to do for my project :(
Important code blocks from various files:
I already tried to delete the ships from the port, also tried directly deleting them from the port but the priority_queue gets messed up.
class Civilization {
string name;
int x;
int y;
list<Villager> villagers;
list<Ship*> port;
priority_queue<Ship*, vector<Ship*>, Ship::comp> battle;
}
void Civilization::damageShips()
{
priority_queue<Ship*, vector<Ship*>, Ship::comp> copy = battle;
Ship *s = battle.top();
s->setSpeed(0.0);
while(!copy.empty()) {
Ship *s = copy.top();
s->setShield(s->getShield() - 10);
s->setFuel(s->getFuel() - 15);
copy.pop();
}
priority_queue<Ship*, vector<Ship*>, Ship::comp> temp;
while(!copy.empty()) {
Ship *s = copy.top();
string id = s->getId();
if (s->getShield() > 0 && s->getFuel() > 0) {
temp.push(s);
} else
deleteShip(id);
copy.pop();
}
battle = temp;
battle.pop();
}
void battlefielddisplay::setCivilization(Civilization *civilizaition)
{
size_t size = civilizaition->battlefieldSize();
ui->battlefield_table->setRowCount(int(size));
Civilization &c = *civilizaition;
priority_queue<Ship*, vector<Ship*>, Ship::comp> copy = c.getBattlefield();
int cnt = 0;
while(!copy.empty()) {
Ship *s = copy.top();
QString id = QString::fromStdString(s->getId());
QString fuel = QString::number(s->getFuel());
QString speed = QString::number(s->getSpeed());
QString shield = QString::number(s->getShield());
QString warriors = QString::number(s->size());
QTableWidgetItem *idItem = new QTableWidgetItem(id);
QTableWidgetItem *fuelItem = new QTableWidgetItem(fuel);
QTableWidgetItem *speedItem = new QTableWidgetItem(speed);
QTableWidgetItem *shieldItem = new QTableWidgetItem(shield);
QTableWidgetItem *warriorsItem = new QTableWidgetItem(warriors);
ui->battlefield_table->setItem(cnt, 0, idItem);
ui->battlefield_table->setItem(cnt, 1, fuelItem);
ui->battlefield_table->setItem(cnt, 2, speedItem);
ui->battlefield_table->setItem(cnt, 3, shieldItem);
ui->battlefield_table->setItem(cnt, 4, warriorsItem);
cnt++;
copy.pop();
}
}
void MainWindow::on_battle_remove_ship_clicked()
{
if (flag) {
Civilization* c = videogame.searchCivilization(ui->civilization_search_input->text().toStdString());
double shield = ui->shield_battle_remove->value();
double fuel = ui->fuel_battle_remove->value();
Ship *s = c->getBattleShip();
s->setSpeed(0.0);
s->setShield(shield);
s->setFuel(fuel);
c->damageShips();
qDebug() << "[✔]" << "Removed ship from battlefield";
} else
QMessageBox::information(this, "Error", "Civilization not found");
}
bool Civilization::deleteShip(string &id)
{
bool found = false;
for(size_t i(0); i < shipSize(); ++i) {
auto it = port.begin();
advance(it, i);
auto x = *it;
if (x->getId() == id) {
port.erase(it);
delete x;
--i;
found = true;
}
}
return found;
}
The main problem I see is that you delete the objects without removing the pointers from the container. You are iterating the same container multiple times and trying to access the deleted objects.
An additional problem is that you have multiple copies of the same queue so even removing the pointer from the main container may cause problems.
Try to reconsider the algorithm paying special attention to the life time of the objects. For example you may have a lazy deletion: instead of deleting just mark the objects as those that shall be deleted later. You may have a cleanup at the end of your function.

Can't get a value from LMDB

I'm trying to store and fetch some data from LMDB. Data seems to be stored, I can see the keys in my database, but it gives me MDB_NOTFOUND when I try to fetch the value with the same ID I have just stored it under.
Database opening
MDB_env* environment;
MDB_dbi main;
MDB_dbi order;
mdb_env_create(&environment);
mdb_env_set_maxdbs(environment, 2);
mdb_env_open(environment, path.toStdString().c_str(), 0, 0664);
int rc;
MDB_txn *txn;
mdb_txn_begin(environment, NULL, 0, &txn);
mdb_dbi_open(txn, "main", MDB_CREATE, &main);
mdb_dbi_open(txn, "order", MDB_CREATE | MDB_INTEGERKEY, &order);
mdb_txn_commit(txn);
Insertion
void Core::Archive::addElement(const Shared::Message& message) {
QByteArray ba;
QDataStream ds(&ba, QIODevice::WriteOnly);
message.serialize(ds);
uint64_t stamp = message.getTime().toMSecsSinceEpoch();
const std::string& id = message.getId().toStdString();
MDB_val lmdbKey, lmdbData;
lmdbKey.mv_size = id.size();
lmdbKey.mv_data = (uint8_t*)id.c_str();
lmdbData.mv_size = ba.size();
lmdbData.mv_data = (uint8_t*)ba.data();
MDB_txn *txn;
mdb_txn_begin(environment, NULL, 0, &txn);
int rc;
rc = mdb_put(txn, main, &lmdbKey, &lmdbData, 0);
if (rc == 0) {
MDB_val orderKey;
orderKey.mv_size = 8;
orderKey.mv_data = (uint8_t*) &stamp;
rc = mdb_put(txn, order, &orderKey, &lmdbKey, 0);
if (rc) {
mdb_txn_abort(txn);
} else {
rc = mdb_txn_commit(txn);
if (rc) {
qDebug() << "A transaction error: " << mdb_strerror(rc);
}
}
} else {
qDebug() << "An element couldn't been added to the archive, skipping" << mdb_strerror(rc);
mdb_txn_abort(txn);
}
}
Fetching
Shared::Message Core::Archive::getElement(const QString& id) {
MDB_val lmdbKey, lmdbData;
lmdbKey.mv_size = id.toStdString().size();
lmdbKey.mv_data = (uint8_t*)id.toStdString().c_str();
MDB_txn *txn;
int rc;
mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn);
rc = mdb_get(txn, main, &lmdbKey, &lmdbData);
if (rc) {
qDebug() <<"Get error: " << mdb_strerror(rc);
mdb_txn_abort(txn);
throw NotFound(id.toStdString(), jid.toStdString());
} else {
//it never comes here
}
}
Testing code
Core::Archive ar();
ar.open("Test");
Shared::Message msg1;
msg1.generateRandomId();
msg1.setBody("oldest");
msg1.setTime(QDateTime::currentDateTime().addDays(-7));
Shared::Message msg2;
msg2.generateRandomId();
msg2.setBody("Middle");
msg2.setTime(QDateTime::currentDateTime().addDays(-4));
Shared::Message msg3;
msg3.generateRandomId();
msg3.setBody("newest");
msg3.setTime(QDateTime::currentDateTime());
ar.addElement(msg2);
ar.addElement(msg3);
ar.addElement(msg1);
Shared::Message d0 = ar.getElement(msg1.getId());
My logs show stored keys. I can see the required key, I can even compare it with the requested key if I use cursors to scroll over the whole storage, it even shows they are equal, but mdb_cursor_get or mdb_get constantly give me MDB_NOTFOUND. What am I doing wrong?
I got it. No matter what I put into database, I have to read it as a char*
Had to modify fetching code
lmdbKey.mv_data = (uint8_t*)id.toStdString().c_str();
I had to change it to
lmdbKey.mv_data = (char*)id.toStdString().c_str();
and it worked

How can I get the result of a request after executing the request using c++ builder XE6 and Firebird?

After connecting to a Firebird database with C++ builder, I cannot get a result from a simple select request.
I have some confusion about a lot of members of classes:
void __fastcall TForm2::btn1Click(TObject *Sender)
{ TSQLConnection co = new TSQLConnection(this);
Base_Firebird *fb = new Base_Firebird() ;
bool bl = fb->Connecter(co);
String sqlstring = "select nom_action from T_ACTION where CLE_ACTION=6 ";
if (bl)
TSQLQuery *req = new TSQLQuery(NULL) ;
req->SQLConnection = co ;
req->SQL->Add(sqlstring);
req->Open() ;
}
My problem is here after opening the TSQLQuery, I don't know how I can get the result and execute the command.
Try changing the end of your subroutine to something like this:
if (bl)
{ /// you forgot compound operator here !!!!!
TSQLQuery *req = new TSQLQuery(this) ;
req->SQLConnection = co ;
req->SQL->Text = sqlstring;
req->Open() ;
int j = 0;
while( !req->EOF() )
{
++j;
String Value = req->Fields[0]->AsString;
ShowMessageFmt( "Row %d ==> Value: %s ", ARRAYOFCONST(( j, Value )) );
// String MSG = Format( "Row %d ==> Value: %s ", ARRAYOFCONST(( j, Value )) );
// ShowMessage( MSG );
req -> Next();
};
req->Close();
ShowMessage("Data over.");
}
req -> Free(); // maybe "delete req;" would work too, dunno
}
To check:
http://docwiki.embarcadero.com/Libraries/Seattle/en/Vcl.Dialogs.ShowMessageFmt
http://docwiki.embarcadero.com/Libraries/Seattle/en/System.SysUtils.Format
https://osdn.net/projects/cc1101driver/scm/svn/blobs/head/trunk/VC_test/Cpp_builder_2009/Cpp_Builder_test/documents/JVC_20120502/jvcl/examples/JvProgressDialog/BCB/JvProgressDialogMain.cpp
http://www.texttransformer.com/d2chelp/cbuilderarrayofconst.htm
http://docwiki.embarcadero.com/RADStudio/Seattle/en/Open_Arrays#C.2B.2B_functions_that_take_open_array_arguments
http://docwiki.embarcadero.com/RADStudio/Seattle/en/Support_for_Object_Pascal_Data_Types_and_Language_Concepts
Read Embarcadero's documentation. There are whole chapters on how to work the SQL components you are using, including:
How To Perform Database Procedures
Navigating Datasets
Using dbExpress
Using dbExpress Components Index
Using TSQLQuery
Data.SqlExpr.TSQLQuery
For example:
void __fastcall TForm2::btn1Click(TObject *Sender)
{
TSQLConnection *co = new TSQLConnection(NULL);
Base_Firebird *fb = new Base_Firebird();
if (fb->Connecter(co))
{
TSQLQuery *req = new TSQLQuery(NULL);
req->SQLConnection = co;
req->SQL->Text = "select nom_action from T_ACTION where CLE_ACTION=6";
req->Open();
while (!req->Eof)
{
// use req->Fields as needed...
req->Next();
}
delete req;
}
delete fb;
delete co;
}

calculate the message delivery ratio

I am trying to calculate the message delivery ratio using TraCIDemo.
In sendBeacon I am incrementing messageDeliverySend every time I send a message and in processBeacon I increment the messageDeliveryReceive parameter based on the sending node.
In processBeacon I do a string compare with node[0], but I want to check this parameter dynamically. How do I do the dynamic check part for this code?
My scenario will be if there are multiple nodes transmitting to node[1] for example I want to record values only from node[0].
void ROAMER::sendBeacon(ROAMERBeacon * beacon, double delay) {
ROAMER_EV << "Sending beacon: address = " << beacon->getAddress()
<< ", position = " << beacon->getPosition() << endl;
IPv4ControlInfo * networkProtocolControlInfo = new IPv4ControlInfo();
networkProtocolControlInfo->setProtocol(IP_PROT_MANET);
networkProtocolControlInfo->setTimeToLive(255);
networkProtocolControlInfo->setDestAddr(IPv4Address::LL_MANET_ROUTERS);
networkProtocolControlInfo->setSrcAddr(getSelfAddress().get4());
messageDeliverySend++;
delayTime = simTime();
UDPPacket * udpPacket = new UDPPacket(beacon->getName());
udpPacket->encapsulate(beacon);
udpPacket->setSourcePort(ROAMER_UDP_PORT);
udpPacket->setDestinationPort(ROAMER_UDP_PORT);
udpPacket->setControlInfo(networkProtocolControlInfo);
sendUDPPacket(udpPacket, delay);
}
void ROAMER::processBeacon(ROAMERBeacon * beacon) {
if(strcmp(beacon->getSenderAddress(),"node[0]") == 0){
messageDeliveryReceive++;
}
}
void ROAMER::finish(){
messageDeliveryRatio = messageDeliveryReceive/messageDeliverySend;
recordScalar("Message Delivery Ratio",messageDeliveryVecRatio);
}

Open XML Excel Cell Formatting

I am trying to export to excel using Open XML with simple formatting. Export to Excel is working. The problem is with formatting the data. I am trying to have very basic formatting. i.e. the Column names should be in bold and rest of the content in normal font. This is what I did. Please let me know where am I going wrong.
private Stylesheet GenerateStyleSheet()
{
return new Stylesheet(
new Fonts(
new Font(new DocumentFormat.OpenXml.Spreadsheet.FontSize { Val = 12},
new Bold(),
new Font(new DocumentFormat.OpenXml.Spreadsheet.FontSize { Val = 12}))
)
);
}
protected void ExportExcel(DataTable dtExport)
{
Response.ClearHeaders();
Response.ClearContent();
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";
//"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" '"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" '"application/vnd.ms-excel"
Response.AddHeader("content-disposition", "attachment; filename=Test.xlsx");
Response.Charset = "";
this.EnableViewState = false;
MemoryStream ms = new MemoryStream();
SpreadsheetDocument objSpreadsheet = SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook);
WorkbookPart objWorkbookPart = objSpreadsheet.AddWorkbookPart();
objWorkbookPart.Workbook = new Workbook();
WorksheetPart objSheetPart = objWorkbookPart.AddNewPart<WorksheetPart>();
objSheetPart.Worksheet = new Worksheet(new SheetData());
Sheets objSheets = objSpreadsheet.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
Sheet objSheet = new Sheet();
objSheet.Id = objSpreadsheet.WorkbookPart.GetIdOfPart(objSheetPart);
objSheet.SheetId = 1;
objSheet.Name = "mySheet";
objSheets.Append(objSheet);
WorkbookStylesPart stylesPart = objSpreadsheet.WorkbookPart.AddNewPart<WorkbookStylesPart>();
stylesPart.Stylesheet = GenerateStyleSheet();
stylesPart.Stylesheet.Save();
objSheetPart.Worksheet.Save();
objSpreadsheet.WorkbookPart.Workbook.Save();
for (int cols = 0; cols < dtExport.Columns.Count; cols++)
{
Cell objCell = InsertCellInWorksheet(GetColumnName(cols), 1, objSheetPart);
objCell.CellValue = new CellValue(dtExport.Columns[cols].ColumnName);
objCell.DataType = new EnumValue<CellValues>(CellValues.String);
objCell.StyleIndex = 0;
}
objSheetPart.Worksheet.Save();
objSpreadsheet.WorkbookPart.Workbook.Save();
for (uint row = 0; row < dtExport.Rows.Count; row++)
{
for (int cols = 0; cols < dtExport.Columns.Count; cols++)
{
//row + 2 as we need to start adding data from second row. First row is left for header
Cell objCell = InsertCellInWorksheet(GetColumnName(cols), row + 2, objSheetPart);
objCell.CellValue = new CellValue(Convert.ToString(dtExport.Rows[Convert.ToInt32(row)][cols]));
objCell.DataType = new EnumValue<CellValues>(CellValues.String);
objCell.StyleIndex = 1;
}
}
objSheetPart.Worksheet.Save();
objSpreadsheet.WorkbookPart.Workbook.Save();
objSpreadsheet.Close();
ms.WriteTo(Response.OutputStream);
Response.Flush();
Response.End();
}
// Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet.
// If the cell already exists, return it.
private Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart)
{
Worksheet worksheet = worksheetPart.Worksheet;
SheetData sheetData = worksheet.GetFirstChild<SheetData>();
string cellReference = (columnName + rowIndex.ToString());
// If the worksheet does not contain a row with the specified row index, insert one.
Row row = default(Row);
if ((sheetData.Elements<Row>().Where(r => r.RowIndex.Value == rowIndex).Count() != 0))
{
row = sheetData.Elements<Row>().Where(r => r.RowIndex.Value == rowIndex).First();
}
else
{
row = new Row();
row.RowIndex = rowIndex;
sheetData.Append(row);
}
// If there is not a cell with the specified column name, insert one.
if ((row.Elements<Cell>().Where(c => c.CellReference.Value == columnName + rowIndex.ToString()).Count() > 0))
{
return row.Elements<Cell>().Where(c => c.CellReference.Value == cellReference).First();
}
else
{
// Cells must be in sequential order according to CellReference. Determine where to insert the new cell.
Cell refCell = null;
foreach (Cell cell in row.Elements<Cell>())
{
if ((string.Compare(cell.CellReference.Value, cellReference, true) > 0))
{
refCell = cell;
break; // TODO: might not be correct. Was : Exit For
}
}
Cell newCell = new Cell();
newCell.CellReference = cellReference;
row.InsertBefore(newCell, refCell);
return newCell;
}
}
It seems like you are missing a ")" after your first font creation. So then you end opp with only one font index (the default one)
Below is the code I use for exactly what you are asking for.
You might remove fills and borders and remove them from cellformat, but I had some syntax problems while writing this so I just left it when it all worked :-)
private Stylesheet GenerateStyleSheet()
{
return new Stylesheet(
new Fonts(
// Index 0 - Default font.
new Font(
new FontSize() { Val = 11 },
new Color() { Rgb = new HexBinaryValue() { Value = "000000" } }
),
new Font(
new Bold(),
new FontSize() { Val = 11 },
new Color() { Rgb = new HexBinaryValue() { Value = "000000" } }
)
),
new Fills(
// Index 0 - Default fill.
new Fill(
new PatternFill() { PatternType = PatternValues.None })
),
new Borders(
// Index 0 - Default border.
new Border(
new LeftBorder(),
new RightBorder(),
new TopBorder(),
new BottomBorder(),
new DiagonalBorder())
),
new CellFormats(
// Index 0 - Default cell style
new CellFormat() { FontId = 0, FillId = 0, BorderId = 0 },
new CellFormat() { FontId = 1, FillId = 0, BorderId = 0, ApplyFont = true }
)
);
}