Programación Qt (2) -Avance inicial

Prefacio

  • A través del artículo anterior, tenemos una comprensión preliminar de Qt, Programación Qt (1) -Comprensión
  • Aquí comenzamos a estudiar Qt en profundidad. Como sabemos antes, lo importante en Qt son las señales y las ranuras, que están conectadas a través de la función connect (). Aquí echamos un vistazo más de cerca a las señales y las tragamonedas.

1. Señales y ranuras personalizadas de Qt

1. Señales y tragamonedas personalizadas

  • 1. Primero, necesita crear dos clases, una clase de señal y una clase de función de ranura. Haga clic derecho en el proyecto->Agregar nuevo y cree una nueva clase.
    Insertar descripción de la imagen aquí
  • 2. Establezca los atributos de la clase: nombre de clase, clase principal, ubicación.
    Insertar descripción de la imagen aquí
    En la función de ranura declarada, haga clic derecho en el nombre de la función, seleccione Refactor->Agregar definición en el archivo .cpp.
    Clase de señal personalizada:
    agregue una declaración de señal en el archivo de encabezado de ZMSignals., no es necesario implementar
    Insertar descripción de la imagen aquí
    una clase de función de ranura personalizada:
    agregue la definición e implementación de la función de ranura personalizada en el archivo de encabezado y el archivo fuente de la clase ZMSlots.
    Insertar descripción de la imagen aquí

Insertar descripción de la imagen aquí

  • 3. Conecte señales y ranuras.
    Las señales y las ranuras deben conectarse a través de una ventana, por ejemplo: widget, ventana, etc.
//emit是发送信号的标识,不写会报警告,版本问题,(非必须)
 emit zmSignal.zm_sig_start();

Insertar descripción de la imagen aquí

2. Problema de sobrecarga de parámetros de banda de señal personalizada

  • 1. Agregue funciones de ranura y señal sobrecargadas
    Insertar descripción de la imagen aquí
    Insertar descripción de la imagen aquí
  • 2. Se descubrió que se informó un error al conectarse, debido a que había ambigüedad en la función de sobrecarga de contexto al conectarse.
    Insertar descripción de la imagen aquí
  • 3. Podemos usar un puntero de función con parámetros para señalar la función que queremos señalar para eliminar la ambigüedad. Personalmente recomiendo el primero de los dos métodos siguientes.
#if 1 //两个方式一样,只是指针函数开放与不开放的问题
    //方法一:

    //设置两个带参数的函数指针
    void (ZMSignals::*str_sig_start)(QString) = &ZMSignals::zm_sig_start;
    void (ZMSlots::*str_slot_accept)(QString) = &ZMSlots::zm_slot_accept;

    //关联带参数的函数指针
    w.connect(&zmSignal, str_sig_start, &zmSlot, str_slot_accept);
#else
    //方法二:强制转换型,代码可读性低
    w.connect(&zmSignal, ( void (ZMSignals::*)(QString)) &ZMSignals::zm_sig_start, &zmSlot, (void (ZMSlots::*)(QString)) &ZMSlots::zm_slot_accept);
#endif

Insertar descripción de la imagen aquí

3. Resumen de problemas de sobrecarga de funciones

  • Preste atención a qué función apunta el puntero de la función sobrecargada de señal. Al conectar la señal de la función sobrecargada, debe indicar qué función de ranura está conectada.

4. Ampliación de señales y slots

1. Conexión de señal:

  • Activamos una señal haciendo clic en un botón y luego activamos la función de ranura correspondiente a la señal a través de la conexión entre la señal y la ranura. Es decir: las señales conectan señales. Una señal de mensaje se puede vincular a múltiples ranuras. De manera similar, una función de ranura también se puede vincular a múltiples señales de mensajes. ( Relación de muchos a muchos )
    , por ejemplo: activar un clic en un botón activa simultáneamente la ejecución de la función de ranura correspondiente a ZMSlots y activa la función de cierre de ranura correspondiente a MainWindow.
    Insertar descripción de la imagen aquí

2. Desconexión de señal:

  • La conexión se puede desconectar mediante la función de desconexión, que se utiliza de la misma manera que la conexión de señal.
  • desconectar (emisor de señal, señal, receptor de señal, función de ranura);
    Insertar descripción de la imagen aquí

3. Parámetros de señales y slots.

  • Lo que envía la señal es lo que recibe la función de ranura y los tipos deben ser consistentes.
  • El número de parámetros de la señal puede ser mayor que el número de parámetros de la función de ranura, pero los tipos de parámetros del mismo número de parámetros deben corresponder uno a uno. Lo contrario no es posible.

2. función lambda

  • Para resolver el problema de la transmisión y conexión de varias señales en el proyecto, en proyectos grandes, el uso excesivo de la conexión y transmisión de señales reducirá la legibilidad del proyecto y aumentará el costo de familiaridad.

1. Comprender las funciones Lambda

  • La función Lambda, también llamada expresión Lambda, es una función anónima (función sin nombre), que es diferente de las funciones tradicionales.
  • Las expresiones Lambda son un concepto introducido después de C++ 11 y se utilizan para definir y crear objetos de funciones anónimos.

2. Estructura de expresión lambda:

[Lista de captura] (parámetro) mutable-> tipo de retorno {cuerpo de función},
por ejemplo:

[](){
    
    
	qDebug("Hello Qt");
}
  • [], identifica el comienzo de una función anónima Lambda. Esto debe estar presente y no se puede omitir. El parámetro del objeto de función se pasa al constructor de la clase de objeto de función generada automáticamente por el compilador. Los parámetros del objeto de función solo pueden usar variables locales visibles en el ámbito donde se define Lambda, incluido el de la clase donde se encuentra Lambda.
  • [] Los parámetros correspondientes en el objeto de función de corchete tienen las siguientes formas:
    • Vacío , no se utilizan parámetros de objeto de función
    • = , el cuerpo de la función utiliza variables locales visibles en el alcance de Lambda, incluido el método de paso de valores de this de la clase, lo que equivale a que el compilador proporcione todas las variables locales en el alcance de Lambda**Asignación**Una copia para la función Lambda
    • & , el cuerpo de la función utiliza variables locales visibles en el alcance de Lambda, incluido el método de referencia de this de la clase, lo que equivale a que el compilador proporcione todas las variables locales en el alcance de Lambda**Cita**Una copia para la función Lambda
    • esto, la variable miembro dentro de Lambda se puede usar en el cuerpo de la función
    • a , no es una letra, pero se refiere a una variable a específica, copie una variable a en Lambda y úsela
    • &a , variable de referencia a en Lambda
    • a, &b , copia a, referencia b
    • =, &a, &b , excepto las referencias a y b, se copian otras variables.
    • &,a,b , excepto para las copias de a y b, se hace referencia a otras variables.
  • mutable: la marca se puede cambiar

3. ¿Por qué utilizar la función Lambda?

  • Algunas funciones sólo se utilizan temporalmente y su lógica de negocio es muy simple, por lo que no es necesario darles nombres. Algunas operaciones también se pueden simplificar en Qt.

4. Instancia lambda

Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí

3. Extensión de la función Lambda

1. Valor de retorno de Lambda

Insertar descripción de la imagen aquí

El programa puede generar el resultado normalmente: 40;

  • punto importante:
    • -> es un signo con un valor de retorno, int es el tipo de valor de retorno y se devuelve directamente en la función.
    • El último () es para llamar a la función. Sin (), no es una llamada a función. La función aquí se puede llamar directamente después de ser definida.

Expresión lambda, realizando números de Fibonacci.

    //斐波那契数:Fibonacci数
    int a=0, b=1;
    [](int& a,int& b, int count){
    
    
        int ret = 0;
        for (int i =0; i<count; i++) {
    
    
            ret = a+b;
            a=b,b=ret;
            qDebug()<<ret;
        }
    }(a, b, 10);//函数调用时,传a,b进到Lambda表达式里

resultado de la operación:
Insertar descripción de la imagen aquí

2. Aplicación de Lambda

  • Una señal sin parámetros llama a una función de ranura con parámetros. En este momento, se utiliza Lambda para
    Insertar descripción de la imagen aquí
    implementar el análisis principal: debido a que el clic del botón no tiene parámetros, la función anónima tampoco tiene parámetros, pero se llama a una señal con parámetros en el modo anónimo. función.

3. QString para char*

  • Porque QDebug incluirá las comillas dobles de QString al imprimir.
    Insertar descripción de la imagen aquí
  • Entre algunos métodos públicos de la clase QString, existe un método toUtf8, que devuelve un QByteArray y primero se convierte en una matriz de bytes. Luego hay un método de datos, que llama al método de datos y luego convierte la matriz en char*
    Insertar descripción de la imagen aquí

4. Significado de Lambda

  • 1.Hacer que el código sea más conciso y eficiente
  • 2. Si se conecta, el receptor de la señal es este, esto se puede omitir.
  connect(btn, &QPushButton::clicked,[=](){
    
     //信号接收者为this,可以省略不写
        this->close();
    });//发送信号

