簡體   English   中英

不使用線程的C ++ / Qt線程錯誤

[英]C++/Qt Threads error without using threads

我正在使用一種特殊形式的qt框架,它將看起來有些復雜。 不過別擔心。 它與qt的原始框架相同。 (不,我無法更改)

該程序的目的是從ui的tableview加載表格。 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

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中的聲明有關。

如果我沒記錯的話,問題就出在這里:

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

您嘗試創建一個QStandardItemModel作為父級傳遞this Form實例,該表單是在主線程上創建的,此調用顯然發生在另一個線程上(您所做的編輯不夠,還不清楚RbObject繼承QThread但是您可以檢查一下自己),然后顯示錯誤消息。

為什么不在主線程上調用該函數? 而不是這樣做

f->show();
entered_ui = 1;

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

在另一個線程中,為Form類創建一個插槽/信號對,將此代碼放入插槽中,並觸發來自RbObject45000::exec()的連接信號。 從非UI trhead執行UI操作是不正確的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM