uinput thread and UI
-
Seriale::Seriale(QWidget *parent) : QMainWindow(parent), ui(new Ui::Seriale) { ui->setupUi(this); this->installEventFilter(this); ui->textEdit->append(s2Value + " "); ui->textEdit->moveCursor(QTextCursor::End); mThreadKEY = new ThreadKEY(this); <------ problem on_Btn_Open_clicked(); } void Seriale::Open_uinput_port() { /* uinput driver open */ key_fd = open("/dev/uinput",O_WRONLY | O_NDELAY); strcpy(uinp.name,"virtual-kbd"); uinp.id.bustype = BUS_USB; uinp.id.vendor = 1; uinp.id.product = 1; uinp.id.version = 1; write(key_fd,&uinp,sizeof(uinp)); /* set key value */ ioctl(key_fd, UI_SET_EVBIT, EV_KEY); ioctl(key_fd, UI_SET_KEYBIT, KEY_A); ioctl(key_fd, UI_SET_KEYBIT, KEY_B); /* ...... etc etc for all key */ } /* other not interesting code*/ void Seriale::OperThread() /*parsing with ring buffer --problem with signal*/ { int ptr_start, ptr_end; unsigned int crc_buf; /* check STX and ETX in packet */ m_abyBuffer.FindChar(STX,ptr_start); m_abyBuffer.FindChar(ETX,ptr_end); if((ptr_start >= ptr_end) && (ptr_end - ptr_start != 8)){ return; } if ( (ptr_start != 0) && (ptr_end != 8) ) { m_abyBuffer.m_iReadPtr = m_abyBuffer.m_iReadPtr + ptr_start; memset (g_Packet_Buffer, 0, sizeof(g_Packet_Buffer)); m_abyBuffer.ReadBinary(g_Packet_Buffer, (ptr_end-ptr_start)+1); } else { memset (g_Packet_Buffer, 0, sizeof(g_Packet_Buffer)); m_abyBuffer.ReadBinary(g_Packet_Buffer, PACKET_LENGTH); } /* Pasing packet */ if(g_Packet_Buffer[1] != MOD_GET){ return; } if(g_Packet_Buffer[2] != SEL_KEYPAD){ return; } crc_buf = crc16_append(g_Packet_Buffer,6); if((g_Packet_Buffer[6] !=(char)((crc_buf>>8)&0xff)) || (g_Packet_Buffer[7]!=(char)(crc_buf&0xff))){ //CRC Check return; } if(g_Packet_Buffer[3] == KEYPAD_DOWN){ Keydown_Event(g_Packet_Buffer); } if(g_Packet_Buffer[3] == KEYPAD_UP){ Keyup_Event(g_Packet_Buffer); } } void Seriale::Keydown_Event(char key_down[10]) { //QTextCursor cursor = ui->textEdit->textCursor(); //cursor.movePosition(QTextCursor::End); QString s1Value = QChar(key_down[4]); //QString s2Value; int v_latin = QChar(key_down[4]).toLatin1(); qDebug() << "At keyPad send these value " << v_latin; switch (v_latin) { case 30: s2Value = "A"; send_String(s2Value); //emit send_String(s2Value); //ui->textEdit->append(s2Value); //cursor.movePosition(QTextCursor::End); break; case 48: s2Value = "B"; send_String(s2Value); //emit send_String(s2Value); //ui->textEdit->append(s2Value) //cursor.movePosition(QTextCursor::End); break; case 46: s2Value = "C"; send_String(s2Value); //emit send_String(s2Value); //ui->textEdit->append(s2Value) //cursor.movePosition(QTextCursor::End); break; case 32: s2Value = "D"; send_String(s2Value); //emit send_String(s2Value); //ui->textEdit->append(s2Value) //cursor.movePosition(QTextCursor::End); break; case 18: s2Value = "E"; send_String(s2Value); //emit send_String(s2Value); //ui->textEdit->append(s2Value) //cursor.movePosition(QTextCursor::End); break; case 33: s2Value = "F"; send_String(s2Value); //emit send_String(s2Value); //ui->textEdit->append(s2Value) //cursor.movePosition(QTextCursor::End); break; case 34: s2Value = "G"; send_String(s2Value); //emit send_String(s2Value); //ui->textEdit->append(s2Value) //cursor.movePosition(QTextCursor::End); break; case 35: s2Value = "H"; send_String(s2Value); //emit send_String(s2Value); //ui->textEdit->append(s2Value) //cursor.movePosition(QTextCursor::End); break; case 23: s2Value = "I"; send_String(s2Value); //emit send_String(s2Value); //ui->textEdit->append(s2Value) // cursor.movePosition(QTextCursor::End); break; case 36: s2Value = "J"; send_String(s2Value); //emit send_String(s2Value); //ui->textEdit->append(s2Value) //cursor.movePosition(QTextCursor::End); break; case 37: s2Value = "K"; send_String(s2Value); //emit send_String(s2Value);; //ui->textEdit->append(s2Value) //cursor.movePosition(QTextCursor::End); break; case 38: s2Value = "L"; send_String(s2Value); //emit send_String(s2Value); //ui->textEdit->append(s2Value); //cursor.movePosition(QTextCursor::End); break; case 50: s2Value = "M"; send_String(s2Value); //emit send_String(s2Value);; //ui->textEdit->append(s2Value) //cursor.movePosition(QTextCursor::End); break; case 49: s2Value = "N"; send_String(s2Value); //emit send_String(s2Value);; //ui->textEdit->append(s2Value) //cursor.movePosition(QTextCursor::End); break; case 24: s2Value = "O"; send_String(s2Value); //emit send_String(s2Value); //ui->textEdit->append(s2Value) //cursor.movePosition(QTextCursor::End); break; case 25: s2Value = "P"; send_String(s2Value); //emit send_String(s2Value); //ui->textEdit->append(s2Value) //cursor.movePosition(QTextCursor::End); break; case 59: s2Value = "F1"; send_String(s2Value); //emit send_String(s2Value); //ui->textEdit->append(s2Value) //cursor.movePosition(QTextCursor::End); break; case 60: s2Value = "F2"; send_String(s2Value); //emit send_String(s2Value); //ui->textEdit->append(s2Value); // cursor.movePosition(QTextCursor::End); break; case 68: s2Value = "F10"; send_String(s2Value); //emit send_String(s2Value); //ui->textEdit->append(s2Value) //cursor.movePosition(QTextCursor::End); break; case 87: s2Value = "F11"; send_String(s2Value); //emit send_String(s2Value); //ui->textEdit->append(s2Value) //cursor.movePosition(QTextCursor::End); break; default: break; } struct input_event event; char Receive_Packetf[10] = {0, }; strcpy(Receive_Packetf,key_down); //Input key event memset(&event,0,sizeof(event)); event.type = EV_KEY; event.code = Receive_Packetf[4]; event.value = 1; write(key_fd,&event,sizeof(event)); //Sync event memset(&event,0,sizeof(event)); event.type = EV_SYN; event.code = SYN_REPORT; event.value = 0; write(key_fd,&event,sizeof(event)); } void Seriale::send_String(QString v2String){ /*this->ui->textEdit->moveCursor(QTextCursor::End); this->ui->textEdit->setTextColor(Qt::blue); this->ui->textEdit->append(v2String + " "); this->ui->textEdit->moveCursor(QTextCursor::End);*/ /*ui->textEdit->moveCursor(QTextCursor::End); ui->textEdit->setTextColor(Qt::blue); ui->textEdit->append(v2String + " "); ui->textEdit->moveCursor(QTextCursor::End);*/ /* ***** all these not work and not understand how to connect qthred signal to ui textEdit********* */ }
the Qthread .h file:
#include <QThread> /* Initialize Thread */ class Seriale; class ThreadKEY : public QThread { Q_OBJECT public: explicit ThreadKEY(QObject *parent = 0); void run(); bool Stop; bool Run; bool End; Seriale* pMainClass; signals: void send1_String(QString v3String); public slots: };
the Qthread .cpp file:
ThreadKEY::ThreadKEY(QObject *parent) : QThread(parent) { pMainClass = (Seriale*) parent; this->Stop = false; this->Run = false; this->End = false; } /* * Function name : void ThreadKEY::run * Description : This function is run to OperThread function. */ void ThreadKEY::run() { this->Run = true; pMainClass->OperThread(); this->End = true; this->Run = false; this->Stop = true; }
briefly: I have a GUI made in Qtcreator, very simple only for testing, with a QtextEdit inside which is called textEdit.
I take the values from the serial using a "ring-buffer" .... now everything works fine, but the system does not distinguish between the keyboard that I have connected and the keypad that is also connected ... however the values are correctly managed .... so I inserted a switch / case in the packet capture of the key values .... but if I try to write the corresponding letters on the QTextEdit I get errors that I imagine depend on an incorrect connection of the signal with the slot ..... but not I would know how to do it .... do I have to make a sub-class of QtextEdit to have the "append" slot? in addition what should I connect: this-> ui, OperThread-> ui or what? the code is not mine and I would not like to rewrite it completely .... in addition I find it very interesting to understand at least this thing .... how to connect a signal from Qthread declared in this way to the ui.
the error from Qtcreator that I use as debug:
At keyPad send these value 87 QObject::connect: Cannot queue arguments of type 'QTextCharFormat' (Make sure 'QTextCharFormat' is registered using qRegisterMetaType().) QObject::connect: Cannot queue arguments of type 'QTextCursor' (Make sure 'QTextCursor' is registered using qRegisterMetaType().)
-
@gfxx
wtf is this ?
pMainClass = (Seriale*) parent;
do yourself a favour and rewrite all of it.
From the looks of it. its not to much code, and the original creator didn't seem to have much, if any, experience with c++ or Qt
And stay away from threading, at least for now, I'm not sure what you're actually trying to write to, but you probably won't need threads.
If you designed your code/classes well enough it will be very easy to move everything to its own thread, should it be needed.
-
@J-Hilk said in uinput thread and UI:
do yourself a favour and rewrite all of it.
From the looks of it. its not to much code, and the original creator didn't seem to have much, if any, experience with c++ or Qt
And stay away from threading, at least for now, I'm not sure what you're actually trying to write to, but you probably won't need threads.
If you designed your code/classes well enough it will be very easy to move everything to its own thread, should it be needed.You are in right, the creator copy a library called "ring_buffer.h" that is for free .... than it make these real complicated way to parse the serial packet ....
Normally i use move to qtharead if needed (but really low case) ... better for me is create a Qthread class .... more simple to manage signal and slot.In these case seems problem is that Qthread start a mainwindow void
pMainClass = (Seriale*) parent; /*see on thread.h file, I made a correction*/
.... Qt it execute it .... and seems it become thread part .... never use these sort of trik and need to know if is valid, if is good way to do, and how to manage signal & slod in that case.
-
Hi,
No it does not, you are currently doing GUI operations from a different thread. You are just lucky it does not crash.
Having a member variable in your QThread subclass does not "move it" to the new thread. Look for thread affinity in QThread's documentation.
As @J-Hilk wrote, nuke that stuff and rewrite it correctly.
There's likely no need for threads at this stage and you should really only consider them if you have actual performance problem.