qt中connect函数探究

2023-11-01

      综合了一下网上资源,整理得出。

      

QT 是一个跨平台的 C++ GUI 应用构架,它提供了丰富的窗口部件集,具有面向对象、易于扩展、真正的组件编程等特点,更为引人注目的是目前 Linux 上最为流行的 KDE 桌面环境就是建立在 QT 库的基础之上。QT 支持下列平台:MS/WINDOWS-95、98、NT 和 2000;UNIX/X11-Linux、Sun Solaris、HP-UX、Digital Unix、IBM AIX、SGI IRIX;EMBEDDED- 支持 framebuffer 的 Linux 平台。伴随着 KDE 的快速发展和普及,QT 很可能成为 Linux 窗口平台上进行软件开发时的 GUI 首选。

 connect,是QT中的连接函数,将信号发送者sender对象中的信号signal与接受者receiver中的member槽函数联系起来。当指定信号signal时必须使用宏SIGNAL(),当指定槽函数时必须使用宏SLOT(),如果发送者与连接者属于同一个对象时,那么在connect调用中接受者参数可以忽略。

概述

信号和槽机制是 QT 的核心机制,要精通 QT 编程就必须对信号和槽有所了解。信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性,也是 QT 区别于其它工具包的重要地方。信号和槽是 QT 自行定义的一种通信机制,它独立于标准的 C/C++ 语言,因此要正确的处理信号和槽,必须借助一个称为 moc(Meta Object Compiler)的 QT 工具,该工具是一个 C++ 预处理程序,它为高层次的事件处理自动生成所需要的附加代码。

在我们所熟知的很多 GUI 工具包中,窗口小部件 (widget) 都有一个回调函数用于响应它们能触发的每个动作,这个回调函数通常是一个指向某个函数的指针。但是,在 QT 中信号和槽取代了这些凌乱的函数指针,使得我们编写这些通信程序更为简洁明了。 信号和槽能携带任意数量和任意类型的参数,他们是类型完全安全的,不会像回调函数那样产生 core dumps。

所有从 QObject 或其子类 ( 例如 Qwidget) 派生的类都能够包含信号和槽。当对象改变其状态时,信号就由该对象发射 (emit) 出去,这就是对象所要做的全部事情,它不知道另一端是谁在接收这个信号。这就是真正的信息封装,它确保对象被当作一个真正的软件组件来使用。槽用于接收信号,但它们是普通的对象成员函数。一个槽并不知道是否有任何信号与自己相连接。而且,对象并不了解具体的通信机制。

你可以将很多信号与单个的槽进行连接,也可以将单个的信号与很多的槽进行连接,甚至于将一个信号与另外一个信号相连接也是可能的,这时无论第一个信号什么时候发射系统都将立刻发射第二个信号。总之,信号与槽构造了一个强大的部件编程机制。

信号与槽的关联

通过调用 QObject 对象的 connect 函数来将某个对象的信号与另外一个对象的槽函数相关联,这样当发射者发射信号时,接收者的槽函数将被调用。该函数的定义如下:

      bool QObject::connect ( const QObject * sender, const char * signal, 
		 const QObject * receiver, const char * member ) [static]

这个函数的作用就是将发射者 sender 对象中的信号 signal 与接收者 receiver 中的 member 槽函数联系起来。当指定信号 signal 时必须使用 QT 的宏 SIGNAL(),当指定槽函数时必须使用宏 SLOT()。如果发射者与接收者属于同一个对象的话,那么在 connect 调用中接收者参数可以省略。

例如,下面定义了两个对象:标签对象 label 和滚动条对象 scroll,并将 valueChanged() 信号与标签对象的 setNum() 相关联,另外信号还携带了一个整形参数,这样标签总是显示滚动条所处位置的值。

						 QLabel     *label  = new QLabel; 
    QScrollBar *scroll = new QScrollBar; 
    QObject::connect( scroll, SIGNAL(valueChanged(int)), 
                      label,  SLOT(setNum(int)) );

