qt自定义槽函数不起作用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了qt自定义槽函数不起作用相关的知识,希望对你有一定的参考价值。

本来可以实现的,不懂为什么不行了。贴代码:
这样写 void Userinfo::on_closeBtn1_clicked() 和 connect(ui->closeBtn1,SIGNAL(clicked()),this,SLOT( closeBtn1_clicked() ));//closeBtn1_clicked()是新的槽函数................................这两种都不行
但是connect(ui->closeBtn1,SIGNAL(clicked()),this,SLOT( close() ));这样写又可以,折腾了好久都不懂为什么。新手求大神解答

你定义的这个函数

void closeBtn1_clicked() ;

一定要在前面添加Q_SLOT 宏表示这个是一个槽函数,否则系统无法执行关联操作。

或者在定义的时候加入下面标记也可以:

1、 Q_SLOT void closeBtn1_clicked() ;

或者

private slots:
void closeBtn1_clicked() ;

参考技术A 源代码截个清晰图看看吧追问

这是一个新的窗口,只有btn这个控件,代码也就这些,我在头文件也定义了槽函数,感觉这不是逻辑问题,是不是少了什么库。
我现在新增一个dialog界面,然后直接在main.cpp里show出来,也会报错。
LNK2019: 无法解析的外部符号 "public: virtual __thiscall

就是换到这台机子就有点问题

追答

可能是你没装好吧……删干净重装吧。我的Qt有时候也会抽风,平白无故的出错,同一个程序,在第一个工程项目里就一直失败,新开一个项目,粘贴过去就成功运行了…这才尴尬

本回答被提问者采纳

Qt - QLocalSocket 信号槽不起作用导致析构函数死锁

【中文标题】Qt - QLocalSocket 信号槽不起作用导致析构函数死锁【英文标题】:Qt - QLocalSocket Signal-Slot not working resulting in deadlocks in destructor 【发布时间】:2016-07-05 10:10:04 【问题描述】:

我正在使用 QLocalSocket 和 QLocalServer 在 Windows 7 上使用 VS 2010 和 Qt 5.5.1 进行进程间通信。

在向其他进程发送超过 256 条消息后,CIPSocket 中的析构函数冻结。我将问题追溯到 qtbase\src\corelib\ioqwinoverlappedionotifier.cpp 中的信号槽问题,其中在 notify(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED *overlapped) 中发出的信号 _q_notify() 不会导致调用 _q_notified() .因此 Semaphore hSemaphore 超过了它的 max-count,导致析构函数死锁。

信号槽不工作的原因可能是什么?我找不到任何断开连接或阻塞信号。

提前致谢。

main.cpp:

#include "main.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QThread>
#include <iostream>

int main(int argc, char *argv[])

    printf("Server (0) or Socket (1)?\n");
    char c = getchar();
    if (c == '0') 
        QCoreApplication app(argc, argv);
        CIPServer server;
        app.exec();
    
    else if (c == '1') 
        CIPSocket socket;
        for (unsigned int i = 0; i <= 256; ++i) 
            socket.update(i);
            QThread::msleep(10);
        
    


/*--------------------------------------------------------------------------
   CIPSocket
----------------------------------------------------------------------------*/
CIPSocket::CIPSocket()
: m_bIsReady(false)

    m_pSocket = new QLocalSocket(this);
    m_stream.setDevice(m_pSocket);

    connect(m_pSocket, SIGNAL(connected()), this, SLOT(connectionReady()));
    connect(m_pSocket, SIGNAL(disconnected()), this, SLOT(connectionLost()));

    m_pSocket->connectToServer("DemoServer");


CIPSocket::~CIPSocket()

    delete m_pSocket;
    m_pSocket = NULL;


void CIPSocket::update(int i)

    if (m_bIsReady)
        m_stream << i;


void CIPSocket::connectionReady()
 m_bIsReady = true; 

void CIPSocket::connectionLost()
 m_bIsReady = false; 

/*--------------------------------------------------------------------------
   CIPServer
----------------------------------------------------------------------------*/
CIPServer::CIPServer(QObject* parent)
: QLocalServer(parent)

    if (!listen("DemoServer")) 
        throw ("Could not connect to 'DemoServer'");
    
    connect(this, SIGNAL(newConnection()), this, SLOT(socketConnected()));


CIPServer::~CIPServer()


void CIPServer::socketConnected()

    qDebug() << "Connected";
    m_pConnection = nextPendingConnection();
    m_stream.setDevice(m_pConnection);
    connect(m_pConnection, SIGNAL(disconnected()), m_pConnection, SLOT(deleteLater()));
    connect(m_pConnection, SIGNAL(readyRead()), this, SLOT(update()));


