Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
专用变量的Qt信号槽处理:特征还是缺陷? 我用QT库工作了相当长的C++代码(超过70K行),在处理私有变量时遇到了信号槽机制的意外(对于我)的行为。_C++_Qt_Signals Slots_Private Members - Fatal编程技术网

专用变量的Qt信号槽处理:特征还是缺陷? 我用QT库工作了相当长的C++代码(超过70K行),在处理私有变量时遇到了信号槽机制的意外(对于我)的行为。

专用变量的Qt信号槽处理:特征还是缺陷? 我用QT库工作了相当长的C++代码(超过70K行),在处理私有变量时遇到了信号槽机制的意外(对于我)的行为。,c++,qt,signals-slots,private-members,C++,Qt,Signals Slots,Private Members,其思想是,当一个对象(object1)与另一个对象(object2)进行通信时,该对象(object2)可以通过包含前者的私有变量(object1的vec1)的信号对其进行修改。我想知道这是一个特性还是一个缺陷 我在这里放了一个简化的代码来说明这一事实:object1有一个名为vec1(指针)的私有QVector变量,并向object2发送一个信号以删除vec1的一些元素。此object2捕获信号并成功执行任务 #include "mainwindow.h" #include

其思想是,当一个对象(object1)与另一个对象(object2)进行通信时,该对象(object2)可以通过包含前者的私有变量(object1的vec1)的信号对其进行修改。我想知道这是一个特性还是一个缺陷

我在这里放了一个简化的代码来说明这一事实:object1有一个名为vec1(指针)的私有QVector变量,并向object2发送一个信号以删除vec1的一些元素。此object2捕获信号并成功执行任务

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow mainWin;
    mainWin.show();
    return a.exec();
}
#包括“mainwindow.h”
#包括
int main(int argc,char*argv[])
{
质量保证申请a(argc、argv);
mainWin;
mainWin.show();
返回a.exec();
}
主窗口

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLabel>
#include <QVBoxLayout>
#include "object1.h"
#include "object2.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
};
#endif // MAINWINDOW_H
\ifndef主窗口
#定义主窗口
#包括
#包括
#包括
#包括“object1.h”
#包括“object2.h”
类主窗口:公共QMainWindow
{
Q_对象
公众:
主窗口(QWidget*parent=nullptr);
~main窗口();
};
#endif//main窗口
mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{    
    QVector<int> * vec;
    object1 *obj1 = new object1();
    object2 *obj2 = new object2();

    connect(obj1, SIGNAL(remove_items_signal1(QVector<int>*,int)),
        obj2, SLOT(remove_items_slot2(QVector<int>*,int)));

    vec = obj1->get_vec1();

    QString str1("vec1 before removing any elements = ");
    for (int i = 0 ; i < vec->length(); i++){
        str1.append(QString(" %1").arg(vec->at(i)));
    }
    QLabel *label1 = new QLabel(str1);

    // remove some elements at the end of the vector using the signal-slot mechanism
    // Notice that the elements of vec1 (which is private of object1) 
    // are removed in object2.

    int i = 3;

    obj1->emit_remove_items(i);

    vec = obj1->get_vec1();

    QString str2("vec1 after removing the last " + QString("%1").arg(i) + " elements in object2 = ");
    for (int i = 0 ; i < vec->length(); i++){
        str2.append(QString(" %1").arg(vec->at(i)));
    }
    QLabel *label2 = new QLabel(str2);

    QVBoxLayout *layout = new QVBoxLayout();
    layout->addWidget(label1);
    layout->addWidget(label2);

    QWidget *window = new QWidget();
    window->setLayout(layout);

    setCentralWidget(window);

}

