Qt常用控件、警告与问题总结

Qt Creator 转 Visual Studio

Qt Creator转Visual Studio

在pro文件所在文件夹,打开cmd

qmake -tp vc [x]

Visual Studio转Qt Creator

Qt VS Tools->Convert Project to Qt VS Tools Project

QT开发总结

样式表(QSS)

  1. 创建样式表

    1. 新建文本文档,后缀改为*.qss*。
    2. qss以ANSI格式编码,UTF-8无BOM。
  2. 加载样式表

    1. 静态加载

      1. 同加载资源文件。
    2. 动态加载

      1. 路径写为绝对路径
      #include <QFile>
      
      QString qss;
      QFile qssFile(":/styles/qstylesheet.qss");
      qssFile.open(QFile::ReadOnly);
      if(qssFile.isOpen())
      {
          qss = QLatin1String(qssFile.readAll());
          qApp->setStyleSheet(qss);
          qssFile.close();
      }
      
  3. 使用样式表

    1. 加载样式表后,选择器

letter-spacing: 5.1.2才有

Alignment

enum Qt::AlignmentFlag
flags Qt::Alignment

This enum type is used to describe alignment. It contains horizontal and vertical flags that can be combined to produce the required effect.

The TextElideMode enum can also be used in many situations to fine-tune the appearance of aligned text.

The horizontal flags are:

ConstantValueDescription
Qt::AlignLeft0x0001Aligns with the left edge.
Qt::AlignRight0x0002Aligns with the right edge.
Qt::AlignHCenter0x0004Centers horizontally in the available space.
Qt::AlignJustify0x0008Justifies the text in the available space.

The vertical flags are:

ConstantValueDescription
Qt::AlignTop0x0020Aligns with the top.
Qt::AlignBottom0x0040Aligns with the bottom.
Qt::AlignVCenter0x0080Centers vertically in the available space.
Qt::AlignBaseline0x0100Aligns with the baseline.

You can use only one of the horizontal flags at a time. There is one two-dimensional flag:

ConstantValueDescription
Qt::AlignCenterAlignVCenter | AlignHCenterCenters in both dimensions.

You can use at most one horizontal and one vertical flag at a time. Qt::AlignCenter counts as both horizontal and vertical.

Three enum values are useful in applications that can be run in right-to-left mode:

ConstantValueDescription
Qt::AlignAbsolute0x0010If the widget’s layout direction is Qt::RightToLeft (instead of Qt::LeftToRight, the default), Qt::AlignLeft refers to the right edge and Qt::AlignRight to the left edge. This is normally the desired behavior. If you want Qt::AlignLeft to always mean “left” and Qt::AlignRight to always mean “right”, combine the flag with Qt::AlignAbsolute.
Qt::AlignLeadingAlignLeftSynonym for Qt::AlignLeft.
Qt::AlignTrailingAlignRightSynonym for Qt::AlignRight.

Masks:

ConstantValue
Qt::AlignHorizontal_MaskAlignLeft | AlignRight | AlignHCenter | AlignJustify | AlignAbsolute
Qt::AlignVertical_MaskAlignTop | AlignBottom | AlignVCenter | AlignBaseline

Conflicting combinations of flags have undefined meanings.

The Alignment type is a typedef for QFlags. It stores an OR combination of AlignmentFlag values.

QLabel

设置文字对齐方式,QSS的text-align有时会失效,使用:

qproperty-alignment:'AlignRight|AlignBottom';

QToolButton与QPushButton

QToolButton: 图标按钮

QPushButton: 文字按钮

QTableWidget

ui->tableWgt->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); //设置表头填充表格
ui->tableWgt->horizontalHeader()->setHighlightSections(false); // 设置点击时表头不亮
// 选中整行
ui->tableWgt->setSelectionBehavior(QTableWidget::SelectRows);
ui->tableWgt->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableWgt->setContentsMargins(10, 0, 10, 0);
ui->tableWgt->setColumnCount(6);
ui->tableWgt->horizontalHeader()->setFixedHeight(36);

一般样式设计

setSelectionBehavior(QAbstractItemView::SelectRows); // 选中整行
horizontalHeader()->setHighlightSections(false);     // 设置点击时表头不亮

双击item字体不变色

设置代理

class ItemDelegate : public QItemDelegate
{
    Q_OBJECT
public:
    ItemDelegate()
    {

    }

private:
    void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index)
    {
        QStyleOptionViewItem itemOption(option);
        QColor ItemForgeroundColor = index.data(Qt::ForegroundRole).value<QColor>();
        if(ItemForgeroundColor.isValid())
        {
            if(ItemForgeroundColor != option.palette.color(QPalette::WindowText))
            {
                itemOption.palette.setColor(QPalette::HighlightedText, ItemForgeroundColor);
            }
        }
        QItemDelegate::paint(painter, itemOption, index);
    }
};

//使用:
ui->tablewidget->setItemDelegated(new ItemDelegate());  

拖拽item

ui设置:

setDragDropMode(QAbstractItemView::DragDrop);      // 设置拖拽
setDropIndicatorShown(true);                       // 显示拖拽