一个信号甚至能够与另一个信号相关联,看下面的例子:

						 class MyWidget : public QWidget 
    { 
    public: 
        MyWidget(); 
    ... 
    signals: 
        void aSignal(); 
    ... 
    private: 
    ... 
        QPushButton *aButton; 
    }; 
    MyWidget::MyWidget() 
    { 
        aButton = new QPushButton( this ); 
        connect( aButton, SIGNAL(clicked()), SIGNAL(aSignal()) ); 
    }

在上面的构造函数中,MyWidget 创建了一个私有的按钮 aButton,按钮的单击事件产生的信号 clicked() 与另外一个信号 aSignal() 进行了关联。这样一来,当信号 clicked() 被发射时,信号 aSignal() 也接着被发射。当然,你也可以直接将单击事件与某个私有的槽函数相关联,然后在槽中发射 aSignal() 信号,这样的话似乎有点多余。

当信号与槽没有必要继续保持关联时,我们可以使用 disconnect 函数来断开连接。其定义如下:

      bool QObject::disconnect ( const QObject * sender, const char * signal, 
		 const Object * receiver, const char * member ) [static]

这个函数断开发射者中的信号与接收者中的槽函数之间的关联。

有三种情况必须使用 disconnect() 函数:

  • 断开与某个对象相关联的任何对象。这似乎有点不可理解,事实上,当我们在某个对象中定义了一个或者多个信号,这些信号与另外若干个对象中的槽相关联,如果我们要切断这些关联的话,就可以利用这个方法,非常之简洁。

     disconnect( myObject, 0, 0, 0 ) 
    或者
     myObject->disconnect()
  • 断开与某个特定信号的任何关联。

     disconnect( myObject, SIGNAL(mySignal()), 0, 0 ) 
    或者
     myObject->disconnect( SIGNAL(mySignal()) )
  • 断开两个对象之间的关联。

     disconnect( myObject, 0, myReceiver, 0 ) 
    或者
     myObject->disconnect(  myReceiver )

在 disconnect 函数中 0 可以用作一个通配符,分别表示任何信号、任何接收对象、接收对象中的任何槽函数。但是发射者 sender 不能为 0,其它三个参数的值可以等于 0。


QT QObject::connect函数的用法

从Qobject(QObject.h)源码中可以看到QObject::connect的定义是这样的:

1.     static bool connect(const QObject *sender, const char *signal,  

2.                         const QObject *receiver, const char *member, Qt::ConnectionType =  

3.         #ifdef qdoc  

4.                             Qt::AutoConnection  

5.         #else  

6.             #ifdef QT3_SUPPORT  

7.                                 Qt::AutoCompatConnection  

8.         #else  

9.                                     Qt::AutoConnection  

10.         #endif  

11.      #endif  

12.     );  

13.  inline bool connect(const QObject *sender, const char *signal,  

14.                     const char *member, Qt::ConnectionType type =  

15.      #ifdef qdoc  

16.                      Qt::AutoConnection  

17.      #else  

18.         #ifdef QT3_SUPPORT  

19.                                  Qt::AutoCompatConnection  

20.         #else  

21.                                  Qt::AutoConnection  

22.         #endif  

23.      #endif  

24.     ) const;  

其中第二个connect的实现其实只有一句话:

1.     { return connect(asender, asignal, this, amember, atype); }  

所以对于connect函数的学习其实就是研究第一个connect函数。

我们在使用connect函数的时候一般是这样调用的:

1.     connect(sender,SIGNAL(signal()),receiver,SLOT(slot()));  

这里用到了两个宏:SIGNAL() 和SLOT();通过connect声明可以知道这两个宏最后倒是得到一个const char*类型。
在qobjectdefs.h中可以看到SIGNAL() 和SLOT()的宏定义:

1.     #ifndef QT_NO_DEBUG  

2.     # define QLOCATION "\0"__FILE__":"QTOSTRING(__LINE__)  

3.     # define METHOD(a)   qFlagLocation("0"#a QLOCATION)  

4.     # define SLOT(a)     qFlagLocation("1"#a QLOCATION)  

5.     # define SIGNAL(a)   qFlagLocation("2"#a QLOCATION)  

6.     #else  

7.     # define METHOD(a)   "0"#a  

8.     # define SLOT(a)     "1"#a  

9.     # define SIGNAL(a)   "2"#a  

