-
question
mainwindow에서 m_serialPort 객체를 생성 후 open() 전의 객체를 Qthread 인수에 전달하여 Qthread 초기화 때 open()을 선언 했는데 run() 함수에서 해당 serial이 open되지 않았다고 합니다.
좋은 답변 공유 부탁드립니다. 감사합니다.------------------Reference files--------------------
worker.h
#ifndef WORKER_H
#define WORKER_H#include <QThread>
#include <QSerialPort>class Worker : public QThread
{
Q_OBJECTpublic:
explicit Worker(QObject *parent = nullptr,QSerialPort *serial = nullptr);
void stop();
int m_stopFlag = false;
QSerialPort serial;
private:
void run();signals:
void getData(QByteArray data);
};#endif // WORKER_H
worker.cpp
#include "worker.h"
#include "mainwindow.h"
#include <QDebug>Worker::Worker(QObject *parent,QSerialPort *serial):
QThread(parent)
{
serial->open(QIODevice::ReadOnly);
}void Worker::run()
{
serial.open(QIODevice::ReadOnly);
qDebug() << serial.isOpen();
while(1)
{
const QByteArray data = serial.readAll();
emit getData(data);
}
}void Worker::stop()
{
m_stopFlag = true;
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QSettings>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QComboBox>
#include <QPushButton>
#include <QLabel>
#include "worker.h"QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{
Q_OBJECTpublic:
MainWindow(QWidget *parent = nullptr);
~MainWindow();public slots:
void KeyBoard_triggered();
void Excel_triggered();
void ExcelLocation_triggered();
void Printer_triggered();
void Csv_triggered();
void Log_triggered();
void Preferences_triggered();
void Checkbox_clicked();
void TEbtn_clicked();
void DELbtn_clicked();// Serial Slot (READ) void readData(); // 포트 새로 고침 void RefreshPortList_list(); // 포트 연결 버튼 slots void SerialConnect_clicked();
protected:
void mousePressEvent(QMouseEvent *f);
void ReadFile();
void handleError(QSerialPort::SerialPortError error);
void on_btnConnect_clicked();
void on_btnDisConnect_clicked();private:
// ui 화면 초기화
Ui::MainWindow *ui;// Port_Combo_Box 객체 초기화 QComboBox port_combo; // 초기화 작업 시 아래 함수 함께 실행 void fillPortsInfo(); // 새로고침 버튼 QPushButton Refresh; // 시리얼 객체 초기화 QSerialPort* m_serialPort = nullptr; // 현재 포트 상태 라벨 QLabel port_status_lbl; // 연결 버튼 초기화 QPushButton ConnectBtn; // 초기화 작업 시 Serial 연결 void initialSerial(); Worker* qthread;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "worker.h"
#include <QDebug>
#include <QMouseEvent>
#include <QTableWidget>
#include <QMessageBox>
#include <QSettings>
#include <QCheckBox>
#include <QHBoxLayout>
#include <Qt>
#include <QTableWidgetItem>
#include <QPushButton>
#include <QScrollArea>
#include <QGroupBox>
#include <QComboBox>
#include <QThread>MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, m_serialPort(new QSerialPort(this))
{
ui->setupUi(this);
ui->toolBar->setIconSize(QSize(50,50));
ui->toolBar->setFixedHeight(50);
ui->actionKeyBoard->setEnabled(true);
ui->actionLog->setCheckable(true);
ui->actionCsv->setCheckable(true);
ui->actionExcel->setCheckable(true);
ui->actionPrinter->setCheckable(true);
ui->actionKeyBoard->setCheckable(true);
ui->actionExcelLocation->setCheckable(true);
ui->actionPreferences->setCheckable(true);// 처음 실행시 KeyBoard Mode Default ui->actionKeyBoard->setChecked(true); ui->actionExcel->setChecked(false); ui->actionExcelLocation->setChecked(false); ui->actionPrinter->setChecked(false); ui->actionCsv->setChecked(false); ui->actionLog->setChecked(false); ui->actionPreferences->setChecked(false); // 포트 정보 읽어오기 fillPortsInfo(); // toolBar Action Connect Signal connect(ui->actionKeyBoard, SIGNAL(triggered()), this, SLOT(KeyBoard_triggered())); connect(ui->actionExcel, SIGNAL(triggered()), this, SLOT(Excel_triggered())); connect(ui->actionExcelLocation, SIGNAL(triggered()), this, SLOT(ExcelLocation_triggered())); connect(ui->actionPrinter, SIGNAL(triggered()), this, SLOT(Printer_triggered())); connect(ui->actionCsv, SIGNAL(triggered()), this, SLOT(Csv_triggered())); connect(ui->actionLog, SIGNAL(triggered()), this, SLOT(Log_triggered())); connect(ui->actionPreferences, SIGNAL(triggered()), this, SLOT(Preferences_triggered()));
// QSettings * settings = 0;
// settings = new QSettings("./INITS/DATA.ini", QSettings::IniFormat);
// ret = settings->value()QString filepath = "C:/Users/Administrator/Documents/02_Gui_Application/INITS/DATA.ini"; QSettings settings(filepath, QSettings::IniFormat); settings.setIniCodec("UTF-8"); QStringList sectionList = settings.childGroups(); //tableWidget 설정 // 테이블 위젯 가로로 지정 ui->tableWidget->verticalHeader()->setVisible(false); // data.ini 에서 값 group(sections) 개수 가져오기 int iniLength = sectionList.length(); // tableWidget 행 개수 지정 ui->tableWidget->setRowCount(iniLength); // tableWidget 열 개수 지정 ui->tableWidget->setColumnCount(7); // tableWidget 열 데이터 나열 QStringList category_header; category_header << "적용" << "UID" << "기기명" << "DATA" << "T/E" << "EXCEL" << "삭제"; ui->tableWidget->setHorizontalHeaderLabels(category_header); // tableWidget 열 데이터 width ui->tableWidget->setColumnWidth(0,20); ui->tableWidget->setColumnWidth(1,20); ui->tableWidget->setColumnWidth(2,80); ui->tableWidget->setColumnWidth(3,60); ui->tableWidget->setColumnWidth(4,60); ui->tableWidget->setColumnWidth(5,90); ui->tableWidget->setColumnWidth(6,60); // data.ini데이터 tableWidget에 넣기 for(int i=0; i<sectionList.size(); i++) { int a = 0; // checkbox 생성 QCheckBox *checkbox = new QCheckBox(); connect(checkbox, SIGNAL(clicked()), this, SLOT(Checkbox_clicked())); QWidget *w = new QWidget(); QHBoxLayout *layoutCB = new QHBoxLayout(); layoutCB->addWidget(checkbox); layoutCB->setAlignment(Qt::AlignCenter); layoutCB->setContentsMargins(0, 0, 0, 0); w->setLayout(layoutCB); ui->tableWidget->setCellWidget(i, a, w); // checkbox 상태 확인 settings.beginGroup(sectionList.at(i)); if(settings.value("recivedata").toString() == "Y") { checkbox->setChecked(true); }else{ checkbox->setChecked(false); } // uuid 적용 a += 1; QTableWidgetItem* uuidItem = new QTableWidgetItem(settings.value("uuid").toString()); uuidItem->setTextAlignment(Qt::AlignCenter); ui->tableWidget->setItem(i,a,uuidItem); // 기기명 적용 a += 1; QTableWidgetItem* uuidName = new QTableWidgetItem(sectionList.at(i)); uuidName->setTextAlignment(Qt::AlignCenter); ui->tableWidget->setItem(i,a,uuidName); // data 미리 만들어 두기 a += 1; QTableWidgetItem* tableData = new QTableWidgetItem(); tableData->setTextAlignment(Qt::AlignCenter); // Tab / Enter a += 1; QPushButton *TEbtn = new QPushButton(ui->tableWidget->cellWidget(i,a)); TEbtn->setVisible(true); TEbtn->setFixedWidth(60); TEbtn->setText(settings.value("btnte").toString()); ui->tableWidget->setCellWidget(i,a,TEbtn); // TAB/ENTER SIGNAL CONNECT connect(TEbtn, SIGNAL(clicked()), this, SLOT(TEbtn_clicked())); // EXCEL a += 1; QPushButton *EXCELbtn = new QPushButton(ui->tableWidget->cellWidget(i,a)); EXCELbtn->setVisible(true); EXCELbtn->setFixedWidth(90); ui->tableWidget->setCellWidget(i,a,EXCELbtn); // 삭제 a += 1; QPushButton *DELbtn = new QPushButton(ui->tableWidget->cellWidget(i,a)); DELbtn->setVisible(true); DELbtn->setFixedWidth(60); DELbtn->setText("DEL"); ui->tableWidget->setCellWidget(i,a,DELbtn); connect(DELbtn, SIGNAL(clicked()), this, SLOT(DELbtn_clicked())); settings.endGroup(); } // Preferences 환경설정 Widget // 환경설정 스크롤 영역 QGroupBox *groupBox = new QGroupBox("PORT 설정"); QHBoxLayout *port_layout = new QHBoxLayout; // Refresh 버튼 관련 설정 Refresh.setText("R"); connect(&Refresh, SIGNAL(clicked()), this, SLOT(RefreshPortList_list())); // ConnectBt 버튼 관련 설정 connect(&ConnectBtn, SIGNAL(clicked()), this, SLOT(SerialConnect_clicked())); // port_status_lbl 관련 설정 QString portIni = "C:/Users/Administrator/Documents/02_Gui_Application/INITS/PORT.ini"; QSettings portIniSettings(portIni, QSettings::IniFormat); portIniSettings.setIniCodec("UTF-8"); QStringList portIniSettingsSection = settings.childGroups(); portIniSettings.beginGroup(portIniSettingsSection.at(0)); QString getPort = portIniSettings.value("PORT").toString(); portIniSettings.endGroup(); ConnectBtn.setText("PORT OPEN"); port_layout->addWidget(&port_combo); port_layout->addWidget(&ConnectBtn); port_layout->addWidget(&port_status_lbl); port_layout->addWidget(&Refresh); groupBox->setLayout(port_layout); ui->scrollArea->setWidget(groupBox); ui->scrollArea->hide(); ui->verticalLayout->addWidget(ui->tableWidget); ui->verticalLayout->addWidget(ui->scrollArea);
// setLayout(ui->verticalLayout);
}
void MainWindow::initialSerial()
{
QString portIni = "C:/Users/Administrator/Documents/02_Gui_Application/INITS/PORT.ini";
QSettings portIniSettings(portIni, QSettings::IniFormat);
portIniSettings.setIniCodec("UTF-8");
QStringList portIniSettingSection = portIniSettings.childGroups();portIniSettings.beginGroup(portIniSettingSection.at(0)); QString getPort = portIniSettings.value("PORT").toString();
}
void MainWindow::SerialConnect_clicked()
{if(ConnectBtn.text() == "PORT OPEN") { m_serialPort->setPortName(port_combo.currentText()); m_serialPort->setBaudRate(QSerialPort::Baud115200); m_serialPort->setDataBits(QSerialPort::Data8); m_serialPort->setParity(QSerialPort::NoParity); m_serialPort->setStopBits(QSerialPort::OneStop); m_serialPort->setFlowControl(QSerialPort::NoFlowControl); qDebug() << m_serialPort->isOpen(); qthread = new Worker(this, m_serialPort); connect(qthread, SIGNAL(getData()), SLOT(getData_sig())); qthread->start();
// if(m_serialPort->open(QIODevice::ReadOnly))
// {
// ConnectBtn.setText("PORT CLOSE");
// port_status_lbl.setText("현재 포트 상태 : OPENED");// // ADD
// thread_test = new QThread();// }else{
// QMessageBox::critical(this, tr("Error"), m_serialPort->errorString());
// }
}else if(ConnectBtn.text() == "PORT CLOSE")
{
if(m_serialPort->isOpen())
{
m_serialPort->close();
ConnectBtn.setText("PORT OPEN");
port_status_lbl.setText("현재 포트 상태 : CLOSED");
}else{
QMessageBox::critical(this, tr("Error"), m_serialPort->errorString());
}
}
}void MainWindow::RefreshPortList_list()
{
port_combo.clear();const auto& infos = QSerialPortInfo::availablePorts(); for(const QSerialPortInfo &info : infos) { if(info.description().contains("CP210x",Qt::CaseInsensitive) == true) { port_combo.addItem(info.portName()); }else{ continue; } }
}
void readData()
{}
void MainWindow::fillPortsInfo()
{
// port_comboBox Clear
port_combo.clear();
// 현재 활성화 되어 있는 포트 확인
// auto : 변수의 형식(type)이 자동으로 결정
const auto infos = QSerialPortInfo::availablePorts();for(const QSerialPortInfo &info : infos) { // 포함된 문자열 여부 ( 검색 ) CaseInsenstive - 대소문자 구분 없이 if(info.description().contains("CP210x",Qt::CaseInsensitive) == true) { qDebug() << "true 임"; port_combo.addItem(info.portName()); }else{ continue; } }
}
void MainWindow::on_btnConnect_clicked()
{// 시리얼 설정 코드 // 시리얼 연결 전 m_serialPort->setPortName(port_combo.currentText()); m_serialPort->setBaudRate(QSerialPort::Baud115200); m_serialPort->setDataBits(QSerialPort::Data8); m_serialPort->setParity(QSerialPort::NoParity); m_serialPort->setStopBits(QSerialPort::OneStop); m_serialPort->setFlowControl(QSerialPort::NoFlowControl); if(m_serialPort->open(QIODevice::ReadWrite)) { }
}
// DEL BUTTON CLICKED EVENT
void MainWindow::DELbtn_clicked()
{
qDebug() << "DEL 버튼 아직 이벤트 설정하지 않음";
}// TAB / ENTER BUTTON CLICKED EVENT
void MainWindow::TEbtn_clicked()
{
if(ui->tableWidget->cellWidget(ui->tableWidget->currentRow(),4)->property("text").toString() == "ENTER")
{
ui->tableWidget->cellWidget(ui->tableWidget->currentRow(),4)->setProperty("text","TAB");
}
else if(ui->tableWidget->cellWidget(ui->tableWidget->currentRow(),4)->property("text").toString() == "TAB")
{
ui->tableWidget->cellWidget(ui->tableWidget->currentRow(),4)->setProperty("text","ENTER");
}
}void MainWindow::Checkbox_clicked()
{
qDebug() << "체크박스 클릭됨";
}void MainWindow::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::RightButton)
{
event->ignore();
qDebug() << "오른쪽 클릭 무시됨";
}
}// ui->toolBar->actionKeyBoard triggered Event
void MainWindow::KeyBoard_triggered()
{
ui->actionKeyBoard->setChecked(true);
ui->actionExcel->setChecked(false);
ui->actionExcelLocation->setChecked(false);
ui->actionCsv->setChecked(false);
ui->actionLog->setChecked(false);
ui->actionPreferences->setChecked(false);ui->tableWidget->show(); ui->scrollArea->hide(); qDebug() << "KeyBoard 클릭됨";
}
// ui->toolBar->actionExcel triggered Event
void MainWindow::Excel_triggered()
{
// Excel을 실행 시켜야 한다.
// 기본 KeyBoard Mode로 고정하고 Excel을 실행 시킨다.
// 만약 Excel이 실행중이라면 이미 엑셀이 실행중이라는 Message를 프롬프트ui->actionExcel->setChecked(false); ui->actionExcelLocation->setChecked(false); ui->actionPrinter->setChecked(false); ui->actionLog->setChecked(false); ui->actionCsv->setChecked(false); ui->actionPreferences->setChecked(false); qDebug() << "Excel 클릭됨";
}
void MainWindow::readData()
{}
//ui->toolBar->actionExcelLocation triggered Event
void MainWindow::ExcelLocation_triggered()
{
// filedialog를 실행시켜 저장을 한다.qDebug() << "ExcelLocation 클릭됨"; ui->actionExcelLocation->setChecked(false);
}
//ui->toolBar->actionPrinter triggered Event
void MainWindow::Printer_triggered()
{
qDebug() << "Printer 클릭됨";}
//ui->toolBar->actionCsv triggered Event
void MainWindow::Csv_triggered()
{
qDebug() << "Csv 클릭됨";
}//ui->toolBar->actionLog triggered Event
void MainWindow::Log_triggered()
{
qDebug() << "Log 클릭됨";
}//ui->toolBar->actionPreferences triggered Event
void MainWindow::Preferences_triggered()
{
qDebug() << "Preferences 클릭됨";
ui->tableWidget->hide();
ui->scrollArea->show();
}//void MainWindow::ButtonClicked()
//{
// qDebug() << "ui에서 가져온 생성 이벤트";
//}//void MainWindow::slot_btn()
//{
// qDebug() << "MainWindow에서 직접 위젯 생성 이벤트";
//}MainWindow::~MainWindow()
{
delete ui;
}main.cpp
#include "mainwindow.h"
#include <QApplication>
#include <QTextCodec>int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
} -
-
-
@BAKI Please edit your post and place the code in between code markers. Either highlight it and use the </> tool button, or type three backticks on a line before and a line after each block.
@BAKI said in QT QThread QSerial 질문 입니다.:
mainwindow에서 m_serialPort 객체를 생성 후 open() 전의 객체를 Qthread 인수에 전달하여 Qthread 초기화 때 open()을 선언 했는데 run() 함수에서 해당 serial이 open되지 않았다고 합니다.
좋은 답변 공유 부탁드립니다. 감사합니다.Google translate version:
After creating the m_serialPort object in the mainwindow, I passed the object before open() to the Qthread argument and declared open() when initializing the Qthread, but the run() function says that the serial is not open.
Please share good answers. thank youThere is no need for threads when using QSerialPort. Do this without threads and you will probably find it much easier.
-
-
Hi,
This forum is English based so please use that language when asking questions outside of the International category.
This one has been moved to the Korean sub-forum in the international category so you may have other Korean speaking member being able to help you.