拖拽接收:

bool eventFilter(QObject *watched, QEvent *event)
{
    switch (event->type())
    {
    // 拖拽
    case QEvent::DragEnter:
    {
        emit /*signal*/;
        break;
    } 
    }
}

// 必须重载以下三个函数
void dragEnterEvent(QDragEnterEvent *event)
{
    // 验证传入的控件
    QObject *source = event->source();

    if (source->metaObject()->className() != QStringLiteral("QTreeWidget")) {
        event->ignore();
        return;
    }
    event->acceptProposedAction();
}

void dragMoveEvent(QDragMoveEvent *event)
{
    if (event->source() == this)
    {
        event->setDropAction(Qt::MoveAction);
        event->accept();
    }
    else
    {
        event->acceptProposedAction();
    }
}

void dropEvent(QDropEvent *event)
{
    emit /*signal*/;

    return;
}

QComboBox

QStringList cmbxObject;
cmbxObject << QStringLiteral("label1") << QStringLiteral("label2") << QStringLiteral("label3");
ui->cbObject->addItems(cmbxObject);
ui->cbObject->setCurrentIndex(0);

隐藏item

QListView* view = dynamic_cast<QListView*>(ui->cmbxObject->view());
if (view != nullptr) {
    view->setRowHidden(1, true);
}

QSplitter

分离部件,用于布局

QT窗口操作函数(置顶、全屏,最大化最小化按钮设置)

窗口置顶 与 取消置顶

void MainWindow::on_windowTopButton_clicked()
{
    if(m_flags == nullptr)
    {
        m_flags = windowFlags();
        setWindowFlags(m_flags | Qt::WindowStaysTopHint);
        this->show();
    }
    else
    {
        m_flags = nullptr;
        setWindowFlags(m_flags);
        this->show();
    }
}

全屏显示 与 退出全屏

showFullScreen();	// 全屏显示函数
showNormal();	// 退出全屏函数
showMaximized();	// 最大化函数
showMinimized();	// 最小化函数
resize(x, y);		// 固定尺寸显示
setMaximumSize(w, h);	// 最大尺寸函数
setMinimumSize(w, h);	// 最小尺寸函数

其中showFullScreenshowNormal只对顶层窗口有效,对子窗口无效。用下面的方法将子窗口升成顶层窗口。

  • 对子窗口使用setWindowFlags(Qt::Window)升成顶层窗口,然后调用showFullScreen
  • 全屏后恢复正常,调用setWindowFlags(Qt::subWindow),将子窗口设置为非顶层窗口,再调用showNormal恢复正常。

最大化、最小化、关闭按钮

1、在Dialog中添加最大化、最小化、关闭按钮。

this->setWindowFlags(Qt::Dialog | Qt::WindowMinMaxButtonHint | Qt::WindowCloseButtonHint);

WindowMinMaxButtonHint设置最大和最小按钮,只设置这个,关闭按钮不可用,因此需要添加WindowCloseButtonHint

2、只禁止最大化按钮

this->setWindowFlags(windowFlags() &~ Qt::WindowMaximizedButtonHint);

WindowMaximizedButtonHintWindowType枚举数量,通过修改它可以选择禁止”最小化“或者”关闭“按钮。

3、禁止屏幕拖动

this->setFixedSize(this->width(), this->height());

4、获取屏幕的宽度和高度

QApplication::desktop()->width();
QApplication::desktop()->height();

QString与int互相转换

QString转int

// 1、toInt()
QString str("100");
int tmp = str.toInt();
// 2、
bool ok;
QString str("100");
int tmp = str.toInt(&ok);

int转QString

int tmp = 100;
QString str = QString::number(tmp);

跨组件传递信号

一个父级组件有两个子级组件,子组件A传递信号给子组件B。

方法一,使用代理模式

方法二,绑定组件

QListWidgetItem *pItem   = new QListWidgetItem();
QPushButton* pBtn = pWgtItem->getBtn();
connect(pBtn, SIGNAL(clicked()), this, SLOT(s_showWgtChat()));

插入像素图pixmap

QTableWidget中插入像素图。

效果图:

image-20211228115222345

代码:

// 1. 创建QPixmap对象,绑定路径(绝对/相对都可),设置大小、缩放。
// 绝对路径
QPixmap piximg("D:/images/icons/arrow_double_to_right.png"); 
// 相对路径
// QPixmap piximg(":/icons/arrow_double_to_right.png"); 
piximg = piximg.scaled(32, 32, Qt::KeepAspectRatio, Qt::SmoothTransformation);

// 2. 创建QLabel,绑定QPixmap。
QLabel *l1 = new QLabel();
l1->setPixmap(piximg);
//    l1->setMaximumSize(32, 32);
//    l1->setScaledContents(true);
l1->setAlignment(Qt::AlignHCenter); // 居中

// 3. 设置表格中的位置
ui->wgtTableCalling->setCellWidget(i, 1, l1);

QT所有字体

QFontDatabase database;
foreach(const QString &family, database.families(QFontDatabase::Any))
{
    qDebug() << family;
}

widget不显示