10. #endif  

所以这两个宏的作用就是把函数名转换为字符串并且在前面加上标识符。

比如:SIGNAL(read())展开后就是"2read()";同理SLOT(read())展开后就是"1read()"。

1.     connect(sender,SIGNAL(signal()),receiver,SLOT(slot()));  

2.     实际上就是connect(sender,“2signal()”,receiver,“1slot())”;  

搞明白了实际的参数就可以来看connect的真正实现过程了,在QObject.cpp文件中可以找到connect的实现代码。

1.     bool QObject::connect(const QObject *sender, const char *signal,  

2.                           const QObject *receiver, const char *method,  

3.                           Qt::ConnectionType type)  

4.     {  

5.         {  

6.             const void *cbdata[] = { sender, signal, receiver, method, &type };  

7.             if (QInternal::activateCallbacks(QInternal::ConnectCallback, (void **) cbdata))  

8.                 return true;  

9.         }  

10.   

11.      if (sender == 0 || receiver == 0 || signal == 0 || method == 0) {  

12.         qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",  

13.                   sender ? sender->metaObject()->className() : "(null)",  

14.                  (signal && *signal) ? signal+1 : "(null)",  

15.                   receiver ? receiver->metaObject()->className() : "(null)",  

16.                  (method && *method) ? method+1 : "(null)");  

17.          return false;  

18.     }  

19.      QByteArray tmp_signal_name;  

20.   

21.      if (!check_signal_macro(sender, signal, "connect""bind"))  

22.         return false;  

23.      const QMetaObject *smeta = sender->metaObject();  

24.     const char *signal_arg = signal;  

25.      ++signal; //skip code  

26.     int signal_index = smeta->indexOfSignal(signal);  

27.      if (signal_index < 0) {  

28.         // check for normalized signatures  

29.          tmp_signal_name = QMetaObject::normalizedSignature(signal - 1);  

30.         signal = tmp_signal_name.constData() + 1;  

31.    

32.         signal_index = smeta->indexOfSignal(signal);  

33.          if (signal_index < 0) {  

34.             err_method_notfound(sender, signal_arg, "connect");  

35.              err_info_about_objects("connect", sender, receiver);  

36.             return false;  

37.          }  

38.     }  

39.    

40.     QByteArray tmp_method_name;  

41.      int membcode = extract_code(method);  

42.   

43.      if (!check_method_code(membcode, receiver, method, "connect"))  

44.         return false;  

45.      const char *method_arg = method;  

46.     ++method; // skip code  

47.    

48.     const QMetaObject *rmeta = receiver->metaObject();  

49.      int method_index = -1;  

50.     switch (membcode) {  

51.      case QSLOT_CODE:  

52.         method_index = rmeta->indexOfSlot(method);  

53.          break;  

54.     case QSIGNAL_CODE:  

55.          method_index = rmeta->indexOfSignal(method);  

56.         break;  

57.      }  

58.     if (method_index < 0) {  

59.          // check for normalized methods  

60.         tmp_method_name = QMetaObject::normalizedSignature(method);  

61.          method = tmp_method_name.constData();  

62.         switch (membcode) {  

63.          case QSLOT_CODE:  

64.             method_index = rmeta->indexOfSlot(method);  

65.              break;  

66.         case QSIGNAL_CODE:  

67.              method_index = rmeta->indexOfSignal(method);  

68.             break;  

69.          }  

70.     }  

71.    

72.     if (method_index < 0) {  

73.          err_method_notfound(receiver, method_arg, "connect");  

74.         err_info_about_objects("connect", sender, receiver);  

75.          return false;  

76.     }  

77.      if (!QMetaObject::checkConnectArgs(signal, method)) {  

78.         qWarning("QObject::connect: Incompatible sender/receiver arguments"  

79.                   "\n        %s::%s --> %s::%s",  

80.                  sender->metaObject()->className(), signal,  

81.                   receiver->metaObject()->className(), method);  

82.         return false;  

83.      }  

84.   

85.      int *types = 0;  

86.     if ((type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)  

87.              && !(types = queuedConnectionTypes(smeta->method(signal_index).parameterTypes())))  

