2015-07-21 66 views
0

我正在使用qt框架的特殊形式,它看起来有点复杂。不过别担心。它与qt的原始框架相同。 (不,我不能改变它)C++/Qt线程错误,无需使用线程

我的这个计划的目的是从UI加载一个表tableviewtableview应该具有与目录中的文件一样多的行和文本。我把目录中的所有文件都放在它们上面。只有选定的一个才会被统计和使用。

而现在我的问题: 我想显示表格像一个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

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是硬件模块的按钮,只需点击它们) 因此,如果我这样做,程序将编译并启动。如果我按下按钮,程序运行到my_setCFGFromDirectory()它将退出窗口并停止运行,但如果在my_setCFGFromDirectory()中声明的QStandardItem pointerTableitem一切正常(但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”是制造商 – Schausi

+0

根据我可以得到的答案发布了一个答案。而你正在使用一个线程;) –

回答

0

如果我没有记错的问题就在这里:

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

您尝试创建一个QStandardItemModel通过你的Form例如this作为家长,该形式在主线程创建的,这个调用发生明显在另一个线程上(您所做的编辑还不够,目前还不清楚RbObject是否继承QThread,但您可以自己检查一下),从而获得错误消息。

为什么不调用主线程上的函数?相反,在不同的线程这样

f->show(); 
entered_ui = 1; 

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

的,做了Form类插槽/信号对,把这段代码在插槽和RbObject45000::exec()火所连接的信号。从非UI头部进行UI操作是不正确的。

+0

1. Yheea。我认为你知道你想说的是什么。我会改变它。非常感谢^^ :) 2.Ähm。所以你的意思是'f-> show()'funktion在错误的文件中? 如果是这样,我可以告诉你,这是这样的,我不能改变它。我刚刚扭过最后一年的项目,我正在与之合作的公司这么说。还有yhea。这就是事情:) – Schausi

+0

那么,'f-> show()'不是主要问题(我不知道Qt内部,也许它检查从哪个线程调用它,并且内部实际上发出一个信号给主线程当你从非gui线程调用它时),'f-> my_setCFGFromDirectory()'是。你得到的问题是因为你在一个错误的线程中用一个父对象创建一个对象。如果你可以1)将'my_setCFGFromDirectory()'中的所有东西移动到'Form'的一个槽中,并在'my_setCFGFromDirectory()'中为该槽发出一个信号,你应该没问题。 –

+0

嗯。嗯。你的意思是'my_setCFGFromDirectory'中的所有内容或只是声明的东西? – Schausi