2015-07-21 4 views
0

Я использую специальную форму фрейма qt, и это будет выглядеть несколько сложнее. Но не беспокойся. Это то же самое, что и исходная структура qt. (И нет, я не могу это изменить)Ошибка C++/Qt Threads без использования потоков

Мое намерение этой программы - загрузить таблицу в tableview с ui. tableview должен иметь столько строк и текст, сколько файлов, находящихся в каталоге. Я беру все файлы в каталог и накладываю на них фильтр. Только выбранные будут подсчитываться и использоваться впоследствии.

И теперь к моей проблеме: Я хочу отобразить таблицу как таблицу Excel: она должна выделить ячейку, где мой курсор (в моем примере это счетчик, который идет вверх и вниз) стоит прямо сейчас (в настоящее время я у меня нет курсора, поэтому я должен использовать самосозданный «курсор». Вы увидите его в программе, что я имею в виду). Я использую QStandardItemModel для его отображения и QStandardItem, чтобы определить его. Поскольку я хочу изменить цвет ячеек, я использую массив QStandardItem для сохранения ячеек один за другим.

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 

и 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"; 
    } 


} 

Основной заголовок 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 

И это главное: rbobject45000. cpp

(RB_KEY_7-9 - это кнопки аппаратного модуля, нужно только щелкнуть их). Итак, если я так делаю, программа будет компилироваться и запускаться. Если я нажимаю кнопки и программа запускается в my_setCFGFromDirectory(), она выходит из окна и перестает работать, но если QStandardItem pointerTableitem объявлен в my_setCFGFromDirectory(), все работает отлично (но pointerTableitem должно быть private).

Ошибки я получаю:

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 

Похоже сказать, я использую нить (я уверен, что у меня нет). Но я знаю, что это имеет какое-то отношение к pointerTableitem и декларации в заголовке и cpp.

+0

Вы говорите, что не используете поток, но 'RbObject45000 :: exec()' кажется подозрительным как функция, которая переопределяет 'QThread :: exec()'. Можете ли вы опубликовать определение 'RbObject4500'? –

+0

Я его отредактировал :) Но у него нет проблем в файле 45000. Этот файл работает нормально. Только «form.h» и «form.cpp» являются toublemakers. – Schausi

+0

отправил ответ на основании того, что я могу извлечь из этого. И вы используете нить;) –

ответ

0

Если я не ошибаюсь, проблема лежит здесь:

model = new QStandardItemModel(max_files, 1, this); 

Вы пытаетесь создать QStandardItemModel передавая свой Form экземпляр this как родитель, форма была создана в основном потоке, этот вызов по-видимому, происходит в другом потоке (редактирование, которое вы сделали, было недостаточно, все еще неясно, наследует ли RbObjectQThread, но вы можете это проверить) и, таким образом, сообщение об ошибке.

Почему бы не вызвать функцию на основном потоке?Вместо того чтобы делать это

f->show(); 
entered_ui = 1; 

// Geting the Files from Directory 
f->my_setCFGFromDirectory(); 

в другом потоке, сделать пару слота/сигнал для Form класса, поместить этот код в слоте и огнестойкость подключенного сигнала от RbObject45000::exec(). Неправильно делать манипуляции с пользовательским интерфейсом из не-UI trhead.

+0

1. Yheaa. Я думаю, что вы получите то, что вы пытаетесь сказать. Я изменю его. Спасибо alot ^^ :) 2. Ähm. Значит, вы подразумеваете, что функция 'f-> show()' находится в неправильном файле? Если это так, я могу сказать вам, что это так, и я не могу его изменить. Я только сейчас корчу свой последний проект, и компания, с которой я работаю, так говорит. И она. Thats the thing :) – Schausi

+0

Ну, 'f-> show()' не является основной проблемой (мне не знакомы с внутренними компонентами Qt, возможно, она проверяет, из какого потока он вызывается и внутри фактически испускает сигнал в основной поток когда вы вызываете его из потока non gui), 'f-> my_setCFGFromDirectory()' is. Проблема, которую вы получаете, связана с тем, что вы создаете объект с родителем в неправильном потоке. Если вы можете либо 1) переместить все материалы, находящиеся в 'my_setCFGFromDirectory()', в слот 'Form', и выпустить сигнал для этого слота в' my_setCFGFromDirectory() ', все должно быть хорошо. –

+0

Гм. Гектометр Вы имеете в виду все в 'my_setCFGFromDirectory' или только декларации? – Schausi

Смежные вопросы