MainWindow::~MainWindow()
{
}
#包括“mainwindow.h”
主窗口::主窗口(QWidget*父窗口)
:QMainWindow(父级)
{    
QVector*vec;
object1*obj1=new object1();
object2*obj2=new object2();
连接(obj1,信号(移除项目信号1(QVector*,int)),
obj2,插槽(删除项目插槽2(QVector*,int));
vec=obj1->get_vec1();
QString str1(“删除任何元素之前的vec1=”);
对于(int i=0;ilength();i++){
str1.append(QString(“%1”).arg(vec->at(i));
}
QLabel*label1=新的QLabel(str1);
//使用信号槽机制移除向量末尾的一些元素
//请注意,vec1的元素(它是object1的私有元素)
//在object2中删除。
int i=3;
obj1->发射和移除项目(i);
vec=obj1->get_vec1();
QString str2(“删除object2=“”)中最后一个“+QString(“%1”).arg(i)+”元素后的vec1”;
对于(int i=0;ilength();i++){
str2.append(QString(“%1”).arg(vec->at(i));
}
QLabel*label2=新的QLabel(str2);
QVBoxLayout*布局=新的QVBoxLayout();
布局->添加小部件(标签1);
布局->添加小部件(label2);
QWidget*窗口=新的QWidget();
窗口->设置布局(布局);
setCentralWidget(窗口);
}
MainWindow::~MainWindow()
{
}
目标1.h

#ifndef OBJECT1_H
#define OBJECT1_H

#include <QWidget>
#include <QVector>

class object1 : public QWidget
{
    Q_OBJECT
public:
    explicit object1(QWidget *parent = 0);
    ~object1();
    void emit_remove_items(int);
    QVector<int> * get_vec1();
signals:
    void remove_items_signal1(QVector<int> *, int);
private:
    QVector<int> *vec1;
};
#endif // OBJECT1_H
\ifndef OBJECT1\u H
#定义对象1_H
#包括
#包括
类object1:公共QWidget
{
Q_对象
公众:
显式object1(QWidget*parent=0);
~object1();
无效发射和移除项目(int);
QVector*get_vec1();
信号:
无效删除项目信号1(QVector*,int);
私人:
QVector*vec1;
};
#endif//OBJECT1_H
object1.cpp

#include "object1.h"

object1::object1(QWidget *parent) : QWidget(parent)
{
    vec1 = new QVector<int>();
    *vec1 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9;
}

object1::~object1(){

}

void object1::emit_remove_items(int i){
    emit remove_items_signal1(vec1, i);
}

QVector<int>* object1::get_vec1(){
    return vec1;
}
#包括“object1.h”
object1::object1(QWidget*parent):QWidget(parent)
{
vec1=新的QVector();

*vec1从信号/插槽正在做一些奇怪的事情的意义上来说,这并不奇怪。您的成员函数
object1::emit\u remove\u items
将对私有成员
vec1
的引用传递给信号
remove\u items\u signal1
(这只是另一个函数)。将此信号连接到插槽会使信号实现调用该插槽(这只是另一个函数)

不过,您对信号/插槽模式的使用有点奇怪,因为您将
object1
的私有部分泄露给了
object2
,正如您所注意到的,这破坏了封装

良好做法是确保:

  • 函数名反映函数的功能,而不是在首次编写函数时如何使用它们
  • 信号是被动命名的,例如,
    somethingChanged
    somethingEnded
  • 插槽或所有函数都是主动命名的,例如
    doSomething
    endSomething
  • 应用这些指导原则,然后修改代码以满足这些要求,甚至可能会使奇怪的私有指针传递部分消失。
    如果没有,你需要重新思考你到底想完成什么。

    正如@rubenvb所说:这不是特定于信号/插槽的,如果你通过引用/指针将一个对象传递给另一个函数,该函数可以修改它。如果你不想这样做,就不要将它传递给函数/信号。在你的例子中,你通过指针访问容器,只是不需要'不要这样做。改为通过常量引用传递它们。(它们是隐式共享的,因此副本很便宜)
    #ifndef OBJECT2_H
    #define OBJECT2_H
    
    #include <QWidget>
    #include <QVector>
    
    class object2 : public QWidget
    {
        Q_OBJECT
    public:
        explicit object2(QWidget *parent = 0);
        ~object2();
    public slots:
        void remove_items_slot2(QVector<int> *, int);
    private:
        QVector<int> *vec2;
    };
    #endif // OBJECT2_H
    
    #include "object2.h"
    
    object2::object2(QWidget *parent) : QWidget(parent)
    {
       vec2 = new QVector<int>();
    }
    
    object2::~object2(){
    
    }
    
    void object2::remove_items_slot2(QVector<int> * vec1, int i){
        vec2 = vec1;
        if (i < vec2->length()){
            int j = vec2->length()-i;
            vec2->remove(j,i);
        }
    }