日志(重写QLog.h)

Qt输出日志到指定文件只需重写QLog.h

  1. pro文件中添加“DEFINES += QT_MESSAGELOGCONTEXT”,打印日志不需要输入“__LINE__”;

    // 1: 添加
    qDebug() << __FUNCTION__:
    // 2: 不添加
    qDebug() << __FUNCTION__ << __LINE__;
    
  2. 主函数中安装重写的日志函数:

// 安装日志函数
setLogParam(argc, argv);
qInstallMessageHandler(installLog);
deleteLog(30);


### 日志类型

```c++
// 一般信息
#define qDebug QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC).debug
// 信息
#define qInfo QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC).info
// 警告
#define qWarning QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC).warning
// 严重错误
#define qCritical QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC).critical
// 致命错误
#define qFatal QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC).fatal

QDebug

#include <QDebug>

qDebug() << "HelloWorld";
int num = 0;
QString str = "HelloWorld";
qDebug("num = %d, str = %s", num, str);
// %x

QT 编译代码警告总结

QT 5.9.6,C++ 11,Clang编译

zero as null pointer constant

C++11中使用NULL代替nullptr

C++中NULL定义为整数0:

#ifndef NULL
#ifdef __cplusplus
  #define NULL 0
#else
  #define NULL ((void *)0)
#endif
#endif

use of old-style cast

类型转换

类型1

int iNum = 10;
// warning: use of old-style cast
double dNum1 = (double)iNum / 10;
// 使用静态或动态cast
double dNum2 = static_cast<double>(iNum / 10);

static_cast运算符

静态强制转换

仅 基于表达式 中的类型,将表达式转换为 type-id 的类型。

语法

static_cast(expression)

备注

static_cast是静态强制转换,不执行 运行时类型检查

dynamic_cast动态强制转换,会执行检查,dynamic_cast仅适用于指针或引用。

类型2

// warning: use of old-style cast
QImage *img1 = (QImage*)img;
// 直接new
QImage *img2 = new QImage;

QT开发问题总结

构建与运行

virtual struct QMetaObject const

*error LNK2001:解析的外部符号 “public:virtual struct QMetaObject const __thiscall Xxxx::metaObject(void)const”(?metaObject@xxx……)

  1. 检查pro中文件类型是否正确。
  2. 项目内有同名文件、类、函数。

模块计算机类型“X86”与目标计算机类型“x64”冲突

error: LNK1112: 模块计算机类型“X86”与目标计算机类型“x64”冲突

方法一:工具->选项->构建与运行->构建套件->选择使用的构建套件,下方C、C++调整位“amd64_x86”(32位)

方法二:删除Qt工程文件,重新用Qt打开项目pro文件选择32位。

No executable specified

删除项目根目录的ProtectName.pro.user

QNativeSocketEngine::hasPendingDatagrams() was called in QAbstractSocket::UnconnectedState

端口被占用

UI

Unknown property letter-spacing、font-stretch

QStyleSheet没有以上属性。

QFSFileEngine::open: No file name specified

未找到原因

QTableWidget::sortByColumn导致显示不全问题

原因是后续插入cell的数据如果符合排序的条件,会触发QTablewidget立即重新排序;
例:QTablewidget按第0列降序,插入第一行正常, 插入(1, 0) > (0, 0)时, tablewidget会将两行互换,交换之后第二行是原本第一行的数据,第一行是第二行的数据,此时第一行除了(0, 0)数据其他cell都为空继续插入(1, j)时,会覆盖掉重新插入数据。

解决方法:在插入数据前关闭排序,插入完启用排序

// 1. 控件设置
ui->tablewidget->setSortingEnabled(true);
ui->tablewidget->sortByColumn(0, Qt::DescendingOrder);

// 2. 插入数据前后关闭和开启
ui->tablewidget->setSortingEnabled(false);
for (int i = 0; i < vecTmpLog.size(); i++)
{
    tableShowList.clear();
    tableShowList << vecTmpLog[i].getStrId().toStdString().c_str() \
        << vecTmpLog[i].getStrTime().toStdString().c_str() \
        << vecTmpLog[i].getStrDeviceID().toStdString().c_str();

    ui->tablewidget->insertRowData(tableShowList, vecTmpLog[i].getStrId());
    ui->tablewidget->setItemToolTip(i, 0, vecTmpLog[i].getStrId());
}
ui->tablewidget->setSortingEnabled(true);

QPaintDevice::metrics: Device has no metric information

一般是手误把QTableWidget->columnCount()写成QTableWidget->colorCount(),不会报错,但会警告QPaintDevice::metrics: Device has no metric information

QSqlDatabase

2022-09-16 15:56:13:673 [Warning] QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
2022-09-16 15:56:13:674 [Warning] QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
2022-09-16 15:56:13:674 [Warning] QSqlDatabasePrivate::removeDatabase: connection 'connectionMsg' is still in use, all queries will cease to work.
2022-09-16 15:56:13:674 [Warning] QSqlDatabasePrivate::addDatabase: duplicate connection name 'connectionMsg', old connection removed.
  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值