Insertar descripción de la imagen aquí

4. Controles de uso común

1. control QTextEdit

  • QTextEdit: cuadro de edición de texto,
    Insertar descripción de la imagen aquí
  • Ejemplo:
    Insertar descripción de la imagen aquí

2, QVentana principal

  • QMainWindow es la clase de ventana principal que proporciona una interfaz para los usuarios, que incluye una barra de menú (barra de menú), múltiples barras de herramientas (barra de herramientas), múltiples componentes remachados (ventanas flotantes de Dockwidgets), una barra de estado (estado) y un widget central (centralwidget). , es la base de la aplicación, por ejemplo: editor de texto, editor de imágenes, etc.
    Insertar descripción de la imagen aquí

3. Barra de menú (QMenuBar)

  • Solo hay una barra de menú y el método de configuración es: setMenuBar
    Insertar descripción de la imagen aquí

4. Agregar barra de herramientas (QToolbar)

  • La barra de herramientas se puede arrastrar a voluntad y se puede colocar en el lado izquierdo, superior, inferior o derecho del software, o incluso flotar en la interfaz de la aplicación.
  • La diferencia entre una barra de herramientas y una barra de menú : solo puede haber una barra de menú, y está en la parte superior; mientras que puede haber múltiples barras de herramientas, y sus posiciones son diversas. Entonces el método de configuración es addToolBar
    Insertar descripción de la imagen aquí

5. Agregar barra de estado (QStatusBar)

  • Solo se puede agregar una barra de estado, por lo que el método de configuración es setStatusBar.
    Insertar descripción de la imagen aquí

  • Agregar barra de estado,Debido a las diferencias en los sistemas y cuando el número de caracteres chinos y símbolos chinos es impar, es posible que aparezcan caracteres confusos.

    • Solución 1: restablezca las reglas de codificación en el editor y agregue todos los caracteres chinos delante de ellasu8, eso es todo
      Insertar descripción de la imagen aquí
      Insertar descripción de la imagen aquí

    • Solución 2: utilice el método QStringLiteral(), porque se implementa internamente mediante expresiones Lambda y las llamadas de alta frecuencia afectan el rendimiento.
      Insertar descripción de la imagen aquí

6. Remachado de componentes y componentes centrales (QDockWidget, centralWidget)

1. Componentes remachados (dockWidget)

-Los componentes remachados, los componentes centrales y las ventanas flotantes tienen el mismo significado. Al consultar la documentación de Qt Assistant, vemos que QDockWidget se basa en QWidget.Puede haber varias ventanas flotantes, así que agregueDockWidget:
Insertar descripción de la imagen aquí

  • Cuando hay un componente remachado, flotará cuando se arrastre hacia el medio y el lugar de acoplamiento predeterminado es un poco extraño. Esto se debe a que en QMainWindow no hemos agregado el widget central. El widget central predeterminado está vacío, por lo que está directamente en la parte superior.
    Insertar descripción de la imagen aquí
  • Para la configuración de piezas remachadas, consulte la documentación del asistente Qt, que es la misma que la barra de herramientas.

2. Widget central

  • En QMainWindow, hay un componente central, pero este componente central no es un componente central específico, sino que podemos establecer un componente específico como componente central.Sólo puede haber un widget central, por lo que setCentralWidget
    Insertar descripción de la imagen aquí
    Insertar descripción de la imagen aquí

5. Ingeniería e interfaz de usuario

1. diseñador de interfaz de usuario

  • Habrá un archivo .ui en cada proyecto, que en realidad es un archivo de interfaz Qt. Cuando se abre el archivo, el diseñador Qt ui se inicia automáticamente. Los controles de edición en este diseñador serán mucho más convenientes e intuitivos, y mejorarán enormemente el desarrollo. eficiencia.
    Insertar descripción de la imagen aquí
    Insertar descripción de la imagen aquí
  • Después de agregar una vista de tabla
    Insertar descripción de la imagen aquí
    Insertar descripción de la imagen aquí
    y configurar una nueva acción, arrastre la acción directamente a la posición correspondiente.
  • Preste más atención al uso de la configuración de propiedades, el uso de señales y ranuras y el uso de la configuración de propiedades del botón derecho.

2. Agregue archivos de recursos Qt

  • Hay dos formas de agregar recursos: agregar código fuente y agregar usando el diseñador de UI. Por ejemplo: un objeto QAction, agregarle un ícono o establecer un ícono. Puede agregar varios representantes. En términos generales, una herramienta o una pestaña. es un ícono, por lo tanto, debemos configurar el ícono, es decir, configurar el ícono, luego el método se configura al principio, setIcon