88.         return false;  

89.    

90.     QMetaObject::connect(sender, signal_index, receiver, method_index, type, types);  

91.      const_cast<QObject*>(sender)->connectNotify(signal - 1);  

92.     return true;  

93.  }  


上面是去除了debug代码的connect实现。

 

1.     const void *cbdata[] = { sender, signal, receiver, method, &type };  

2.     if (QInternal::activateCallbacks(QInternal::ConnectCallback, (void **) cbdata))  

3.           return true;  

判断连接是否已经建立。
QInternal::ConnectCallback在qglobal.cpp中实现。

1.     bool QInternal::activateCallbacks(Callback cb, void **parameters)  

2.     {  

3.         Q_ASSERT_X(cb >= 0, "QInternal::activateCallback()""Callback id must be a valid id");  

4.       

5.         QInternal_CallBackTable *cbt = global_callback_table();  

6.         if (cbt && cb < cbt->callbacks.size()) {  

7.             QList<qInternalCallback> callbacks = cbt->callbacks[cb];  

8.             bool ret = false;  

9.             for (int i=0; i<callbacks.size(); ++i)  

10.             ret |= (callbacks.at(i))(parameters);  

11.          return ret;  

12.     }  

13.      return false;  

14. }  

QInternal_CallBackTable 定义为(qglobal.cpp)

1.     struct QInternal_CallBackTable {  

2.         QVector<QList<qInternalCallback> > callbacks;  

3.     };  

qInternalCallback定义为(qnamespace.h)

1.     typedef bool (*qInternalCallback)(void **);这是一个函数指针 返回值是bool,只有一个参数为void**。这个指针在调用registerCallback加入列表。  


 

 

1.     if (!check_signal_macro(sender, signal, "connect""bind"))  

2.         return false;  

判断signal是否合法。

在QObject.cpp文件中可以找到check_signal_macro的实现

1.     static bool check_signal_macro(const QObject *sender, const char *signal,  

2.                                     const char *func, const char *op)  

3.     {  

4.         int sigcode = extract_code(signal);  

5.         if (sigcode != QSIGNAL_CODE) {  

6.             if (sigcode == QSLOT_CODE)  

7.                 qWarning("Object::%s: Attempt to %s non-signal %s::%s",  

8.                          func, op, sender->metaObject()->className(), signal+1);  

9.             else  

10.             qWarning("Object::%s: Use the SIGNAL macro to %s %s::%s",  

11.                       func, op, sender->metaObject()->className(), signal);  

12.         return false;  

13.      }  

14.     return true;  

15.  }  


extract的实现也在QObject中,它就是去字符串第一个字符,并且只取低2位的值。

1.     static int extract_code(const char *member)  

2.     {  

3.         // extract code, ensure QMETHOD_CODE <= code <= QSIGNAL_CODE  

4.         return (((int)(*member) - '0') & 0x3);  

5.     }  


这里又有两个宏:QSIGNAL_CODE 和QSLOT_CODE。它们也是在qobjectdefs.h文件中定义的。

1.     #ifdef QT3_SUPPORT  

2.     #define METHOD_CODE   0                        // member type codes  

3.     #define SLOT_CODE     1  

4.     #define SIGNAL_CODE   2  

5.     #endif  


这个定义与之前的SIGNAL和SLOT的定义是对应的。

 

 

 

1.     const QMetaObject *smeta = sender->metaObject();  

2.     const char *signal_arg = signal;  

3.     ++signal; //skip code  

4.     int signal_index = smeta->indexOfSignal(signal);  

5.     if (signal_index < 0) {  

6.         // check for normalized signatures  

7.         tmp_signal_name = QMetaObject::normalizedSignature(signal - 1);  

8.         signal = tmp_signal_name.constData() + 1;  

9.       

10.     signal_index = smeta->indexOfSignal(signal);  

11.      if (signal_index < 0) {  

12.         err_method_notfound(sender, signal_arg, "connect");  

13.          err_info_about_objects("connect", sender, receiver);  

14.         return false;  

15.      }  

16. }  

获取signal的索引。

metaObject()是在moc_name.cpp文件中生成的。

1.     return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;  