void CIPServer::update()

    if (m_pConnection->bytesAvailable() >= 4) 
        int i;
        m_stream >> i;
        qDebug() << i;
    

main.h:

#include <QtNetwork/QLocalServer>
#include <QtNetwork/QLocalSocket>
#include <QtCore/QDataStream>
#include <QtCore/QThread>


    /// \brief Creates a socket for inter-process communication
    class CIPSocket
        : public QObject
    
        Q_OBJECT;

    public:
        /// Constructor
        CIPSocket();
        /// Destructor
        virtual ~CIPSocket();

        /// Send the data
        void update(int i);

    public slots:
        /// Enables updating
        void connectionReady();
        /// Disables updating
        void connectionLost();

    private:
        /// The target stream
        QDataStream m_stream;
        /// The socket connecting to server
        QLocalSocket* m_pSocket;
        /// Indicates if the socket is connected
        bool m_bIsReady;
    ;

    /// \brief Creates a server for inter-process communication
    class CIPServer
        : public QLocalServer
    
        Q_OBJECT;

    public:
        /// Constructor
        CIPServer(QObject* parent = NULL);
        /// Destructor
        virtual ~CIPServer();
        /// Starts the server
        void start();

    private slots:
        /// Connects the socket to the stream and to the update function
        void socketConnected();
        /// Reads the data from the stream and emits a the results
        void update();

    private:
        /// The currently connected socket
        QLocalSocket* m_pConnection;
        /// The incoming stream
        QDataStream m_stream;
    ;

demo.pro:

CONFIG += qt debug
QT += network
HEADERS += main.h
SOURCES += main.cpp
CONFIG += console

【问题讨论】:

我试图重现您的示例,但由于未知的 CSocketThread,它无法编译。 抱歉,我忘了删除一些额外的代码。现在应该可以编译了。 一些想法:尝试bool QLocalSocket::flush() .. 可能你的一些数据卡在内部缓冲区中。另外,也许调整您的代码以使用bool QLocalSocket::waitForBytesWritten(int msecs = 30000) @Derick Schoonbee:我试过这个,但没有成功。数据传输正确。如上所述,问题在于 qtbase\src\corelib\ioqwinoverlappedionotifier.cpp 中的信号量溢出,因为异步通信的工件没有被删除,因为没有调用连接的插槽来执行此操作。问题是为什么没有调用连接的插槽。 @Roland:已经报告给 Qt:bugreports.qt.io/browse/QTBUG-54567。我以为我可能忘记了对套接字的一些准备工作,但似乎问题出在 Qt 上。 【参考方案1】:

由于事件循环未运行而发生错误。启动 QCoreApplication 会启动事件循环,但会等待应用程序退出。因此发送必须在另一个线程中完成。 附加代码显示了正确的用法。

main.cpp:

#include "main.h"

int main(int argc, char *argv[])

    QCoreApplication app(argc, argv);
    printf("Server (0) or Socket (1)?\n");
    char c = getchar();
    if (c == '0') 
        CIPServer server;
        QCoreApplication::exec();
    
    else if (c == '1') 
        CIPSocket socket;
        CSender sender(500);
        QObject::connect(&sender, SIGNAL(sendMessage(int)), &socket, SLOT(update(int)));
        QObject::connect(&sender, SIGNAL(allMessagesSent()), &socket, SLOT(close()));
        sender.start();
        QCoreApplication::exec();
    


/*--------------------------------------------------------------------------
   CIPSocket
----------------------------------------------------------------------------*/
CIPSocket::CIPSocket()
: m_bIsReady(false)

    m_pSocket = new QLocalSocket(this);
    m_stream.setDevice(m_pSocket);

    connect(m_pSocket, SIGNAL(connected()), this, SLOT(connectionReady()));
    connect(m_pSocket, SIGNAL(disconnected()), this, SLOT(connectionLost()));

    m_pSocket->connectToServer("DemoServer");


CIPSocket::~CIPSocket()

    delete m_pSocket;
    m_pSocket = NULL;


void CIPSocket::update(int i)

    if (m_bIsReady)
        m_stream << i;


void CIPSocket::connectionReady()
 m_bIsReady = true; 

void CIPSocket::connectionLost()
 m_bIsReady = false; 

void CIPSocket::close()
 QCoreApplication::exit(); 

/*--------------------------------------------------------------------------
   CIPServer
----------------------------------------------------------------------------*/
CIPServer::CIPServer(QObject* parent)
: QLocalServer(parent)

    if (!listen("DemoServer")) 
        throw ("Could not connect to 'DemoServer'");
    
    connect(this, SIGNAL(newConnection()), this, SLOT(socketConnected()));


