我正在运行QT嵌入式应用程序(4.8.5),发现导致GUI线程挂起的问题。
下面是按钮代码。
const char* PushButtonService::m_eventfile = "/dev/input/event1";
PushButtonService::PushButtonService(QObject *parent): m_stop(false), m_pressed(false)
{
m_sockfd = open(m_eventfile, O_RDONLY);
m_notifier = new QSocketNotifier(m_sockfd, QSocketNotifier::Read, this);
connect(m_notifier, SIGNAL(activated(int)), this, SLOT(readBtnEvts()));
m_notifier->setEnabled(true);
}
void PushButtonService::readBtnEvts()
{
QLOG_TRACE() << "read evts";
struct input_event events[64];
QMutexLocker locker(&m_mutex);
int bytes = read(m_sockfd, events, sizeof(struct input_event));
if (bytes < (int) sizeof(struct input_event)) {
QLOG_TRACE() << "no evts";
return;
}
for (int i = 0; i < bytes / sizeof(struct input_event); i++){
if (events[i].type == EV_KEY ) {
if (events[i].value == 2) {
if ( ! m_pressed ) {
QLOG_TRACE() << "Emergency Pressed";
emit emergencyPressed();
m_pressed = true;
}
}else if (events[i].value == 0){
if (m_pressed){
QLOG_TRACE() << "Emergency Released";
emit emergencyReleased();
m_pressed = false;
}
}
}
}
}
PushButtonService::~PushButtonService()
{
close(m_sockfd);
delete m_notifier;
}
以下是GUI框架:
m_emergency_frame = new EmergencyFrame(this, m_language);
m_emergency_frame->hide();
m_push_button = new PushButtonService(this);
connect(m_push_button, SIGNAL(emergencyPressed()), this, SLOT(emergencyPressed()));
connect(m_push_button, SIGNAL(emergencyReleased()), this, SLOT(emergencyReleased()));
void MainFerryFrame::emergencyPressed(){
QLOG_TRACE() << "Button pressed";
m_emergency_frame->show();
m_emergency_frame->raise();
}
void MainFerryFrame::emergencyReleased()
{
QLOG_TRACE() << "Button released";
m_emergency_frame->hide();
}
我可以在开始时获得按钮事件,但是在重复一些之后,GUI应用程序挂起,并且在应用程序出现时回溯:
(gdb) bt
#0 0xb650a378 in read () from /lib/arm-linux-gnueabihf/libpthread.so.0
#1 0xb69c81c0 in ?? () from /usr/lib/libQtGui.so.4
#2 0xb6632bf4 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) () from /usr/lib/libQtCore.so.4
#3 0xb6667f2a in QSocketNotifier::activated(int) () from /usr/lib/libQtCore.so.4
#4 0xb6638106 in QSocketNotifier::event(QEvent*) () from /usr/lib/libQtCore.so.4
#5 0xb69cf818 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/libQtGui.so.4
#6 0xb69d123a in QApplication::notify(QObject*, QEvent*) () from /usr/lib/libQtGui.so.4
#7 0x000d7028 in ?? ()
Cannot access memory at address 0x2044
#8 0x000d7028 in ?? ()
Cannot access memory at address 0x2044
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
任何线索?
答案 0 :(得分:0)
m_sockfd = open(m_eventfile, O_RDONLY);
我相信这将执行阻止读取,除非设置了O_NONBLOCK
。这是因为当您收到通知时,无法保证有64个事件可用。
您应该在自己的Qthread中执行PushButtonService
个对象。
m_push_button = new PushButtonService(0);
m_service_thread = new QThread();
m_push_button->moveToThread(m_service_thread);
您必须在插槽中移动PushButtonService
构造函数的所有设置(即bootstrap
),并将其连接到QThread的开始信号。