其中staticMetaObject也是在moc文件中定义的

1.     const QMetaObject MainWindow::staticMetaObject = {  

2.         { &QMainWindow::staticMetaObject, qt_meta_stringdata_MainWindow,  

3.           qt_meta_data_MainWindow, 0 }  

4.     };  

qt_meta_stringdata_MainWindow(具体名字和类名有关)就是staticconstchar[]类型。它记录了全部的signals和slots等的函数名、返回值和参数表的信息。

qt_meta_data_MainWindow(具体名字和类名有关)是staticconstuint[]类型。它记录了每一个函数的函数名、返回值和参数表在qt_meta_stringdata_MainWindow中的索引。同时它还记录了每一个函数的类型具体在qmetaobject.cpp文件中定义。

1.     enum MethodFlags  {  

2.         AccessPrivate = 0x00,  

3.         AccessProtected = 0x01,  

4.         AccessPublic = 0x02,  

5.         AccessMask = 0x03, //mask  

6.       

7.         MethodMethod = 0x00,  

8.         MethodSignal = 0x04,  

9.         MethodSlot = 0x08,  

10.     MethodConstructor = 0x0c,  

11.      MethodTypeMask = 0x0c,  

12.   

13.      MethodCompatibility = 0x10,  

14.     MethodCloned = 0x20,  

15.      MethodScriptable = 0x40  

16. };  


indexOfSignal(signal);的实现在qmetaobject.cpp中。其主要作用是利用qt_meta_stringdata_MainWindow 和qt_meta_data_MainWindow查找已经定义了的signal并返回索引。
 

 

 

1.     QByteArray tmp_method_name;  

2.     int membcode = extract_code(method);  

3.       

4.     if (!check_method_code(membcode, receiver, method, "connect"))  

5.         return false;  

6.     const char *method_arg = method;  

7.     ++method; // skip code  

8.       

9.     const QMetaObject *rmeta = receiver->metaObject();  

10. int method_index = -1;  

11.  switch (membcode) {  

12. case QSLOT_CODE:  

13.      method_index = rmeta->indexOfSlot(method);  

14.     break;  

15.  case QSIGNAL_CODE:  

16.     method_index = rmeta->indexOfSignal(method);  

17.      break;  

18. }  

19.  if (method_index < 0) {  

20.     // check for normalized methods  

21.      tmp_method_name = QMetaObject::normalizedSignature(method);  

22.     method = tmp_method_name.constData();  

23.      switch (membcode) {  

24.     case QSLOT_CODE:  

25.          method_index = rmeta->indexOfSlot(method);  

26.         break;  

27.      case QSIGNAL_CODE:  

28.         method_index = rmeta->indexOfSignal(method);  

29.          break;  

30.     }  

31.  }  

32.   

33.  if (method_index < 0) {  

34.     err_method_notfound(receiver, method_arg, "connect");  

35.      err_info_about_objects("connect", sender, receiver);  

36.     return false;  

37.  }  


校验method并且查找它的索引。过程与signal类似。

 

1.     if (!QMetaObject::checkConnectArgs(signal, method)) {  

2.         qWarning("QObject::connect: Incompatible sender/receiver arguments"  

3.                  "\n        %s::%s --> %s::%s",  

4.                  sender->metaObject()->className(), signal,  

5.                  receiver->metaObject()->className(), method);  

6.         return false;  

7.     }  


判断signal和method是否兼容,checkConnectArgs函数的在qmetaObject.cpp文件中实现。这个函数校验了signal和method的参数。当两者的参数一致或method参数比signal参数少(method与signal前几个参数一致)的时候返回true,其它返回false。

 

 

 

1.     int *types = 0;  

2.     if ((type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)  

3.             && !(types = queuedConnectionTypes(smeta->method(signal_index).parameterTypes())))  

4.         return false;  


如果是以发消息的方式执行method就需要对参数类型进行判断。queuedConnectionTypes在QObject.cpp实现。实际上是在QMetatype.cpp中定义了一个

static conststruct { constchar * typeName;int type;} types[];在这里记录了全部类型和名称如({"void",QMetaType::Void});Void在Qmetatype.h中定义。

 

 