CIPServer::~CIPServer()


void CIPServer::socketConnected()

    qDebug() << "Connected";
    m_pConnection = nextPendingConnection();
    m_stream.setDevice(m_pConnection);
    connect(m_pConnection, SIGNAL(disconnected()), m_pConnection, SLOT(deleteLater()));
    connect(m_pConnection, SIGNAL(readyRead()), this, SLOT(update()));
    connect(m_pConnection, SIGNAL(disconnected()), this, SLOT(close()));


void CIPServer::update()

    if (m_pConnection->bytesAvailable() >= 4) 
        int i;
        m_stream >> i;
        qDebug() << i;
    


void CIPServer::close()
 QCoreApplication::exit(); 

/*--------------------------------------------------------------------------
   CSender
----------------------------------------------------------------------------*/
CSender::CSender(int iNumMessages)
: m_iNumMessages(iNumMessages)


CSender::~CSender()


void CSender::run()

    while (m_iNumMessages > 0) 
        emit sendMessage(m_iNumMessages);
        msleep(10);
        m_iNumMessages--;
    
    emit allMessagesSent();

main.h:

#include <QtNetwork/QLocalServer>
#include <QtNetwork/QLocalSocket>
#include <QtCore/QDataStream>
#include <QtCore/QThread>
#include <QtCore/QCoreApplication>


    /// \brief Creates a socket for inter-process communication
    class CIPSocket
        : public QObject
    
        Q_OBJECT;

    public:
        /// Constructor
        CIPSocket();
        /// Destructor
        virtual ~CIPSocket();

    public slots:
        /// Enables updating
        void connectionReady();
        /// Disables updating
        void connectionLost();
        /// Send the data
        void update(int i);
        /// Close the application
        void close();

    private:
        /// The target stream
        QDataStream m_stream;
        /// The socket connecting to server
        QLocalSocket* m_pSocket;
        /// Indicates if the socket is connected
        bool m_bIsReady;
    ;

    /// \brief Creates a server for inter-process communication
    class CIPServer
        : public QLocalServer
    
        Q_OBJECT;

    public:
        /// Constructor
        CIPServer(QObject* parent = NULL);
        /// Destructor
        virtual ~CIPServer();

    private slots:
        /// Connects the socket to the stream and to the update function
        void socketConnected();
        /// Reads the data from the stream and emits a the results
        void update();
        /// Close the application
        void close();

    private:
        /// The currently connected socket
        QLocalSocket* m_pConnection;
        /// The incoming stream
        QDataStream m_stream;
    ;

    /// \brief Sends the messages via CIPSocket
    class CSender
        : public QThread
    
        Q_OBJECT;

    public:
        /// Constructor
        CSender(int iNumMessages);
        /// Destructor
        virtual ~CSender();
        /// Sends the requestet number of messages in 10 ms steps
        virtual void run();

    signals:
        /// Sends the message via the CIPSocket
        void sendMessage(int);
        /// Informs about all messages being sent
        void allMessagesSent();

    private:
        /// The number of messages to send
        int m_iNumMessages;
    ;

【讨论】:

【参考方案2】:

程序运行良好:尝试以下操作:

启动服务器-启动客户端,发送数据-服务器接收数据-停止客户端-再次启动客户端,发送数据-服务器接收数据...

程序没有死锁,也没有死机!程序在第 13 行等待 Qt eventloop 中的事件:

app.exec();

问题是:它会做什么?

我假设,你喜欢下班后退出程序,然后插入:

void CIPServer::socketConnected()
 . . .
  connect(m_pConnection, SIGNAL(disconnected()), this, SLOT(theend()));

void CIPServer::theend()

    QCoreApplication::quit();

尝试以下操作: 启动服务器——启动客户端,发送数据——服务器接收数据——停止客户端——服务器也停止

【讨论】:

感谢您的回复,但答案并未解决所描述的问题。我的问题不是服务器没有关闭,而是 CIPSocket 在发送 256+ 条消息后挂在析构函数中。因此 Socket 也没有断开连接。 (不过我检查了你的方法)

以上是关于qt自定义槽函数不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Qt。如果我在 QStyledItemDelegate 中定义了 paint() 方法,则方法 displayText() 不起作用

QtVirtualKeyboard - 更改布局不起作用

自定义函数不起作用,但逐行起作用

未调用 Qt 信号槽

使用自定义 json 函数检索数据时分页不起作用

为多个页面定义和调用自定义 AJAX 函数不起作用