i created new form in Qt and i would like to ask you where is form load function, where i can put my code.
And another problems are that file_exists doesn't work and i dont know why (i would like to use C native functions), and my Messagebox show before form load why? I would like to load while form and then show my Messagebox. And the last thing is that this->close(); at if statement doesn't work.
This is my code:
#include "nacitanie_okno.h"
#include "ui_nacitanie_okno.h"
#include "funkcie.h"
#include <iostream>
const char *subory[] = { "test.txt" } ;
nacitanie_okno::nacitanie_okno(QWidget *parent) :
QDialog(parent),
ui(new Ui::nacitanie_okno)
{
ui->setupUi(this);
int i;
int pocet = 1;
int percent = 20 / pocet;
for(i = 0; i < pocet ; i++){
if(file_exists(subory[i])){
ui->progressBar->setValue(ui->progressBar->value() + percent);
} else {
MessageBox("Hi","teeest"); // my own function for messagebox
this->close();
}
}
}
nacitanie_okno::~nacitanie_okno()
{
delete ui;
}
and in funkcie.h is this:
bool file_exists(const char * subor)
{
if (FILE * sub = fopen(subor, "r"))
{
fclose(sub);
return true;
}
return false;
}
thank you
The best way to create Form is pointers .
The "Load Form" function is the constructor of the class .
So when you want to create a form ,lets say you have "class Myform;" which is a gui form class, should be like this :
Myform* form = new Myform("constructor variables");
This will call the constructor where there you should write what you want as Form Load Function .
use this->hide this should work .
Print errno value , as fopen sets the errno value upon error .
Related
I want to read the size and the values of my matrix from a text file.
an example of a text file
graphe.txt
4 (the size of the matrix)
1 0 1 0
1 1 1 1
0 1 1 1
0 0 0 1
I tried a code but unfortunately it didn't work .I got this errors:
error: 'class MainWindow' has no member named 'display' this->display->setText(val);
error: cannot convert 'QString' to 'int' in assignment
matrice[ligne][i]=val;
void MainWindow::remplir_matrice(int taille_mat,int matrice[][50] )
{
QFile file("/home/yosra/degré/degré/graphe.txt");
if (file.open(QIODevice::ReadOnly))
{
QTextStream in(&file);
int i=1;
int ligne=1;
while ((!in.atEnd())&&(ligne<=taille_mat))
{
ligne++;
QString line = in.readLine();
QStringList list = line.split(" ");
QString val = list.at(i);
this->display->setText(val);
val.toInt();
matrice[ligne][i]=val;
i++;
}
file.close();
}
}
void MainWindow::afficher(int matrice[][50],int taille_mat)
{
qDebug()<<" les elements de matrice";
for(int i=0;i<taille_mat;i++)
{
for(int j=0;j<taille_mat;j++)
qDebug()<<"M "<<matrice[i][j]<<endl;
}
}
void MainWindow::parourir_fichier(int matrice[50][50],int taille_mat)
{
QFile file("/home/y/degré/classement/graphe.txt");
if (file.open(QIODevice::ReadOnly))
{
QTextStream in(&file);
QStringList list;
QString line = in.readLine();
QString val = list.at(0);
this->display->setText(val);
val.toInt();
taille_mat=val;
qDebug() << "taille_mat=" << taille_mat<<endl;
file.close();
}
remplir_matrice(taille_mat,matrice);
afficher(matrice,taille_mat);
}
this is my MainWindow's header
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void remplir_matrice(int taille_mat,int matrice[][50] );
void parourir_fichier(int matrice[][50],int taille_mat);
void afficher(int matrice[][50],int taille_mat);
private:
Ui::MainWindow *ui;
int matrice[50][50];
int taille_mat;
};
Could it be that you mean:
ui->display->setText(val);
The MainWindow class does not have a pointer to the display object. Perhaps the display object was created with Qt Creator editor as a TextEdit field?
Update
If you just want to see a value while you are still developing your code, you are probably better off using qDebug() (documentation here). You will need to include to make this work. The output will be shown in the output pane when you run the application from Qt Creator.
#include <QDebug>
// ...further down in your code:
qDebug() << "Output of val:" << val;
The second error message is pretty clear, isn't it? A QString cannot be automatically converted to an int. I don't really know Qt, but a quick Google search reveals the existence of a toInt member function, so the following probably works:
matrice[ligne][i]=val.toInt();
As for the first error message, this->display supposes the existence of a member variable in MainWindow. If display is a member function (it certainly sounds like one), then you need parentheses: this->display(). If there is no member function of that name either, then we cannot help you much with the code that you have posted.
I am using a special form of the qt framework and it will look a bit complicated. But do not worry. It is the same as the original framework of qt. (And no I can't change it)
My intention of this program is to load a table in a tableview from the ui. The tableview should have as many rows and text as files that are in a directory. I take all files in the directory and put an filter on them. Only the selected one are counted and used afterwards.
And now to my problem:
I want to display the table like an Excel table: it should highlight the cell where my cursor (in my example it is an counter which goes up and down) stands right now (Currently I do not have a cursor, so I have to use a self-created "cursor". You will see it in the program what I mean).
I use a QStandardItemModel to display it and a QStandardItem to define it.
Because I want to change the color of the cells I use an QStandardItem array to save the cells one by one.
form.h:
#ifndef FORM_H
#define FORM_H
#include <QWidget>
#include <QTextTable>
#include <QFont>
#include <QFile>
#include <QDir>
#include <QTextStream>
#include <QString>
#include <QStringList>
#include <QStandardItemModel>
#include <QStandardItem>
#include <QBrush>
namespace Ui {
class Form;
}
class Form : public QWidget
{
Q_OBJECT
public:
explicit Form(QWidget *parent = 0);
~Form();
void my_setCFGFromDirectory();
void my_Highlighted(int, bool);
void my_loadCFG(int);
private:
Ui::Form *ui;
QFile file;
QTextStream textstream;
QDir directory;
QString filename;
QStringList stringlist;
QStringList filter;
QStandardItemModel *model;
QStandardItem *tableitem;
QStandardItem* pointerTableitem[];
int max_files;
int w_counter;
bool check1;
bool check2;
bool check3;
};
#endif // FORM_H
and the
form.cpp
#include "form.h"
#include "ui_form.h"
#include "rbobject.h"
Form::Form(QWidget *parent) :
QWidget(parent),
ui(new Ui::Form)
{
ui->setupUi(this);
}
Form::~Form()
{
delete ui;
}
void Form::my_Highlighted(int actual_count, bool modus){
if(modus == 1){
w_counter = 0;
while(w_counter < max_files){
if(w_counter == actual_count){
pointerTableitem[w_counter]->setBackground(QBrush(QColor(130,180,255)));
}
w_counter++;
}
}
else
{
w_counter = 0;
while(w_counter < max_files){
pointerTableitem[w_counter]->setBackground(QBrush(QColor(255,255,255)));
w_counter++;
}
}
}
void Form::my_setCFGFromDirectory(){
directory.setPath("/etc/rosenbauer/CFG-Files");
filter << "*_CFG.ini";
stringlist = directory.entryList(filter); //takes the selected files and wriths them in a filelist
max_files = stringlist.count(); //Counts the selected files
pointerTableitem [max_files];
memset(pointerTableitem, 0, max_files*sizeof(int)); //The compiler can not see how many elements should be in the array at the time he constructs the array.
//So you have to use this to tell the compiler, how many elements it should create
model = new QStandardItemModel(max_files, 1, this); //Rows , Columns , this
model->setHorizontalHeaderItem(0, new QStandardItem(QString("CFG-Files"))); //Column , QStandarditem...name
for(w_counter = 0; w_counter != max_files; w_counter++){
tableitem = new QStandardItem();
tableitem->setBackground(QBrush(QColor(255,255,255)));
tableitem->setText(QString(stringlist[w_counter])); //Wriths text in the cell
qDebug() << tableitem->text();
pointerTableitem[w_counter] = tableitem; //Stacks the tableitems in a filelist
model->setItem(w_counter, 0, tableitem); //Row, Column , tableitem...text
}
w_counter = 0;
//pointerTableitem[2]->setBackground(QBrush(QColor(130,180,255))); //Test
ui->TableConfig->setModel(model); //Sets the table into the UI
}
void Form::my_loadCFG(int file_position){
check1 = 0;
check2 = 0;
directory.setPath("/etc/rosenbauer/etc/rosenbauer");
check1 = directory.remove("SA008_890560-001_CFG.ini");
check2 = directory.remove("reparsed/SA008_890560-001_CFG.ini_reparsed");
if(check1 && check2){
filename = pointerTableitem[file_position]->text();
check3 = QFile::copy("/etc/rosenbauer/CFG-Files/"+filename, "/etc/rosenbauer/SA008_890560-001_CFG.ini");
if(!check3){
qDebug() << "Error! Could not copy new CFG-file into directory";
}
}
else
{
qDebug() << "Error! Could not delete running CFG-file(s) from directory";
}
}
The main header rbobject45000.h
#ifndef RbObject45000_H
#define RbObject45000_H
#include "rbobject.h"
#include "form.h"
class RbObject45000 : public RbObject{
public:
RbObject45000();
RbObject45000(qint32 rbObjectId, RDataObject *dataobject, qint32 style, QObject *parent = 0);
RbObject45000(qint32 rbObjectId, qint32 style, qint32 prio, QObject *parent);
bool entered_ui;
bool entered_key;
short counter;
short w_count;
short delay_count;
short max_files;
short begin;
short end;
Form *f;
void exec();
~RbObject45000();
};
#endif // RbObject45000_H
And this is the main:
rbobject45000.cpp
RbObject45000::RbObject45000(qint32 rbObjectId, qint32 style, qint32 prio, QObject *parent):
RbObject(rbObjectId, style, prio, parent){
entered_ui = 0;
entered_key = 0;
counter = 0;
w_count = 1; //... whilecounter
delay_count = 0; //... delay for the deadtime
max_files = 0;
begin = 0;
end = 0;
f= new Form(); //f...name of the displayed UI
}
void RbObject45000::exec(){
//Opens the file on the display
if(getKey(RB_KEY_9) && getKey(RB_KEY_7) && entered_ui ==0){
f->show();
entered_ui = 1;
// Geting the Files from Directory
f->my_setCFGFromDirectory();
}
// Prescind them file in the table
if(entered_ui == 1 && delay_count == 2){
if(getKey(RB_KEY_7)){
counter--;
entered_key = 1;
if(counter < 0){
counter = 0;
}
}
else if(getKey(RB_KEY_9)){
counter++;
entered_key = 1;
if(counter > max_files){
counter = max_files;
}
}
if(entered_key == 1){
while(w_count <= max_files){
f->my_Highlighted(w_count, 0); //Cell , not highlighted
w_count++;
}
w_count = 0;
f->my_Highlighted(counter,1); //Cell , highlighted
entered_key = 0;
}
delay_count = 0;
}
else if(delay_count == 2){ //if delay == 2 and nobody hit a button
delay_count = 0;
}
delay_count++;
//Load the coosen file as programm-config in
if(entered_ui == 1){
if(getKey(RB_KEY_8)){
f->my_loadCFG(counter);
}
}
}
(RB_KEY_7-9 are buttons of a hardware-module, only have to click them)
So if I do it like this, the program will compile and start. If I press the buttons and the program run into the my_setCFGFromDirectory() it exits the window and stop running, but if the QStandardItem pointerTableitem is declared in the my_setCFGFromDirectory() everything works fine (but the pointerTableitem needs to be private).
The errors I get are:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is Form(0x167498), parent's thread is QThread(0x1414e8), current thread is QThread(0x15d2d8)
Segmentation fault
It appears to say I use a thread (I'm sure I don't). But I know it has something to do with pointerTableitem and the declaration in the header and cpp.
If I'm not mistaken the problem lies here:
model = new QStandardItemModel(max_files, 1, this);
You try to create a QStandardItemModel passing your Form instance this as a parent, the form was created on the main thread, this call apparently happens on another thread (the edits you made were not enough, it is still unclear if RbObject inherits QThread but you could check that yourself) and thus the error message.
Why not call the function on the main thread? Instead of doing this
f->show();
entered_ui = 1;
// Geting the Files from Directory
f->my_setCFGFromDirectory();
in a different thread, make a slot/signal pair for the Form class, put this code in the slot and fire the connected signal from RbObject45000::exec(). It is not correct to do UI manipulation from a non-UI trhead.
I am trying to undo/redo in multi document interface. I have different entities. Each entity has its own class. I have used UndoGroup but when I unable to push them to undoStack dont know whats's wrong there. Can anyone help me to solve the issue.
cadgraphicscene.cpp
CadGraphicsView::CadGraphicsView()
{
undoStack = new QUndoStack(this);
}
QUndoStack *CadGraphicsView::m_undoStack() const
{
return undoStack;
}
void CadGraphicsView::showUndoStack()
{
undoView = 0;
// shows the undoStack window
if (undoView == 0)
{
undoView = new QUndoView(undoStack);
undoView->setWindowTitle("Undo Stack");
}
undoView->show();
}
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
m_undoGroup = new QUndoGroup(this);
QAction *undoAction = m_undoGroup->createUndoAction(this);
undoAction->setShortcut(QKeySequence::Undo);
QAction *redoAction = m_undoGroup->createRedoAction(this);
redoAction->setShortcut(QKeySequence::Redo);
menuEdit->insertAction(menuEdit->actions().at(1), undoAction);
menuEdit->insertAction(undoAction, redoAction);
menuEdit->addAction(undoAction);
menuEdit->addAction(redoAction);
undoAction->setEnabled(true);
redoAction->setEnabled(true);
}
void MainWindow::updateActions()
{
CadGraphicsView *view = currentDocument();
m_undoGroup->setActiveStack(view == 0 ? 0 : view->m_undoStack());
}
void MainWindow::addDocument(CadGraphicsView *view)
{
m_undoGroup->addStack(view->m_undoStack());
connect(view->m_undoStack(), SIGNAL(indexChanged(int)), this, SLOT(updateActions()));
connect(view->m_undoStack(), SIGNAL(cleanChanged(bool)), this, SLOT(updateActions()));
setCurrentDocument(view);
}
void MainWindow::setCurrentDocument(CadGraphicsView *view)
{
mdiArea->currentSubWindow();
}
CadGraphicsView *MainWindow::currentDocument() const
{
return qobject_cast<CadGraphicsView *>(mdiArea->parentWidget());
}
I am confused with why I am not able to push entities to undoStack. Please help me to solve this issue
I think the problem is in these two functions (see the inline comments):
void MainWindow::setCurrentDocument(CadGraphicsView *view)
{
// The view argument is not used at all. You do not set anything here.
mdiArea->currentSubWindow();
}
CadGraphicsView *MainWindow::currentDocument() const
{
// mdiArea->parentWidget() returns the MainWindow, so this function
// always returns 0.
return qobject_cast<CadGraphicsView *>(mdiArea->parentWidget());
// You should write it as
// return qobject_cast<CadGraphicsView *>(mdiArea->activeSubWindow()->widget());
}
Hi i am new to object oriented programming. here I intent to make three animation plots
subwindow_movie *child_Movie = new subwindow_movie;
child_Movie->setGeometry(20,100,620,560);
child_Movie->setplot(0);
child_Movie->show();
subwindow_movie *child_Movie1 = new subwindow_movie;
child_Movie1->setGeometry(680,100,620,560);
child_Movie1->setplot(1);
child_Movie1->show();
subwindow_movie *child_Movie2 = new subwindow_movie;
child_Movie2->setGeometry(325,350,620,560);
child_Movie2->setplot(2);
child_Movie2->show();
but the problem is that they all share same value of setplot i,e when the third subwindow_movie is created child_movie0 and child_movie1 both setplot values become 2; how to get rid of that... below is the set value function inside the class
#include "subwindow_movie.h"
#include "ui_subwindow_movie.h"
#include "plot.h"
#include <qapplication.h>
#include <qmainwindow.h>
int movie;
subwindow_movie::subwindow_movie(QWidget *parent) :
QDialog(parent),
ui(new Ui::subwindow_movie)
{
ui->setupUi(this);
}
subwindow_movie::~subwindow_movie()
{
delete ui;
}
void subwindow_movie::setplot(int value)
{
if (value ==0)
{ d_plot0 = new Plot( this );
movie=0;}
else if (value ==1)
{ d_plot1 = new Plot( this );
movie=1;}
else if (value ==2)
{ d_plot2 = new Plot( this );
movie=2;}
}
void subwindow_movie::on_movie_slider_valueChanged(int value)
{
if (movie ==0)
{ d_plot0->setAlpha(value);
}
else if (movie ==1)
{ d_plot1->setAlpha(value);
}
else if (movie ==2)
{ d_plot2->setAlpha(value);
}
}
the real problem is int movie which changes for with the creation of new child_movie causes the child_movie0 to run movie2. i dont want the movie variable changed for the child_movie0 with the creation of child_movie1.
With
int movie;
there is only one instance of the movie variable (it is a global variable). Each time you set its value, the previous value is overwritten.
Make movie a member variable instead:
class subwindow_movie {
int movie;
public:
...
}
Then, movie is available as separate instance for each subwindow_movie object you are creating. Inside the subwindow_movie methods, you can still access the variable as before.
Essentially, you should never use global variables - see also http://www.learncpp.com/cpp-tutorial/42-global-variables: Why global variables are evil
I am trying to create pop-up menu depending on a variable as follows:
QMenu menu(widget);
for(int i = 1; i <= kmean.getK(); i++)
{
stringstream ss;
ss << i;
string str = ss.str();
string i_str = "Merge with " + str;
QString i_Qstr = QString::fromStdString(i_str);
menu.addAction(i_Qstr, this, SLOT(mergeWith1()));
}
menu.exec(position);
where:
kmean.get(K) returns an int value,
mergeWith1() is some `SLOT()` which works fine
Issue:
The loop creates an action on menu only for i=1 case, and ignores other values of i.
Additional information
When doing the same loop with casual int values (without convert) everything works fine. e.g. if I do in loop only menu.addAction(i, this, SLOT(...))) and my K=4, a menu will be created with four actions in it, named 1, 2, 3, 4 correspondingly.
What can be the problem caused by
I think the issue is in convert part, when I convert i to string using stringstream and after to QString. May be the value is somehow lost. I am not sure.
QESTION:
How to make the loop accept the convert part?
What do I do wrong in convert part?
In Qt code, you shouldn't be using std::stringstream or std::string. It's pointless.
You have a crashing bug by having the menu on the stack and giving it a parent. It'll be double-destructed.
Don't use the synchronous blocking methods like exec(). Show the menu asynchronously using popup().
In order to react to the actions, connect a slot to the menu's triggered(QAction*) signal. That way you can deal with arbitrary number of automatically generated actions.
You can use the Qt property system to mark actions with custom attributes. QAction is a QObject after all, with all the benefits. For example, you can store your index in an "index" property. It's a dynamic property, created on the fly.
Here's a complete example of how to do it.
main.cpp
#include <QApplication>
#include <QAction>
#include <QMenu>
#include <QDebug>
#include <QPushButton>
struct KMean {
int getK() const { return 3; }
};
class Widget : public QPushButton
{
Q_OBJECT
KMean kmean;
Q_SLOT void triggered(QAction* an) {
const QVariant index(an->property("index"));
if (!index.isValid()) return;
const int i = index.toInt();
setText(QString("Clicked %1").arg(i));
}
Q_SLOT void on_clicked() {
QMenu * menu = new QMenu();
int last = kmean.getK();
for(int i = 1; i <= last; i++)
{
QAction * action = new QAction(QString("Merge with %1").arg(i), menu);
action->setProperty("index", i);
menu->addAction(action);
}
connect(menu, SIGNAL(triggered(QAction*)), SLOT(triggered(QAction*)));
menu->popup(mapToGlobal(rect().bottomRight()));
}
public:
Widget(QWidget *parent = 0) : QPushButton("Show Menu ...", parent) {
connect(this, SIGNAL(clicked()), SLOT(on_clicked()));
}
};
int main (int argc, char **argv)
{
QApplication app(argc, argv);
Widget w;
w.show();
return app.exec();
}
#include "main.moc"