1.     QMetaObject::connect(sender, signal_index, receiver, method_index, type, types);  


调用QMetaObject的connect函数,再次不详细写出。

 

1.     const_cast<QObject*>(sender)->connectNotify(signal - 1);  


最后调用虚函数connectNotify表示connect已经执行完成。

 


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

qt中connect函数探究 的相关文章

  • Qt 在信号/槽中使用 boost::shared_ptr

    是否可能 如果可以 如何在 Qt 中创建一个对共享指针常量引用的信号 槽 我想要一个如下所示的信号 void signal shared ptr
  • 警告似乎指向不同的对象地址

    我正在使用 PySide 当我尝试将电子表格设置为某个小部件时收到警告 09 18 14 48 54 107 WARNING D 0x7ff4a0074650 qt Could not parse stylesheet of widget
  • Qml中的QScrollArea:Flickable + QQuickPaintedItem

    我正在尝试实现类似的东西QScrollArea 在小部件世界中 在 Qml 的帮助下 我决定一探究竟Flickable plus QQuickPaintedItem基于项目 在我的例子中名为抽屉 Flickable onContentXCh
  • 我如何在另一个线程Qt中显示MessageBox

    这是我的代码 int main int argc char argv QApplication a argc argv testApp w w show TestClass test new TestClass QObject connec
  • QSignal Manager - 无法将多个信号连接到一个插槽

    我有 4 个 QLineEdits 和 4 个 QPushButtons 如果我单击 QPushButton 我想在相应的 QLineEdit 内设置一些文本 我想使用QSignalMapper来区分每个QButton及其对应的QLineE
  • 设置 ItemIsMovable 标志时,子项在 QGraphicsView 中不可移动

    要调整项目中的项目QGraphicsView http qt project org doc qt 5 0 qtwidgets qgraphicsview html 我将表示顶点的子项放到要移动的项上 使用构造函数中建立的父子关系 就是下图
  • 当鼠标位于 Qt 窗口的自定义小部件上时,如何移动整个窗口?

    假设我有一个自定义小部件并将其添加到 qt 的主窗口中 如您所见 红色区域是自定义小部件 我想要做的是 当鼠标在红色区域按下并移动时 整个窗口也会移动 我知道如何简单地实施mousePressEvent and mouseMoveEvent
  • Ncurses 和 Qt 互操作性

    拥有基于 Qt 和 ncurses 的应用程序 在等待用户输入时每秒刷新屏幕的最佳方法是什么 例如显示时钟并获取用户输入 我需要 CPU 使用率和应用程序响应能力之间的最佳折衷 更具体地说 如何获取用户输入并仍然使用QTimer以及信号槽机
  • Qt Ui 命名空间

    命名空间有什么意义Ui这是Qt自动生成的吗 这两个命名空间相同吗 在第一个中 其中包含 MainWindow 类的前向声明ui MainWindow h为什么它没有声明为class Ui MainWindow 编译器如何知道 MainWin
  • 如何以编程方式在 qml 中渲染 vtk 项目?

    到目前为止 我了解到我们在 QML 中有两个线程 我们的主应用程序线程和我们的 场景图 线程 http doc qt io qt 5 qtquick visualcanvas scenegraph html http doc qt io q
  • 如何使用 PyQt5 在 QWidget 上设置 numpy 数组图像

    我正在将相机中的图像作为 numpy 数组读取 我的目标是将其放入 pyqt5 的 Qwidget 中并在我的 mainwindow gui 程序上打印 但我收到以下错误 TypeError QPixmap argument 1 has u
  • 故障转储分析:CxxUnhandledExceptionFilter

    我有一个崩溃小型转储需要分析 我的程序是多线程Qt5应用程序 我不是调试专家 但通常我可以轻松找到程序失败的地方 但这次我不能 我在 Visual Studio 2010 中打开转储文件 单击 仅使用本机调试 它向我显示问题所在 它是位置为
  • 如何使用 qt 在键盘上仅显示数字

    我在我的项目中使用 Qt Quick Virtual Keyboard 当我单击一个对象时 我想显示键盘但只显示数字 我怎样才能做到这一点 这就是我想做的 您可以使用Qt ImhFormattedNumbersOnly http doc q
  • 如何在子进程期间和之后执行操作

    我有一个调用子程序的程序 当子程序使用 Popen 运行时 我需要禁用运行按钮并启用停止按钮 但是 由于Popen打开了一个新进程 因此程序完成后应该打印的内容会立即打印出来 我尝试添加self p communicate after Po
  • 如何在 QML 中使用 Font Awesome

    有谁知道如何在 QML 中使用 Font Awesome 吗 我找不到任何文档或任何信息如何在 QML 中使用 Font Awesome 我喜欢做的是使用fontello http fontello com 创建最小的图标集 而不是从 Fo
  • QSpinBox 具有用于十六进制输入的 Unsigned Int

    这里写了很多关于 QSpinBox 使用 int 作为其数据类型的限制的问题 人们通常希望显示更大的数字 就我而言 我希望能够以十六进制显示无符号 32 位整数 这意味着我希望我的范围为 0x0 0xFFFFFFFF 正常的 QSpinBo
  • 使用Qt设置http get请求参数

    我正在 Qt 中开发一个基本应用程序 它使用 REST API 从 Parse com 检索数据 我浏览了一些类参考和 cURL 手册 但仍然不清楚如何设置请求参数 例如 我想对用户进行身份验证 这是 Parse 提供的curl 示例 cu
  • 如何在QLineEdit/QLabel等中从左到右显示阿拉伯符号?

    在Qt的实现中阿拉伯符号显示在右到左方向 因此任何包含阿拉伯符号的字符串都将右对齐 但我的应用程序想要做的是显示所有文本左到右方向 无论是否包含阿拉伯符号 所有文本都是左对齐的 一个例子如下所示 This is 我想实现什么 就是这样QLi
  • 纹理openGl。 C++、qt

    我试图用草纹理覆盖我的地形 由高度图制成 但它没有按预期工作 我什至无法在简单的 GL QUAD 上获取纹理 结果是多色网络 void GLWidget initializeGL glEnable GL TEXTURE 2D 在 QGLwi
  • 由于 QCoreApplication 事件循环,QThread 永远不会退出

    Problem 所以我有一个 CommandRetriever 类来保存一些命令 并且should在不同的线程上执行这些命令 class CommandRetriever public CommandRetriever CommandRet