1. Cómo agregar código fuente

  • Agregar imágenes al código fuente se limita a las rutas. El uso de rutas relativas requiere algunas configuraciones y, una vez que se modifica la ruta, es posible que las imágenes no se carguen.
    Insertar descripción de la imagen aquí

2. Cómo agregar un diseñador de UI

  • Para agregar un requisito previo, debe crear un archivo de recursos, hacer clic con el botón derecho en el proyecto->agregar nuevo->Qt->archivo de recursos Qt, crear un nuevo archivo de recursos del proyecto y luego colocar los recursos de la imagen en él.
    Insertar descripción de la imagen aquí
  • Después de crear el archivo de recursos, configure el prefijo y agregue recursos de imagen. Recuerde guardar después de agregar los recursos.
    Insertar descripción de la imagen aquí
    Insertar descripción de la imagen aquí
  • Después de guardar los recursos agregados en el paso anterior, abra el diseñador de interfaz de usuario y agregue un ícono a la opción "Guardar".
    Insertar descripción de la imagen aquí
    Insertar descripción de la imagen aquí
  • Después de seleccionar el ícono, podrá verlo directamente en el diseñador de interfaz de usuario.
    Insertar descripción de la imagen aquí
  • Después de agregar el archivo de recursos, también podemos usar código para acceder al archivo de recursos.
    Insertar descripción de la imagen aquí
    Al construir QIcon, necesitamos ": + nombre de prefijo + ruta de recurso"

3. Cuadro de diálogo: modal y no modal

  • En las interfaces gráficas de usuario, los cuadros de diálogo son vistas distintivas que se utilizan para mostrar información al usuario u obtener respuestas de entrada del usuario cuando sea necesario. constituye la interacción persona-computadora.
  • Los cuadros de diálogo estándar son una serie de herramientas de diálogo integradas en Qt para simplificar el desarrollo.
  • Los cuadros de diálogo integrados de Qt incluyen:
    • QColorDialog seleccionar cuadro de diálogo de color
    • QFileDialog selecciona un archivo o directorio
    • QFontDialog seleccione fuente
    • QInputDialog permite al usuario ingresar valores y los devuelve
    • MessageBoxDialog cuadro de diálogo modal, utilizado para mostrar información, consulta o aviso, etc.
    • etc.
  • Modal: la interacción del usuario está bloqueada en el cuadro de diálogo actual
  • No modal: el usuario puede salir del cuadro de diálogo actual e interactuar en otros cuadros de diálogo.

1, cuadro de diálogo Q

Insertar descripción de la imagen aquí

  • La función principal de entrada de Qt devuelve un exec, que mantiene mostrada la ventana principal de Qt. En ese momento, hay un bucle infinito en exec. Espera mensajes de control hasta que recibe el mensaje de cierre y luego sale de la ventana. De lo contrario, continúa en bucle. Bloqueado en el mensaje, por lo que la ventana original no puede continuar ejecutándose.
  • Tenga en cuenta el problema del alcance de la expresión lambda (pila)
    Insertar descripción de la imagen aquí
  • Preste atención a los peligros ocultos de las pérdidas de memoria y agregue métodos para eliminar componentes.
    Insertar descripción de la imagen aquí

