Tabla de contenido
- Qt obtiene la ruta del escritorio de la computadora actual
- Qt obtiene la ruta de ejecución del programa actual
- Qt crea un nuevo archivo de texto txt y escribe el contenido
- Cómo escribir contenido en QPlainTextEdit
- Temporizador Q
- Uso de QMessageBox
- QLatin1String
- Diseño Q
- C++
- QFuente
- Etiqueta Q
- Cómo agregar líneas divisorias al diseño
- Se puede hacer clic en el enlace mostrado por Qlabel para abrirlo.
- Obtenga el botón actualmente presionado en la interfaz
- qobject_cast
- QDiálogo
- Cómo quitar el marco punteado de un botón
- QPushButton establece el tamaño del botón
- Explicación detallada del cuarto parámetro de rgba(0,0,0,0)
- QT implementa desvanecimiento de fondo después de una ventana emergente
- La diferencia entre geometría() y frameGeometry()
- Sistema de propiedades Qt Q_PROPERTY
- C++11 =predeterminado y =eliminar
- El nombre del objeto obtiene el nombre de la clase.
- Cómo agregar carpetas en Qt para clasificar los directorios del árbol de la izquierda
- La diferencia entre setStatusTip, setToolTip y setWhatsThis
- ¿Las clases personalizadas de Qt necesitan heredar QObject?
- Errores comunes de compilación de Qt
- La barra de herramientas de la ventana principal cambia el tamaño del icono
- Eliminar las elipses contenidas en elementos en QComboBox
- Hay dos barras de herramientas, cómo mover una barra de herramientas hacia la derecha (alineada a la derecha)
- Qwidget
- Registro del tipo de datos personalizado Q_DECLARE_METATYPE()
- La función QFontMetrics calcula el tamaño de los caracteres y cadenas de una fuente determinada.
- Macro
- Errores de compilación comunes
-
- error: error en la aserción estática: la ranura requiere más argumentos de los que proporciona la señal. [ #define Q_STATIC_ASSERT_X(Condición, Mensaje) static_assert(bool(Condición), Mensaje)]
- error: No hay regla para hacer que el destino sea 'xxx.png', necesario para 'debug/qrc_resource.cpp'. Detener.
- error: [debug/qrc_resource.cpp] Error 1
- error: el campo tiene tipo incompleto
- error: saltar a la etiqueta del caso [-fpermissive] caso xxx: ^
- error: pasar 'const ProjectTreeViewDelegate' como argumento 'este' descarta los calificadores [-fpermissive] drawTreeViewItem(painter, drawRect, modelData);^
- error: argumento predeterminado dado para el parámetro x de
- error: error en la aserción estática: los argumentos de señal y ranura no son compatibles.
- error: aplicación no válida de 'sizeof' al tipo incompleto 'XXX'('VariableData'): sizeOf = sizeof(T)
- Error sobre en línea: uso no válido del tipo incompleto 'xxx'
- Error lambda del error de función de ranura: pasar 'const VarBasicData' como argumento 'este' descarta los calificadores [-fpermissive][=](const VarBasicData& varinfo) { varData.basic = varinfo; });
- La función de actualización()
- Color Q
- evento: establece el estilo del marco cuando el mouse entra y sale
- El papel de INCLUDEPATH en .pri
- Configure solo el botón de cerrar en la esquina superior derecha
- ¿Puedo regresar directamente antes del descanso (tengo que hacer un descanso después del regreso en el cambio)?
- Bucle for multinivel, break solo saltará de un nivel del bucle
- QTreeView
- Cómo asignar valores a iteradores: use *blockIter
- Definición de enumeración
- Uso de findChild
- conectar
-
- Cómo escribir conectar
- expresión lambda de conectar
- Captura de valor [=] y captura de referencia [&] en lambda
- Antes de enviar una señal, primero se debe establecer una conexión.
- Connect está anidado en connect, preste atención a las conexiones repetidas.
- parámetros de conexión
- Cómo evitar conexiones repetidas en connect
- Sobrecarga de la función de conexión de ranura de señal y problemas de inconsistencia de parámetros
- Cuando se hace clic con el mouse del cuadro de diálogo fuera de la ventana, la ventana se cerrará.
- Índice de modelo Q
- Eliminar nodos secundarios del árbol
- QLine
- Conversión entre coordenadas actuales y coordenadas globales
- Determinar si el foco actual está en un control.
- Qt gana y pierde eventos de enfoque
- Comparación sobre la lista
- Arrastrar Cómo mostrar el signo de arrastre deshabilitado
- Cuadro de diálogo QFile
- El problema de que setFocus no surte efecto
Qt obtiene la ruta del escritorio de la computadora actual
#include <QStandardPaths>
QString desktop_path = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
Qt obtiene la ruta de ejecución del programa actual
#include <QCoreApplication>
//方法1:
QString fileName = QCoreApplication::applicationDirPath();
//方法2:
QString fileName = QApplication::applicationDirPath();
La diferencia entre QCoreApplication y QApplication:
QApplication hereda de QGuiApplication y QGuiApplication hereda de QCoreApplication
QApplication: con Gui, QCoreApplication: sin Gui
Qt crea un nuevo archivo de texto txt y escribe el contenido
//在当前程序运行路径下创建
QFile file(QCoreApplication::applicationDirPath() + "/test.txt");
if (!file.exists()) {
qDebug() << "文件不存在!";
}
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
qDebug() << "文件打开失败!";
}
QString str = "测试文件是否被修改!";
QTextStream out(&file);
out << str; //将str写入文件
file.close();
Cómo escribir contenido en QPlainTextEdit
void insertPlainText(const QString &text);
void appendPlainText(const QString &text);
Temporizador Q
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &MainWindow::slotRefresh());
timer->start(1000); //延迟1秒刷新
QTimer también proporciona una función estática para temporizadores de un solo uso. Por ejemplo:
QTimer::singleShot(200, this, &MainWindow::slotRefresh());
Uso de QMessageBox
Constructor
QMessageBox messageBox(QMessageBox::Question, "Question", "The current project has been modified.\nDo you want to save it?", QMessageBox::Yes | QMessageBox::No);
messageBox.exec();
Implementado a través de constructores y funciones de propiedad.
QMessageBox messageBox(this);
messageBox.setIcon(QMessageBox::Warning);
messageBox.setWindowTitle("Warning");
messageBox.setText("Parsed file not found! Please reconfigure!");
messageBox.setStandardButtons(QMessageBox::Yes|QMessageBox::No);
messageBox.setDefaultButton(QMessageBox::Yes);
messageBox.exec();
función estática
QMessageBox::Information(this, "Information", "Project saved successfully!");
QLatin1String
QLatin1String es una envoltura delgada alrededor de const char*.
Muchas funciones miembro de QString se sobrecargan utilizando const char* en lugar de QString como parámetro.
Por ejemplo, suponiendo que str es un objeto QString,
if (str == "auto" || str == "extern"
|| str == "static" || str == "register") {
...
}
El código anterior se ejecutará mucho más rápido que el siguiente código
if (str == QString("auto") || str == QString("extern")
|| str == QString("static") || str == QString("register")) {
...
}
Porque en la segunda parte del código, se construirán cuatro objetos QString temporales y se copiarán los valores de la cadena.
Si utiliza la clase QLatin1String para escribir el programa anterior, es
if (str == QLatin1String("auto")
|| str == QLatin1String("extern")
|| str == QLatin1String("static")
|| str == QLatin1String("register") {
...
}
Aunque el código es un poco largo para ingresar, su eficiencia de ejecución es la misma que la del primer código anterior.
QLatin1String se puede utilizar en cualquier lugar donde se espere un objeto QString
QLabel label;
label.setObjectName(QLatin1String("111"));
Diseño Q
void QLayout::setContentsMargins(int left, int top, int right, int bottom)
Establezca los márgenes izquierdo, superior, derecho e inferior para utilizarlos en el diseño.
De forma predeterminada, QLayout usa el valor proporcionado por el estilo. En la mayoría de las plataformas, los márgenes son de 11 píxeles en todas las direcciones.
QGridLayout* grid = findChild<QGridLayout*>("gridLayout"); //通过对象名获取布局
grid->setContentsMargins(10, 30, 50, 70); //上、左、右、下
int spacing() const
void setSpacing(int)
Establece el espaciado entre widgets en un diseño.
Si un valor no se establece explícitamente, el espaciado del diseño se hereda del diseño principal o de la configuración de estilo del widget principal.
Para QGridLayout y QFormLayout, puede usar setHorizontalSpacing() y setVerticalSpacing() para establecer diferentes espacios horizontales y verticales. En este caso, el espaciado() devuelve -1
C++
¿Cuál es la diferencia entre escribir el archivo de encabezado de clase #include en el archivo de encabezado de C++ y escribir directamente la clase más el nombre de la clase?
El nombre de la clase de clase solo declara que dicha clase existe, pero no se puede obtener información específica sobre esta clase a través de esta declaración. De esta forma puedes declarar un puntero de este tipo en otros lugares donde se use.
#include "xx.h" expande directamente el archivo xx.h durante la compilación, por lo que se pueden usar las interfaces internas y se pueden declarar objetos. Pero la clase xx; no funciona de esta manera. Solo puedes usar su puntero o referencia y no puedes crear un objeto declarado.
使用class 类名一般是为了去除编译依赖,减少编译消耗的时间。
Por ejemplo:
hay un archivo de encabezado "common.h", lo necesita en todos los archivos de encabezado, así que #include "common.h", cuando hay algunos cambios en el código en common.h, está ejecutando el código. todos los archivos de encabezado que dependen de él deben volver a compilarse. Y si es Clase Común, cuando se realizan algunos cambios en el código en common.h, cuando ejecuta el código, todos los archivos de encabezado que dependen de él no se compilarán nuevamente después de haberlo compilado una vez antes. (Después de compilar el encabezado de un archivo, si el archivo de encabezado no se ha modificado, no se volverá a compilar la próxima vez que se ejecute el código)
Solo declarar clases sin incluir puede reducir la correlación de cada archivo durante la compilación. Al cambiar algunas clases, no provocará la recompilación de una gran cantidad de otros archivos. No hace ninguna diferencia cuando se trabaja en un proyecto pequeño, pero sí cuando es más grande. La ventaja de esto se hace evidente cuando la compilación lleva varias horas seguidas.
palabra clave mutable
Mutable también está configurado para romper las limitaciones de const. Las variables modificadas por mutable siempre estarán en un estado mutable, incluso en una función constante
.
declaración anticipada
Declarar una clase en un archivo de encabezado de clase sin definirla se llama declaración directa.
La clase A declarada hacia adelante en el archivo de encabezado es un tipo incompleto. Solo conocemos el tipo de clase A, pero no sabemos qué miembros contiene la clase A.
Un tipo incompleto no puede definir un objeto del tipo, pero solo puede usarse para definir un puntero o referencia del tipo, o para declarar una función del tipo como parámetro o valor de retorno.
Beneficio: el tiempo de compilación se puede reducir para #includes innecesarios
// 当使用前向引用声明时,只能使用被声明的符号,而不能涉及类的任何细节。
class A; //前向声明类A
class B{
public:
A* m_a; //用于定义指向这个类型的指针或引用
void func(A a); //用于声明(不是定义)使用该类型作为形参或者返回类型的函数
}
-
Una clase declarada hacia adelante no puede definir objetos (el tamaño y los miembros internos de la clase no se conocen y no se pueden crear instancias).
-
Se puede utilizar para definir punteros y referencias a este tipo (es decir, definir punteros o referencias de esta clase como variables miembro).
-
Se puede utilizar para declarar (no definir) funciones que utilizan este tipo como parámetro formal o tipo de retorno.
QFuente
La clase QFont se utiliza para dibujar fuentes de texto.
Tenga en cuenta que debe existir una instancia de QGuiApplication antes de usar QFont. La fuente predeterminada de la aplicación se puede configurar usando QGuiApplication::setFont().
Si la fuente seleccionada no contiene todos los caracteres que deben mostrarse, QFont intentará encontrar los caracteres en la fuente equivalente más cercana.
Cuando QPainter dibuja un carácter de una fuente, QFont informará si tiene ese carácter; de lo contrario, QPainter dibujará un cuadrado sin relleno.
Constructores de uso común
QFont(const QString &family, int pointSize = -1, int weight = -1, bool italic = false);
//参数说明:字体样式、字体大小、字体粗细、是否斜体
Funciones de uso común
void setFamily(const QString &family); //设置字体样式
void setPointSize(int pointSize); //设置字体大小
void setWeight(int weight); //设置字体粗细
void setBold(bool enable); //设置字体是否加粗
void setItalic(bool enable); //设置字体是否斜体
void setPixelSize(int pixelSize); //设置字体像素大小
void setOverline(bool enable); //设置字体上划线
void setUnderline(bool enable); //设置字体下划线
void setStrikeOut(bool enable); //设置字体删除线
void setLetterSpacing(SpacingType type, qreal spacing);
//将字体的字母间距设置为spacing,并将间距的类型设置为type。
//字母间距改变字体中单个字母之间的默认间距。根据所选择的间距类型,字母之间的间距可以按字符宽度的百分比或按像素的百分比设置为更小或更大。
enum QFont::SpacingType
enumerar | valor | describir |
---|---|---|
QFont::Porcentaje de espaciado | 0 | Un valor de 100 dejará el espacio sin cambios; un valor de 200 ampliará el espacio detrás de los caracteres al ancho de los propios caracteres. |
QFont::Espaciado absoluto | 1 | Los valores positivos aumentan el espaciado entre letras en los píxeles correspondientes; los valores negativos disminuyen el espaciado. |
void setCapitalization(Capitalization caps);
//将此字体的文本的大写设置为大写。
//字体的大写使文本以选定的大写模式显示。
enum QFont::Capitalization
enumerar | valor | describir |
---|---|---|
QFont::Mezcla de mayúsculas y minúsculas | 0 | Opción de representación de texto normal donde no se aplican cambios de mayúsculas y minúsculas. |
QFont::Todos en mayúsculas | 1 | todas las mayúsculas |
QFont::Todos en minúsculas | 2 | todo en minúsculas |
QFont::SmallCaps | 3 | Versalitas significa todas las letras mayúsculas, pero tienen el mismo tamaño que las minúsculas. |
QFont::Capitalizar | 4 | Poner en mayúscula la primera letra |
Etiqueta Q
Establecer el tamaño y el color de fuente QLabel
QLabel* label = new QLabel(tr("test"));
font.setFont(QFont("宋体"), 12);
QPalette pa;
pa.setColor(QPalette::WindowText, Qt::red);
font.setPalette(pa);
QLabel establece el color de fondo
QLabel* colorLabel = new QLabel(this);
colorLabel->setFixedSize(10, 10);
QPalette palette = colorLabel->palette();
palette.setColor(QPalette::Background, Qt::black);
colorLabel->setAutoFillBackground(true);
colorLabel->setPalette(palette);
La fuente excede la longitud de QLabel, cómo mostrarla en forma de puntos suspensivos
QLabel* m_activeText = new QLabel(this);
QString text = "abcdefg";
QFontMetrics fontWidth(m_activeText->font()); //计算字体的宽度
QString elideText = fontWidth.elidedText(text, Qt::ElideMiddle, 80); //80为最大宽度
m_activeText->setText(elideText);
QLabel no se muestra completamente, ¿cómo ajustar la línea automáticamente?
label->setWordWrap(true); // true:自动换行
label->setAlignment(Qt::AlignVCenter); // 对齐方式
Cómo agregar líneas divisorias al diseño
QLabel* lineLabel = new QLabel(this);
lineLabel->setFrameStyle(QFrame::HLine | QFrame::Sunken); //Sunken:凹陷,Raised:凸起
Simplemente agregue lineLabel al diseño.
Se puede hacer clic en el enlace mostrado por Qlabel para abrirlo.
label->setTextInteractionFlags(Qt::TextBrowserInteraction); //label中的内容可用鼠标选择文本复制,链接激活
label->setOpenExternalLinks(true); //label中的内容若为链接,可直接点击打开
label.setText("<a href = https://blog.csdn.net/WL0616?spm=1000.2115.3001.5343>点我试试"); //https://blog.csdn.net/WL0616?spm=1000.2115.3001.5343为链接网址
Obtenga el botón actualmente presionado en la interfaz
QPushButton* btn= qobject_cast<QPushButton*>(sender());
qobject_cast
La función qobject_cast() se comporta como la función Dynamic_cast() de C++ estándar, con la ventaja de que no requiere soporte RTTI y puede funcionar a través de los límites de la biblioteca dinámica.
qobject_cast convierte dinámicamente el tipo de la clase QObject.qobject_cast convierte el tipo entre paréntesis () al tipo entre paréntesis angulares <>.
T qobject_cast(QObject *object)
Existen dos limitaciones a la hora de utilizarlo:
- El tipo T devuelto debe heredar de QObject.
- La macro Q_OBJECT debe incluirse en la declaración.
QLabel* label = new QLabel();
QWidget* widget = qobject_cast<QWidget*>(label);
QDiálogo
QDialog ocultar/eliminar barra de título
setWindowFlags(Qt::FramelessWindowHint);
Genera una ventana sin bordes. Los usuarios no pueden mover ni cambiar el tamaño de ventanas sin bordes a través del sistema de ventanas.
QDialog elimina el signo de interrogación y solo lo mantiene cerrado
Qt::WindowFlags flags = Qt::Dialog;
flags |= Qt::WindowCloseButtonHint;
setWindowFlags(flags);
Cómo quitar el marco punteado de un botón
Por ejemplo: un botón tiene un efecto de enfoque ¿
Cómo cancelar este efecto?
//方法1
setFocusPolicy(Qt::NoFocus);
//方法2
setStyleSheet("outline: none");
//方法3
setStyleSheet("padding: -1");
QPushButton establece el tamaño del botón
QPushButton hereda de QAbstractButton y QAbstractButton hereda de QWidget. La siguiente es en realidad la interfaz de QWidget.
void setMinimumHeight(int minh)
void setMinimumSize(const QSize &)
void setMinimumSize(int minw, int minh)
void setMinimumWidth(int minw)
Explicación detallada del cuarto parámetro de rgba(0,0,0,0)
Los primeros tres parámetros indican el color y el cuarto parámetro indica la transparencia, su rango está entre 0.0 y 1.0, y 0.5 es translúcido.
rgba(0,0,0,1) significa negro completamente opaco;
rgba(0,0,0,0.5) significa semitransparente, que parece gris;
rgba(0,0,0,0) significa blanco completamente opaco, que es, incoloro;
QT implementa desvanecimiento de fondo después de una ventana emergente
QWidget* widget = nuevo QWidget(este);
widget->resize(this->width(), this->height());
widget->mover(0, 0);
widget->setStyleSheet(“color de fondo:rgba(0, 0, 0, 0.3);”);
widget->mostrar();
La diferencia entre geometría() y frameGeometry()
geometría(): tamaño de la interfaz, excluyendo el decorador de la ventana (es decir, la barra de título)
frameGeometry(): tamaño de la interfaz, incluido el decorador de la ventana superior (es decir, la barra de título)
Sistema de propiedades Qt Q_PROPERTY
Qt proporciona un maravilloso sistema de propiedades. Q_PROPERTY() es una macro utilizada para declarar una propiedad en una clase.
Una propiedad se comporta como un miembro de datos de una clase, pero tiene una funcionalidad adicional a la que se accede a través del sistema de metaobjetos .
Q_PROPERTY(type name
(READ getFunction [WRITE setFunction] |
MEMBER memberName [(READ getFunction | WRITE setFunction)])
[RESET resetFunction]
[NOTIFY notifySignal]
[REVISION int]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
[USER bool]
[CONSTANT]
[FINAL])
Ejemplo de propiedad:
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
Q_PROPERTY: macro utilizada para declarar atributos, bool especificado por Qt
: tipo de atributo
habilitado: nombre del atributo
READ isEnabled (estas dos palabras se pueden entender juntas): es decir, el valor del atributo se puede leer a través de isEnabled
WRITE setEnabled (estas dos palabras Puede juntarlos para entender): es decir, puede establecer el valor del atributo a través de setEnabled
Lo anterior es solo un atributo y una declaración, pero en realidad no está implementado. También es necesario implementar isEnabled y setEnabled respectivamente, para que todo el atributo pueda usarse realmente.
ejemplo:
class MaskWidget : public QDialog {
Q_OBJECT
Q_PROPERTY(QStringList names READ names WRITE setNames DESIGNABLE true)
public:
static MaskWidget* instance();
void setMainWidget(QWidget* pWidget);
QStringList names() const;
void setNames(const QStringList& names);
...
};
Significados de campos adicionales proporcionados por los atributos
LEER: Se utiliza para leer valores de atributos. Si no se especifica la variable miembro (a través de MIEMBRO), se requiere una función de acceso de lectura.
ESCRITURA: Las funciones de acceso de escritura son opcionales. Se utiliza para establecer valores de atributos. Debe devolver void y debe aceptar solo un argumento, ya sea el tipo de propiedad o un puntero o referencia a ese tipo.
MIEMBRO: Si no se especifica ninguna función de acceso de lectura, se requiere asociación de variable miembro. Esto hace que una variable miembro determinada sea legible y escribible sin la necesidad de crear funciones de acceso de lectura y escritura. Si necesita controlar el acceso a variables, puede usar funciones de acceso de lectura o escritura además de la asociación de variables miembro (pero no ambas).
RESET: La función de reinicio es opcional. Se utiliza para restablecer una propiedad a su valor predeterminado específico del contexto.
NOTIFICAR: Las señales de notificación son opcionales. Si se define, debe especificar una señal existente en la clase que se emite cuando cambia el valor de la propiedad. Las señales de notificación para variables miembro deben tomar cero o un argumento, que debe ser del mismo tipo que la propiedad. El parámetro tomará el nuevo valor de la propiedad. La señal NOTIFY solo debe emitirse cuando la propiedad realmente haya cambiado, para evitar que los enlaces se vuelvan a calcular innecesariamente en QML.
REVISIÓN: El número de revisión es opcional. Si se incluye, definirá las propiedades y sus señales de notificación para su uso en una versión específica de la API (generalmente para exposición a QML). Si no se incluye, el valor predeterminado es 0.
DISEÑABLE: Indica si la propiedad debe ser visible en el editor de propiedades de una herramienta de diseño GUI (por ejemplo, Qt Designer). La mayoría de las propiedades se pueden diseñar (el valor predeterminado es verdadero). Se pueden especificar funciones miembro booleanas en lugar de verdadero o falso.
SCRIPTABLE: Indica si el motor de script debe acceder a esta propiedad (el valor predeterminado es verdadero). Se pueden especificar funciones miembro booleanas en lugar de verdadero o falso.
ALMACENADO: Indica si el atributo debe considerarse independiente o dependiente de otros valores. También indica si el valor de la propiedad debe guardarse al almacenar el estado del objeto.
USUARIO: Indica si la propiedad está designada como una propiedad de la clase orientada al usuario o una propiedad editable por el usuario. Normalmente, sólo hay un atributo de usuario por clase (el valor predeterminado es falso).
CONSTANTE: Indica que el valor del atributo es una constante. Para una instancia de objeto determinada, el método READ de una propiedad constante debe devolver el mismo valor cada vez que se llama. El valor de esta constante puede diferir para diferentes instancias del objeto. Las propiedades constantes no pueden tener métodos de escritura ni señales de notificación.
FINAL: Indica que las clases derivadas no anularán esta propiedad. Esto se puede utilizar para optimizar el rendimiento en algunos casos, pero moc no lo aplica.
C++11 =predeterminado y =eliminar
En C ++ 11, cuando definimos una función miembro de una clase, si luego se modifica con "= eliminar", significa que la función se define como eliminada, lo que significa que la función miembro ya no se puede llamar, de lo contrario Algo saldrá mal.
Antes de C++ 11, cuando queríamos que una clase no fuera copiada, definimos el constructor como privado, pero en C++ 11 no hay necesidad de hacer esto. Sólo necesitamos agregar =delete después del constructor. modificarlo.
El nombre del objeto obtiene el nombre de la clase.
obj->metaObject()->className() == QLatin1String("Dialog");
Cómo agregar carpetas en Qt para clasificar los directorios del árbol de la izquierda
- Cree una nueva carpeta en la ruta del proyecto actual, por ejemplo, asígnele un nombre
src
- En la carpeta src recién creada, cree un nuevo documento de texto y asígnele un nombre
src.pri
(cambie el sufijo txt a pri) - Cambie a Qt, agréguelo al .pro del proyecto actual
include(src/src.pri)
y presione Ctrl+S para guardarlo. - Después de guardar (tarda unos segundos), se mostrará la carpeta que agregó.
- Haga clic derecho en la carpeta src que agregó para agregar un nuevo archivo y crear archivos .h y .cpp.
La diferencia entre setStatusTip, setToolTip y setWhatsThis
setStatusTip se usa para la punta de la barra de estado de MainWindow;
setToolTip se usa para la punta del control;
setWhatsThis se usa para la información de ayuda en el cuadro de diálogo.
¿Las clases personalizadas de Qt necesitan heredar QObject?
La clase QObject es la clase base para todos los objetos Qt.
Es mejor que las clases personalizadas hereden QObject, y también se debe escribir la macro Q_OBJECT.
Facilita el uso de señales y slots.
Errores comunes de compilación de Qt
- error: 'tr' no fue declarado en este ámbito...
tr() es una función miembro de la clase QObject.
Motivo: la clase personalizada no hereda QObject
La barra de herramientas de la ventana principal cambia el tamaño del icono
toolBar->setIconSize(QSize(18,18));
Eliminar las elipses contenidas en elementos en QComboBox
Al configurar el ancho máximo de QComboBox:
combox->setMaximumWidth(100);
Si el contenido del elemento es relativamente largo, aparecerán puntos suspensivos en el medio del elemento, lo que no se ve bonito:
la solución para cancelar los puntos suspensivos:
combox->view()->setTextElideMode(Qt::ElideNone); //取消项中的省略号,但是会导致看不见后面的字体
enum TextElideMode {
ElideLeft, //省略号在最左边
ElideRight, //省略号在最右边
ElideMiddle, //省略号在最中间
ElideNone //无省略号
};
Hay dos barras de herramientas, cómo mover una barra de herramientas hacia la derecha (alineada a la derecha)
Configure un widget en la barra de herramientas principal, coloque las dos barras de herramientas dentro del widget y use QHBoxLaout para el diseño. Una se coloca en el Qt::AlignLeft izquierdo, la otra se coloca en el Qt::AlignRight derecho y se coloca un resorte. entre los dos..
Establecer en la primera barra de herramientas:
QWidget* widget = new QWidget(this);
QComboBox* com1 = new QComboBox(this);
QComboBox* com2 = new QComboBox(this);
QToolBar* bar1 = new QToolBar(widget);
bar1->addWidget(com1);
QToolBar* bar2 = new QToolBar(widget);
bar2->addWidget(com2);
QHBoxLayout* lay = new QHBoxLayout;
lay->addWidget(bar1, Qt::AlignLeft);
lay->addStretch();
lay->addWidget(bar2, Qt::AlignRight);
widget->setLayout(lay);
ui->mainToolBar->addWidget(widget);
Qwidget
El widget dibuja el color de fondo.
//CustomLabel继承与QLabel
void CustomLabel::setBackgroundColor(const QColor& color) {
QPalette palette;
palette.setColor(QPalette::Background, color);
setAutoFillBackground(true);
setPalette(palette);
}
widget establece borde
/**
* @brief paintEvent: 绘制边框
*/
void ProjectTree::paintEvent(QPaintEvent* event) {
Q_UNUSED(event)
QPainter p(this);
p.setPen(Qt::black); //设置画笔记颜色
p.drawRect(0, 0, width() - 1, height() - 1); //绘制边框
}
Haga clic con el mouse en otro lugar para ocultar el widget actual
setWindowFlags(Qt::Popup);
Colocar ventana debajo de la ventana actual
void QWidget::stackUnder(QWidget *w)
Coloque el widget debajo de w en la pila de widgets principal. Para hacer esto, el widget en sí y w deben ser hermanos (tanto el widget como w heredan de una clase principal).
Por ejemplo: quiero colocar una ventana debajo de la ventana emergente actual. La ventana actual hereda QDialog, por lo que la ventana que se colocará también debe heredar QDialog.
Cómo obtener la ventana de la clase padre.
QWidget* mainWindow = this->parentWidget();
Por ejemplo
Registro del tipo de datos personalizado Q_DECLARE_METATYPE()
La función QFontMetrics calcula el tamaño de los caracteres y cadenas de una fuente determinada.
QFont font("times", 24);
QFontMetrics fm(font);
int pixelsWide = fm.width("What's the width of this text?");
int pixelsHigh = fm.height();
QString elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags = 0) const;
(Elide: significado de omisión)
Si el ancho del texto de la cadena es mayor que el ancho, se devuelve la versión omitida de la cadena (es decir, la cadena que contiene "..."). De lo contrario, se devuelve la cadena original.
enum TextElideMode {
ElideLeft, //省略号在左边
ElideRight, //省略号在右边
ElideMiddle, //省略号在中间
ElideNone //无省略号
};
Macro
Q_ASSERT
Q_ASSERT es una macro que acepta un valor booleano. Cuando el valor booleano es verdadero, no hace nada. Cuando el valor booleano es falso, se detiene.
Q_ASSERT(index.isValid());
Errores de compilación comunes
error: error en la aserción estática: la ranura requiere más argumentos de los que proporciona la señal. [ #define Q_STATIC_ASSERT_X(Condición, Mensaje) static_assert(bool(Condición), Mensaje)]
Motivo: Generalmente causado por inconsistencia en los parámetros de señales y ranuras.
error: No hay regla para hacer que el destino sea 'xxx.png', necesario para 'debug/qrc_resource.cpp'. Detener.
Causa: Eliminando imágenes bajo recursos en el proyecto
Solución: Vuelva a ejecutar qmake.
error: [debug/qrc_resource.cpp] Error 1
Motivo: esta imagen se agregó al proyecto, pero no existe en el archivo (o se eliminó). No se puede encontrar en este momento, por lo que se informa un error. ¿Cómo encontrar esta imagen inexistente
?
Método: Haga clic en las imágenes una por una, al hacer clic en una imagen que no existe, se mostrará el siguiente error.
Solución: elimine esta imagen del proyecto y agréguela nuevamente
error: el campo tiene tipo incompleto
Motivo: Es solo una declaración directa y no incluye el archivo de inclusión
Solución: Incluya el archivo de inclusión.
error: saltar a la etiqueta del caso [-fpermissive] caso xxx: ^
Motivo: si hay varias líneas de código de definición después de la declaración del caso, especialmente definiciones de variables , es mejor usar {} para dar el alcance de la restricción, porque la computadora no puede reconocer el alcance.
Solución: agregue {} al código después de la declaración del caso
//Ejemplo de error:
switch (a)
{
case 1:
int a = 0;
//stuff
break;
case 2:
//stuff
break;
}
//Demostración correcta:
switch (a)
{
case 1:
{
int a = 0;
//stuff
}
break;
case 2:
//stuff
break;
}
error: pasar 'const ProjectTreeViewDelegate' como argumento 'este' descarta los calificadores [-fpermissive] drawTreeViewItem(painter, drawRect, modelData);^
Motivo: cuando una función es una función constante y otra función llamará a los parámetros de esta función, la otra función también debe configurarse como constante
Solución: la otra función también debe ser una función constante.
Ejemplo de error:
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
void drawTreeViewItem(QPainter* painter, QRect drawRect, ProjectTreeModelData modelData); //错误
Demostración correcta:
//drawTreeViewItem参数里面会调用paint的参数,paint为const函数,则drawTreeViewItem也应为const函数
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
void drawTreeViewItem(QPainter* painter, QRect drawRect, ProjectTreeModelData modelData) const;
Otra situación:
el valor de una variable miembro no se puede cambiar ni asignar en una función constante.
error: argumento predeterminado dado para el parámetro x de
Motivo: los parámetros predeterminados se pueden declarar en una declaración de función o en una definición de función, pero no se pueden declarar tanto en una declaración de función como en una definición de función.
Solución: simplemente elimine cualquier parámetro predeterminado en la definición o declaración.
Ejemplo de error:
//.h文件
void func(int a, int b = 0);
//.cpp文件
void func(int a, int b = 0); //错误
Demostración correcta:
//.h文件
void func(int a, int b = 0);
//.cpp文件
void func(int a, int b);
error: error en la aserción estática: los argumentos de señal y ranura no son compatibles.
Motivo: Los parámetros de la señal no corresponden a los parámetros de la función de ranura
Solución: Los parámetros de la señal y los parámetros de la función de ranura se cambian para que sean consistentes.
Ejemplo de error:
//信号
sigData(int a);
//槽函数
slotGetData(float a); //错误,参数不一致
Demostración correcta:
//信号
sigData(int a);
//槽函数
slotGetData(int a);
error: aplicación no válida de 'sizeof' al tipo incompleto 'XXX'('VariableData'): sizeOf = sizeof(T)
Motivo: Predeclarar una clase es solo una declaración y no se conoce el tamaño de la clase.
Solución: Utilice include para incluir el archivo de encabezado.
Ejemplo de error:
class B; //只是声明
class A {
...
QList<B> m_ list; //无法知道类B的大小
};
Demostración correcta:
#include "B.h"
class A {
...
QList<B> m_ list;
};
Error sobre en línea: uso no válido del tipo incompleto 'xxx'
Motivo: Inline se declara en el archivo de encabezado. Cuando se define en el archivo fuente, si otros archivos llaman a la función en línea, se producirá este error. Debido a que esta función no es visible para otras unidades de compilación, es decir, otros archivos cpp no pueden vincularse a esta biblioteca de funciones.
Solución: la declaración y definición de la función en línea están escritas en el archivo de encabezado
- Si la implementación de la función se coloca en un archivo de encabezado, entonces cada archivo cpp que contenga el archivo de encabezado obtendrá una definición de la función y el vinculador informará un error de redefinición de la función.
- Si la implementación de la función se coloca en el archivo de encabezado y se marca en línea, entonces cada archivo cpp que contenga el archivo de encabezado obtendrá una definición de la función y el vinculador no informará un error.
- Si la implementación de la función se coloca en el archivo cpp y no está marcada en línea, la función se puede vincular a otras unidades de compilación.
- Si la implementación de la función se coloca en el archivo cpp y se marca en línea, entonces la función no es visible para otras unidades de compilación (similar al efecto estático), es decir, otros archivos cpp no pueden vincularse a la biblioteca de funciones, que es lo que aparece. en el título... referencia indefinida a...
Error de error lambda de la función de ranura: pasar 'const VarBasicData' como argumento 'este' descarta los calificadores [-fpermissive][=](const VarBasicData& varinfo) { varData.basic = varinfo; });
Motivo: el parámetro es constante y se producirá un error durante la asignación.
Solución: agregue la palabra clave mutable
Ejemplo de error:
connect(SignalsMedium::getInstance(), &SignalsMedium::sigBasicVarInfo,
[=](const VarBasicData& varinfo) {
varData.basic = varinfo; });
Demostración correcta:
connect(SignalsMedium::getInstance(), &SignalsMedium::sigBasicVarInfo,
[=](const VarBasicData& varinfo) mutable {
varData.basic = varinfo; });
La función de actualización()
Se utiliza para actualizar la interfaz de usuario, activará el evento de redibujado y llamará a la función paintEvent .
En QWidget o sus subclases, puede activar el evento de redibujo llamando a la función de actualización para actualizar la interfaz de usuario.
Color Q
nombre del color de impresión
QString QColor::name() const
qDebug() << color.name();
color básico
QString arrayColor[5][8] = {
{
"#000000", "#A52A2A", "#004040", "#005500", "#00005E", "#00008B", "#4B0082", "#696969"},
{
"#8B0000", "#FF6820", "#8B8B00", "#009300", "#388E8E", "#0000FF", "#7B7BC0", "#808080"},
{
"#FF0000", "#FFAD5B", "#32CD32", "#3CB371", "#7FFFD4", "#7D9EC0", "#800080", "#A9A9A9"},
{
"#FFC0CB", "#FFD700", "#FFFF00", "#00FF00", "#40E0D0", "#C0FFFF", "#480048", "#C0C0C0"},
{
"#FFE4E1", "#D2B48C", "#FFFFE0", "#98FB98", "#AFEEEE", "#68838B", "#E6E6FA", "#FFFFFF"}};
QString arrayToolTip[5][8] = {
{
"Black", "Brown", "Dark Olive Green", "Dark Green", "Dark Teal", "Dark Blue", "Indigo", "Dark Gray"},
{
"Dark Red", "Orange", "Dark Yellow", "Green", "Teal", "Blue", "Blue Gray", "Gray"},
{
"Red", "Light Orange", "Lime", "Sea Green", "Aqua", "Light Blue", "Violet", "Dim Gray"},
{
"Pink", "Gold", "Yellow", "Bright Green", "Turquoise", "SkyBlue", "Dark Magenta", "Light Gray"},
{
"Light Pink", "Tan", "Light Yellow", "Pale Green", "Pale Turquoise", "Pale Blue", "Lavender", "White"}};
evento: establece el estilo del marco cuando el mouse entra y sale
bool BasicColorItem::event(QEvent* event) {
/*鼠标进入时的框架样式*/
if (QEvent::Enter == event->type()) {
setLineWidth(0);
setMidLineWidth(0);
setFrameShape(QFrame::WinPanel);
setFrameShadow(QFrame::Raised);
}
/*鼠标离开时的框架样式*/
if (QEvent::Leave == event->type()) {
initItemFram();
}
return QLabel::event(event);
}
El papel de INCLUDEPATH en .pri
Si hay: INCLUDEPATH += $$PWD/treeview/
, directamente en otros niveles de archivos: #include "abc.h"
Si no hay: INCLUDEPATH += $$PWD/treeview/
, debe buscar nivel por nivel en otros niveles de archivos e incluir: #include "xxx/yyy/zzz/abc.h"
Configure solo el botón de cerrar en la esquina superior derecha
setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
setWindowModality(Qt::WindowModal); //模态窗口
¿Puedo regresar directamente antes del descanso (tengo que hacer un descanso después del regreso en el cambio)?
El uso de return en el interruptor no solo saltará fuera del interruptor, sino que también finalizará directamente el ciclo.
Se sabe que cuando se ejecuta break, el interruptor saltará y las declaraciones posteriores ya no se ejecutarán; return tiene el mismo efecto.
En la idea, ya sea que escriba un descanso después del regreso o un regreso después del descanso, se informará un error directamente y no se podrá llegar a la declaración.
Bucle for multinivel, break solo saltará de un nivel del bucle
QTreeView
establecer la configuración de atributos
setHeaderHidden(true); //隐藏标题
setExpandsOnDoubleClick(false); //是否双击展开项
setRootIsDecorated(false); //是否显示展开和折叠顶级项的控件(v和>)
setEditTriggers(QAbstractItemView::NoEditTriggers); //不可编辑
setIndentation(0); //所有项的缩进为0
setAcceptDrops(true); //接受拖放事件
setAnimated(true); //子项展开的动画
SetExpanded no expande el problema
Problema: cuando no hay nodos secundarios en el elemento actual, setExpanded no es válido. Primero debe agregarRow() y luego setExpanded().
setExpanded debe configurarse desde el nodo superior hacia abajo. Si se configura hacia arriba desde el nodo inferior, no será válido.
setExpanded no es válido de adentro hacia afuera (configure primero el nodo descendiente, luego configure el nodo principal), ejemplo:
QStandardItem* currentItem = new QStandardItem;
m_model->appendRow(currentItem);
for(int i = 0; i < 3; ++i){
QStandardItem* childItem = new QStandardItem;
for(int i = 0; i < 5; ++i){
QStandardItem* grandsonItem = new QStandardItem;
childItem->appendRow(grandsonItem);
}
//此时想的是给childItem添加完子节点后,再去展开它,但是当前节点的父节点都不知道展开了没有,在这里展开子节点是豪无意义的
//所以这里的childItem展开是无效的。在这之前必须先设置父节点的setExpanded
setExpanded(childItem ->index(), true);
currentItem->appendRow(childItem );
}
setExpanded(currentItem->index(), true); //currentItem展开
El código anterior provocará: childItem no se expandirá
Corrección: setExpanded debe configurarse de afuera hacia adentro ( de padre a hijo, luego a nieto, setExpanded )
//每次appendRow之后就setExpanded
QStandardItem* currentItem = new QStandardItem;
m_model->appendRow(currentItem);
setExpanded(currentItem->index(), true); //currentItem展开
for(int i = 0; i < 3; ++i){
QStandardItem* childItem = new QStandardItem;
currentItem->appendRow(childItem );
setExpanded(childItem ->index(), true);
for(int i = 0; i < 5; ++i){
QStandardItem* grandsonItem = new QStandardItem;
childItem->appendRow(grandsonItem);
}
}
Cómo asignar valores a iteradores: use *blockIter
for (QList<BlockData>::iterator blockIter = osciModelData.oscilloscope.blockDList.begin();
blockIter != osciModelData.oscilloscope.blockDList.end(); ++blockIter) {
if (blockModelData.block.uid == blockIter->uid) {
//找到是哪个Block
*blockIter = blockModelData.block;
}
}
Definición de enumeración
Los elementos de enumeración de diferentes tipos de enumeración no pueden tener el mismo nombre
Uso de findChild
Devuelve un elemento secundario de QPushButton llamado "botón1" en el widget principal, aunque el botón no sea un elemento secundario directo del elemento principal:
QPushButton *button = parentWidget->findChild<QPushButton *>("button1");
Devuelve un hijo QListWidget en parentWidget:
QListWidget *list = parentWidget->findChild<QListWidget *>();
Devuelve un elemento secundario de QPushButton llamado "botón1" en parentWidget (su padre directo):
QPushButton *button = parentWidget->findChild<QPushButton *>("button1", Qt::FindDirectChildrenOnly);
Devuelve un hijo QListWidget dentro de parentWidget (su padre directo):
QListWidget *list = parentWidget->findChild<QListWidget *>(QString(), Qt::FindDirectChildrenOnly);
conectar
Cómo escribir conectar
expresión lambda de conectar
connect(pushButton, &QPushButton::clicked, [=](){
...});
// [=]代表把外部所有局部变量、类中所有成员以值的传递方式;如果当前connect处于某个函数中,则表示当前函数下的所有变量、类中所有成员以值的传递方式
// [this]代表把类中所有成员以值的传递方式
// [&]代表把外部所有局部变量、类中所有成员以引用的传递方式;如果当前connect处于某个函数中,则表示当前函数下的所有变量、类中所有成员以引用的传递方式
// ()传递过来的参数
connect(m_var, &QPushButton::sigSetVar, [=](const VarData& data) mutable {
...});
//如果参数为const类型,并且后面使用到该参数,比如赋值之类的,需要写mutable,去掉const属性
Captura de valor [=] y captura de referencia [&] en lambda
Captura por valor[=]
ProjectTreeModelData varModelData = varStandardItem->data(Qt::UserRole + 1).value<ProjectTreeModelData>();
connect(colorWidget, &ColorSelectedDialog::sigBasicColor, [=](const QColor& color) mutable {
//此时获得是varModelData的副本
varModelData.variable.variableData.lineColor = color.name(); //若color是蓝色
colorWidget->close();
});
//因为上面的赋值是赋给varModelData的副本,这里的setData中varModelData中lineColor还是原来的颜色
varStandardItem->setData(QVariant::fromValue(varModelData), Qt::UserRole + 1);
//此时获得的varModelData中lineColor还是原来的颜色,并没有改变为蓝色
varModelData = varStandardItem->data(Qt::UserRole + 1).value<ProjectTreeModelData>();
Captura por referencia [&]
ProjectTreeModelData varModelData = varStandardItem->data(Qt::UserRole + 1).value<ProjectTreeModelData>();
connect(colorWidget, &ColorSelectedDialog::sigBasicColor, [&](const QColor& color) mutable {
//此时获得是varModelData本身,而非副本
varModelData.variable.variableData.lineColor = color.name(); //若color是蓝色
colorWidget->close();
});
//因为上面的赋值是赋给varModelData结构本身,这里的setData中varModelData中lineColor已成为蓝色
varStandardItem->setData(QVariant::fromValue(varModelData), Qt::UserRole + 1);
//此时获得的varModelData中lineColor变为蓝色
varModelData = varStandardItem->data(Qt::UserRole + 1).value<ProjectTreeModelData>();
Antes de enviar una señal, primero se debe establecer una conexión.
Por ejemplo, al enviar datos a otra interfaz, la conexión debe establecerse primero en esa interfaz; de lo contrario, el lado de ejecución de la señal no recibirá los datos.
Para otro ejemplo, debes escribir connect antes de exec() en una interfaz, porque exec() bloqueará el siguiente código.
Generalmente, está escrito en el constructor y comienza a monitorear durante la inicialización. Las situaciones específicas se abordarán caso por caso.
Connect está anidado en connect, preste atención a las conexiones repetidas.
connect(addVarAct, &QAction::triggered, [=]() {
connect(SignalsMedium::getInstance(), &SignalsMedium::sigBasicVarInfo,
[=](const VarBasicData& varinfo) mutable {
addVariable(blockStandardItem, varinfo); });
Problema: Connect está anidado dentro de connect, lo que hace que el connect interno se conecte repetidamente.
Solución: use desconectar para desconectar
connect(addVarAct, &QAction::triggered, [=]() {
connect(SignalsMedium::getInstance(), &SignalsMedium::sigBasicVarInfo,
[=](const VarBasicData& varinfo) mutable {
addVariable(blockStandardItem, varinfo); });
...
/** 必须断开连接,否则会每点一次就会多连接一次,造成重复连接 **/
disconnect(SignalsMedium::getInstance(), &SignalsMedium::sigBasicVarInfo, 0, 0);
parámetros de conexión
Una señal se puede conectar a múltiples ranuras y señales. Si una señal está conectada a varias ranuras, cuando se emita la señal, las ranuras se activarán en el orden en que fueron conectadas.
enumeración Qt::Tipo de conexión
Constante | Valor | Descripción |
---|---|---|
Qt::Autoconexión | 0 | (Predeterminado) Utilice Qt::DirectConnection si el receptor está en el hilo que emitió la señal. De lo contrario, utilice Qt::QueuedConnection. Determina el tipo de conexión al señalizar. |
Qt::Conexión Directa | 1 | Esta ranura se llama inmediatamente cuando se emite la señal. Las ranuras se ejecutan en el mismo hilo. |
Qt::Conexión en cola | 2 | Esta ranura se llama cuando el control regresa al bucle de eventos del hilo receptor. La ranura se ejecuta en el hilo del receptor. |
Qt::Bloqueo de conexión en cola | 3 | Igual que Qt::QueuedConnection, excepto que el hilo de señal se bloquea hasta que regresa la ranura. Esta conexión no se puede utilizar si el remitente y el receptor están en el mismo hilo; de lo contrario, la aplicación se bloqueará. |
Qt::Conexión única | 0x80 | Este es un indicador que se puede usar en combinación con cualquiera de los tipos de conexión anteriores usando OR bit a bit. Si la señal actual y la ranura se han conectado, ya no estarán conectadas para evitar conexiones repetidas. |
Cómo evitar conexiones repetidas en connect
Especialmente si la conexión está anidada dentro de la conexión, es particularmente fácil causar conexiones repetidas dentro de la conexión.
Solución:
(1) desconectar; (en algunos casos, si cada conexión interna maneja cosas diferentes, es mejor usar desconectar)
(2 ) ) Escriba connect en la estructura; (No todas las conexiones se pueden escribir en la estructura. Si una interfaz no es nueva en la estructura, la conexión vinculada a la interfaz no será válida) (3) blockSignals (bloquee todas las señales de
la se envían los controles);
(4) Qt::UniqueConnection; (En algunos casos, si cada conexión interna maneja lo mismo, se usa Qt::UniqueConnection)
Sobrecarga de la función de conexión de ranura de señal y problemas de inconsistencia de parámetros
El método de escritura QT5 provoca errores de compilación
connect(m_thread, &QThread::started, m_timer, &QTimer::start); //线程开始,定时器开始
Motivo: start() es una función sobrecargada. Dado que QT5 no indica parámetros de esta manera , el compilador no puede determinar qué función está conectada e informa un error. Solo
se puede utilizar el método de escritura QT4.
connect(m_thread, SIGNAL(started()), m_timer, SLOT(start())); //线程开始,定时器开始
Cuando se hace clic con el mouse del cuadro de diálogo fuera de la ventana, la ventana se cerrará.
Diálogo para modales
- Establezca el atributo de la ventana en Qt::Popup para cerrar automáticamente la ventana haciendo clic fuera de la ventana.
setWindowFlags(Qt::Popup);
Los dos métodos siguientes no son aplicables a los cuadros de diálogo modales, sino solo a los cuadros de diálogo y widgets no modales.
- Anule el evento de clic del mouse (mousePressEvent()). Si la posición del mouse no está dentro del área de la ventana, cierre la ventana.
- Anule el evento de pérdida de foco (focusOutEvent()). Si la ventana pierde el foco, ciérrela
Índice de modelo Q
Devuelve el índice hermano de la fila y columna del índice actual.
QModelIndex::sibling(int row, int column)
Los índices entre hermanos se pueden obtener entre sí, solo necesitas conocer las filas y columnas de los hermanos.
QModelIndex index0 = index1.sibling(index.row(), 0);
QModelIndex index3 = index1.sibling(index.row(), 3;
```cpp
QModelIndex index0 = index1.sibling(0, index.column());
QModelIndex index3 = index1.sibling(3, index.column());
Eliminar nodos secundarios del árbol
Ejemplo de error:
// 每移除一个子节点,其m_projectNameItem->rowCount()都会少1
//而移除的是m_projectNameItem->child(i),导致某些子节点没有删除
if (m_projectNameItem->hasChildren()) {
for (int i = 0; i < m_projectNameItem->rowCount(); ++i) {
removeStandardItem(m_projectNameItem->child(i), m_projectNameItem);
}
}
m_model->removeRow(m_projectNameItem->row());
Ejemplo correcto:
//先确定有多少个子节点
//每次都删第一个,才能保证删完
if (m_projectNameItem->hasChildren()) {
int count = m_projectNameItem->rowCount();
for (int i = 0; i < count; ++i) {
removeStandardItem(m_projectNameItem->child(0), m_projectNameItem);
}
}
m_model->removeRow(m_projectNameItem->row());
Eliminar recursivamente nodos secundarios de un árbol
removeStandardItem(QStandardItem* standardItem, QStandardItem* parentStandardItem) {
int count = standardItem->rowCount();
if (0 == count) {
parentStandardItem->removeRow(standardItem->row());
return;
}
for (int i = 0; i < count; ++i) {
QStandardItem* childStandardItem = standardItem->child(0);
removeStandardItem(childStandardItem, standardItem);
}
parentStandardItem->removeRow(standardItem->row());
}
QLine
setText activará la señal textChanged de QLineEdit
Establecer estado no editable:
setReadOnly(true); //只读
Conversión entre coordenadas actuales y coordenadas globales
QRect toolRect = geometry();
QPoint point(geometry().x + 100, geometry().y());
QPoint globalPoint = mapToGlobal(point);
Determinar si el foco actual está en un control.
hasFocus();
Qt gana y pierde eventos de enfoque
Anular la función focusInEvent()
de suma del controlfocusOutEvent()
void focusInEvent(QFocusEvent *event) override;
void focusOutEvent(QFocusEvent *event) override;
Comparación sobre la lista
//错误示范
if (RTTVarList.at(i).basic == varModelData.variable.variableData.basic) {
...}
//正确示范
//list的at()是const类型的,放在==的右边
if (varModelData.variable.variableData.basic == RTTVarList.at(i).basic) {
...}
Arrastrar Cómo mostrar el signo de arrastre deshabilitado
Implementado en dragMoveEvent (evento QDragMoveEvent*), aparecerá un letrero deshabilitado al moverse a ciertas posiciones
//当鼠标移动到rect里面时,接受该事件,否则忽略该事件,就会出现禁用标志
void dragMoveEvent(QDragMoveEvent* event){
QRect rect(0,0,100,30);
if(ret.contains(event.pos())){
event->accept();
}else{
event->ignore();
}
}
Cuadro de diálogo QFile
enumeración QFileDialog::AcceptMode
Estilo de apertura del cuadro de diálogo de archivo
- AceptarAbrir: abre el archivo
- AceptarGuardar: Guarda el archivo
enumeración QFileDialog::DialogLabel
Para etiquetas en cuadros de diálogo, puede usar setLabelText() para configurar el texto en la etiqueta.
Buscar en
Nombre de archivo
Tipo de archivo
Aceptar
Rechazar
El problema de que setFocus no surte efecto
No puedes configurar Focus cuando tu widget aún no está visible, eso no funcionará.
La forma de resolver este problema es poner la operación setFocus() en **showEvent()** de nuestro componente.
Generalmente nos gusta poner setFocus al final del constructor, pero esto muchas veces no tiene ningún efecto, este es el problema.
void DisplayWidget::showEvent(QShowEvent* event) {
Q_UNUSED(event);
m_osciNameLine->setFocus();
}