随机推荐

  • Spring(DI)

    DI Dependency Injection 即依赖注入 对象之间的依赖由容器在运行期决定 即容器动态的将某个依赖注入到对象自重 基于XML配置注入依赖 有参构造函数注入依赖 bean类实现有参构造函数 public class Stud
  • 开始在CSDN上安家了哈!

    2014年计划完成50 原创blog 这是我的目标
  • vue项目打包部署到tomcat(详细)

    hash路由模式打包部署到tomcat 1 修改config index js文件下的assetsPublicPath为 2 修改router文件夹下index js添加 base 文件夹名称 例如 yuncheng 可以自己随意设置 3
  • 未找到 van-toast 节点,请确认 selector 及 context 是否正确

    1 json文件引入 van toast vant weapp toast index 2 js文件引入 import Toast from vant weapp toast toast 3 wxml写入
  • 微信小程序蓝牙BLE开发实战——遇到问题及踩坑(三)

    微信小程序蓝牙BLE开发实战 三 对于我这种小白 遇到问题是常见的哈 这里记录下 避免日后再踩坑 文章目录 微信小程序蓝牙BLE开发实战 三 1 iPhone6及6plus无法搜索到设备 解决方案 2 IOS无法获取 mac 地址 如何连接
  • 分布式任务调度平台xxl-job

    一 java的集中式任务调度 while true Thread sleep 轮询 线程休眠的方式实现定时任务 java util Timer java util TimerTask Timer是一种定时器工具 用于使用后台线程计划执行指定
  • 数字IC设计流程学习笔记

    一 规格定制 IC的规格定制包括物理指标 性能指标和功能指标 物理指标 封装 工艺 芯片面积 性能指标 功耗 速度 功能指标 接口 芯片功能 二 系统设计 系统设计是确定IC的算法模型和系统架构等 并通过一些高级语言 matlab等对算法模
  • 【tensorflow基础】读取mnist数据

    转载于 MNIST手写数字数据集读取方法 TensorFlow的封装让使用MNIST数据集变得更加方便 MNIST数据集是NIST数据集的一个子集 它包含了60000张图片作为训练数据 10000张图片作为测试数据 在MNIST数据集中的每
  • spring-security

    文章目录 csrf remember me 密码存储 权限继承 应 要求添加的代码 白名单相关说明 csrf A网站登录 B网站 使用 Copyright C
  • 传染病模型(4)——SIRS模型和SIER模型及matlab具体程序

    前言 常见的传染病模型按照具体的传染病的特点可分为 SI SIS SIR SIRS SEIR 模型 其中 S E I R 的现实含义如下 S Susceptible 易感者 指缺乏免疫能力健康人 与感染者接触后容易受到感染 E Expose
  • 一文了解亚马逊云科技适用于 Amazon Lightsail 的托管数据库

    Amazon Lightsail 是亚马逊云科技提供的一种易上手使用 月度价格经济实惠 并包括了计算实例 容器 存储 数据库的虚拟专用服务器 在创建时可以进行业务蓝图选择 可选择包含多种操作系统 Linux Windows 等 或操作系统加
  • C++中定义常量的几种方式

    概述 在程序运行过程中 始终不发生改变的量 称之为常量 在 C 语言中常量是个固定值 也就是说常量值在定义后不能进行修改 define 宏常量 define 是 C 语言中定义常量的方式 在 C 中也可以使用 define 的使用 defi
  • RocketMQ安装与启动

    分享知识 传递快乐 官网 https rocketmq apache org 1 准备环境 系统 Centos7 jdk 1 8 2 环境部署 解压 rocketmq 并进入 rocketmq 下的 bin 目录 调整启动内存 vim bi
  • C++ 函数模板

    函数模板是通用的函数描述 它们使用泛型来定义函数 其中的泛型可用具体的类型替换 通过将类型作为参数传递给模板 可使编译器生成该类型的函数 由于模板允许以泛型 而不是具体类型 的方式编写程序 因此有时候也被称为通用编程 在标准C 98添加关键
  • ubuntu14.04安装wireshakes

    网络攻防 这课要做一个嗅探器的大作业 想在linux是实现 于是先在ubuntu上下一个wiresharks看看它的一些功能和 废话少说 直接上安装过程与期间遇到的问题 安装编译工具 sudo apt get install build e
  • Spring Gateway集成 Nacos注册中心不能够发现服务的问题解决

    一 问题描述 我们现在是在用Nacos替换Eureka 原来Eureka和Spring gateway运行正常 可以通过Spring gateway调用注册到Eureka中的服务 当前Spring cloud的版本是Hoxton SR8 N
  • 顺序表基本操作

    文章目录 1 顺序表插入元素 2 顺序表删除元素 3 顺序表查找元素 4 顺序表更改元素 1 顺序表插入元素 向顺序表中插入数据元素 根据插入位置的不同 可分为以下 3 种情况 插入到顺序表的表头 在表的中间位置插入元素 尾随顺序表中已有元
  • TCP/IP详解 卷1:协议 学习笔记 第十七章 TCP:传输控制协议

    TCP提供一种面向连接的 可靠的字节流服务 面向连接意味着两个使用TCP的应用 通常是一个客户一个服务器 在彼此交换数据前必须先建立一个TCP连接 在一个TCP连接中 仅有两方进行彼此通信 广播和多播不能用于TCP TCP提供可靠性的方法
  • Unity3D Animation、Animator和AnimationClip

    文章目录 Animation 字段 方法 Animator 字段 方法 AnimationClip 字段 方法 Animation 单一动画 一般使用在单一动画播放 占用资源小 字段 名称 作用 animatePhysics 如果打开这个选
  • qt中connect函数探究

    综合了一下网上资源 整理得出 QT 是一个跨平台的 C GUI 应用构架 它提供了丰富的窗口部件集 具有面向对象 易于扩展 真正的组件编程等特点 更为引人注目的是目前 Linux 上最为流行的 KDE 桌面环境就是建立在 QT 库的基础之上