2, QMessageBox

  • 1. Conozca
    • QMessageBox es un cuadro de diálogo modal , que se utiliza principalmente en aplicaciones para proporcionar información de visualización, consultas emergentes, advertencias, etc. Por ejemplo: cuando editamos texto en el Bloc de notas y hacemos clic en Cerrar si no está guardado, la aplicación mostrará un cuadro de diálogo QMessageBox para preguntar si desea guardar el texto.
    • QMessageBox es un cuadro de diálogo basado en la clase QDialog
      Insertar descripción de la imagen aquí
  • 2. uso
    Insertar descripción de la imagen aquí
    • Ejemplo:
      QMessageBox::information(this, "preguntar", "¿qué estás haciendo?"); información, pregunta, advertencia y cerámica son funciones estáticas y tienen sus propios controles de memoria, por lo que se pueden llamar directamente mediante clases. . Ya no es necesario crearlo en el montón.
      Insertar descripción de la imagen aquí
    • Preste atención al tipo de retorno de las funciones miembro estáticas y cómo llamarlas
    • El significado de los parámetros.
      Insertar descripción de la imagen aquí
    • Parte del código fuente:
 connect(ui->pb02, &QPushButton::clicked, [=](){
    
    
        //在堆中创建msg,需要控制释放,但对于模态来说,会阻塞函数不能结束,如果用户触发结束后,自动跟随函数释放内存。因此不建议这么写
//        QMessageBox* msg = new QMessageBox(this);
//        msg->information(this, "询问","你在干嘛?");

        //比较合理的编写方式,information为静态函数,因此可以直接使用类调用
        int ret = QMessageBox::information(this, "提示","你上班摸鱼5分钟了,请合理安排时间!", QMessageBox::Yes|QMessageBox::No);
        if (ret == QMessageBox::Yes) {
    
    
            qDebug()<<"好的,知道了!";
        } else {
    
    
            qDebug()<<"就是为了让老板知道!";
        }
    });

    connect(ui->pb03, &QPushButton::clicked, [=](){
    
    

        //比较合理的编写方式,question为静态函数,因此可以直接使用类调用
        QMessageBox::question(this, "询问","你在干嘛?");

    });
    connect(ui->pb04, &QPushButton::clicked, [=](){
    
    

        //比较合理的编写方式,warning为静态函数,因此可以直接使用类调用
        QMessageBox::warning(this, "警告","注意:你上班摸鱼10分钟了,可能要被老板发现了");
        critical_func(this);
    });

void critical_func(QWidget* widget)
{
    
    

//    QMessageBox::critical(widget, "致命","不好,你摸鱼被老板发现了!");

    QMessageBox* msg = new QMessageBox(widget);
    msg->resize(200,100);

    QPushButton* btn = new QPushButton();
    btn = msg->addButton("确定", QMessageBox::AcceptRole);
    msg->show();

    widget->connect(btn,&QPushButton::clicked,widget, [=](){
    
    
        msg->critical(widget, "致命","不好,你摸鱼被老板发现了!");
    });
}

3, cuadro de diálogo QColor

  • En el área de funciones estáticas en QColorDialog:
    Insertar descripción de la imagen aquí
  • Cuatro parámetros: color, clase principal, nombre del título, opciones de color ColorDialogOptions. Si solo llama a getColor (), los valores predeterminados se agregan respectivamente. El valor de retorno es QColor.
static QColor getColor(const QColor &initial = Qt::white,
                           QWidget *parent = nullptr,
                           const QString &title = QString(),
                           ColorDialogOptions options = ColorDialogOptions());

Insertar descripción de la imagen aquí

4, cuadro de diálogo QFile

  • Buscar QFileDialog en Qt Assistant, área de funciones estáticas, getOpenFileName y getOpenFileNames son los dos métodos que utilizamos para obtener la ruta del archivo + nombre del archivo. Para operar el archivo, solo necesitamos obtener la ruta + nombre del archivo:
    Insertar descripción de la imagen aquí
  • Dos funciones, una devuelve QString sin agregar s y la otra función que agrega s devuelve una QStringList, es decir, una devuelve un archivo específico y la otra devuelve una lista de archivos.
static QString getOpenFileName(QWidget *parent = nullptr,
                                   const QString &caption = QString(),
                                   const QString &dir = QString(),
                                   const QString &filter = QString(),
                                   QString *selectedFilter = nullptr,
                                   Options options = Options());

Correspondiente a cinco parámetros:
clase principal: generalmente este
título: título
directorio: ruta predeterminada
seleccionadaFiltro: filtrado de archivos, filtrado y visualización de archivos con sufijos que cumplen las condiciones
opthons: archivador, el valor predeterminado es suficiente

  • Ejemplo sencillo:
    Insertar descripción de la imagen aquí

6. Resumen

  • 1. A través de una comprensión preliminar de Qt, aprendimos sobre algunos controles comunes desarrollados en la interfaz Qt, la relación de herencia de los controles y los métodos abiertos en los controles.
  • 2. Hay dos formas en el desarrollo de ingeniería: al programar, usamos código o usamos el diseñador de UI para diseñar de acuerdo con diferentes escenarios de demanda (un juego entre rendimiento y velocidad de desarrollo).
  • 3. El documento Qt Assistant es muy práctico y se recomienda utilizarlo más.
  • 4. Aquí solo tenemos una cierta comprensión de Qt, que involucra patrones de diseño de programación y más aspectos de optimización del rendimiento, que no se han reflejado en este contenido. Las cuentas posteriores se actualizarán continuamente. Los estudiantes interesados ​​también presten atención.

Supongo que te gusta

Origin blog.csdn.net/MOON_YZM/article/details/130592369
Recomendado
Clasificación