Qt知识点梳理

一、杂记
    //管理整个应用程序所用到的资源
    QApplication a(argc, argv);

    ///将应用程序的控制权传递给Qt,程序进入事件循环,等待鼠标,键盘等事件

    return a.exec();

    ///这句初始化静态窗体,内部建立所需要的信号和槽对应

    ui->setupUi(this);

img = img.rgbSwapped(); //BGR 转RGB
rightTip->setAlignment(Qt::AlignCenter | Qt::AlignRight);//对齐方式
//获得当前程序所在目录
return QApplication::applicationDirPath();
//设置图标
this->setWindowIcon(QIcon(":/16-9/LOGO.png"));
//设置外部字体
    nIndex = QFontDatabase::addApplicationFont(path + QStringLiteral("/微软vista雅黑.ttf"));
    if (nIndex != -1)
    {
        QStringList strList(QFontDatabase::applicationFontFamilies(nIndex));
        if (strList.count() > 0)
        {
            font.setFamily(strList.at(0));
            font.setPixelSize(FONT_SIZE *scale * 90 / 72);
        }
    }

//设置style
m_centralWidget->setStyleSheet("QWidget#centralWidget{background-color:rgb(242, 242, 242,180)};");
//管理多个信号对应同一个槽,很好用

QSignalMapper signalMapper;

    for(int i=0;i<btn_count;i++)
    {
        signalMapper.setMapping(btn_custom+i,i);
        connect(btn_custom+i,SIGNAL(clicked(bool)),&signalMapper,SLOT(map()));
    }
    connect(&signalMapper,SIGNAL(mapped(int)),this,SLOT(onToolAction(int)));


//设置窗体透明,在没有父窗口的情况下可以生效,不会显示黑色。
    leftDownBox->setWindowFlags(Qt::FramelessWindowHint);
    leftDownBox->setAttribute(Qt::WA_TranslucentBackground);

//遍历父窗口上的子控件
    QList<CustomToolBtn*> Widgets = customBtnWidget->findChildren<CustomToolBtn*>();
    if(!Widgets.isEmpty())
    {
        foreach(CustomToolBtn* obj ,Widgets)
        {
            delete obj;
        }
    }
//打开窗口获取文件或者文件夹路径

    QStringList filePath;
    QFileDialog *fileDialog = new QFileDialog(this);
    fileDialog->setWindowTitle(tr("Open Image"));
    fileDialog->setFileMode(QFileDialog::ExistingFiles);
    fileDialog->setDirectory(".");
    fileDialog->setNameFilter("*.png *.bmp *.jpg");
    if(fileDialog->exec() == QDialog::Accepted)
    {
        filePath = fileDialog->selectedFiles();
        // QMessageBox::information(NULL, tr("Path"), tr("You selected ") + path);
    }
    //程序只能启动一个
    QSharedMemory shared("name");//随便填个名字就行
    if (shared.attach())
         return 0;
    shared.create(1);

//线程 例子
MovieShow::MovieShow(QObject *parent) : QThread(parent)
{
    m_mMovie = NULL;
    m_bstop = true;
    obj = parent;
}
MovieShow::~MovieShow()
{
    if(m_mMovie!=NULL)
    {
        m_mMovie->stop();
        delete m_mMovie;
        m_mMovie = NULL;
    }
    endMovie();
    quit();
    terminate();
    //wait();
}
void MovieShow::startMovie()
{
    QMutexLocker mutex(&mtx);
    m_bstop = false;
    if(NULL!=m_mMovie)
    {
        m_mMovie->start();
        count = 0;
    }
    this->start();
}
void MovieShow::endMovie()
{
    QMutexLocker mutex(&mtx);
    m_bstop = true;
}
void MovieShow::setMovie(const QString &path)
{
    m_strPath = path;
    if(NULL == m_mMovie)
    {
        m_mMovie = new QMovie(m_strPath);
    }
}
QPixmap& MovieShow::getCurrentPix()
{
    return m_mMovie->currentPixmap();
}
void MovieShow::run()
{
    while(1)
    {
        QPixmap pix = m_mMovie->currentPixmap(); ;
        msleep(500);
        emit sendCurrentPix(QPixmap(pix));
        if(m_bstop)
        {
            break;
        }
    }
}

///在静态的界面里修改了控件的一些属性,需要重新构建才会起作用,如果发现没有修改,重新构建下或许能解决问题

二、父子机制与布局管理


///当使用布局的时候,没有必要显式的指定父窗口,布局会自动设置父窗口

    Qt的父子对象机制是在QObject中实现的。当利用一个父对象创建一个子对象(QLabel *label = QLabel(this);)父对象会把这个子对象添加到自己的子对象列表中去,见上图。当删除这个父对象时,它会遍历子对象列表并且删除每一个子对象。然后,这些子对象再去 删除它们包含的子对象列表中的对象。如此反复递归调用,直至清空所有对象为止。这种父子对象机制可在很大程度上简化内存管理工作,降低内存泄漏的风险。没有指定父对象的需要手动删除

(如果在删除父对象之前删除了子对象是可以的,父对象会自动把删掉的子对象从列表中移除,但是删除了父对象后再去删除子对象就会出错,因为子对象已经被删掉了)

记:在开发中各种情况都可能遇到,有的时候删除了父对象,还会报其他错误(内存泄漏什么的),所以就手动一层层删。有的时候改的多了,程序关上会报内存错误,重新构建就没事了,当然以上说的都是windows平台,切记多执行qmake多重新构建构建。 

布局管理:当子控件隐藏或者动态删除或者又show的时候,也能自动适应

QSizePolicy的 Preferred  Expanding策略

Preferred:窗口部件的默认大小就是它比较合适的大小,但是如果需要,还是可以对该窗口部件进行拉伸或者压缩  

Expanding:是可以拉伸或者压缩该窗口部件,并且希望他能变长变宽。

多出来的窗口空间会分配给Expanding窗口部件,而preferred窗口部件不变。

影响布局的方式:

1.布局拉伸因子:setstretch()

2.margin

3.space

4.子窗口部件的最小大小,最大大小或固定大小,当布局管理器在摆放这些窗口部件的时候,它就会考虑这些约束条件

5.对子窗口部件的类进行派生并且重新实现sizeHint()函数,由此获得所需的大小。

三、信号与槽
    ///信号槽必须的 
    Q_OBJECT

///signals关键字实际上是一个宏,C++预处理器会在编译程序找到它之前转为标准c++代码

///同理slots也是

///槽和普通c++成员函数几乎一样,可以是虚函数,可以被重载,可以是public protected private
/// 也可以直接被其它成员函数调用,参数可以是任意类型。唯一不同,槽函数可以和信号连接,每当发射信号,
/// 对应的槽函数会自动执行
/// 一个信号可以连接多个槽
/// 多个信号可以连接同一个槽
/// 一个信号可以与另一个信号连接
/// 连接可以被移除 disconnect
/// 要使信号和槽成功链接,它们的参数必须具有相同的顺序和相同的类型
/// (如果信号参数比它连接的槽的参数多(其他都符合规则)那么多余的参数会被简单的忽略掉)
/// connect(sender,SIGNAL(signal(int)),receiver,SLOT(slot(int val)); 这样是错误的,要把参数名删掉 否则报错找不到对应的槽
四、处理密集时响应保持
1.多线程:在线程里处理耗时操作(文件读写,但是不能刷新界面),然后通过信号槽的方式,通知主线程刷新界面

2.

QCoreApplication::processEvents();

或者qApp->processEvents();  这个函数告诉主线程处理那些还没有被处理的 各类事件,然后再将控制权返回给调用者。

实际上QApplication::exec();就是一个不断调用processEvents的循环过程。

五、事件
事件发生的先后顺序:

1.子类化QApplication并且重新实现notify()

2.在QApplication对象中安装事件过滤器

3.在QObject中安装事件过滤器

4.重新实现QObject::event()

5.重新实现某些特定的事件(mousePressEvent,paintEvent等)

处理ocx控件的windows,查了好久才查到。
qApp->installNativeEventFilter(liveDetectWdg);
bool LiveDetect::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
    //捕捉ocx发送的自定义消息
    MSg *param = static_cast<MSg *>(message);
    if(param && param->message<=1828 && param->message>=1824)
    {
        emit sendUserMessage(param->message);
    }
    //当窗口关闭的时候,发送个1827结束下事件循环
    if(param->message == 16)
    {
        emit sendUserMessage(1827);
    }
    /*switch (param->message)
    {
    case 1824:
    {
    }
        break;
    case 1825:
    {
    }
        break;
    }*/
    return false;
}

六、跨平台
#ifdef Q_OS_WIN
#define WINAPI __stdcall
#define IDCardDLLSO "xxx.dll"
#define UpLoadDLLSO "yyy.dll"
#endif
 // Linux上的代码
#ifdef Q_OS_LINUX
#define UNICODE
#define WINAPI
#define IDCardDLLSO "./xxx.so"
#define QStringToTCHAR Qstr2lpc
#endif
// Mac上的代码
#ifdef Q_OS_MAC
#endif
#define LPCWSTR const wchar_t*
#define LPWSTR  wchar_t*
#ifdef UNICODE
typedef wchar_t TCHAR;
#define WINAPI __stdcall
#define LPCTSTR const wchar_t*
#define LPTSTR wchar_t*
#else
typedef  char TCHAR;
typedef const char* LPCTSTR;
typedef  char* LPTSTR;
#endif
#define _T QStringLiteral
#ifdef UNICODE
#define QStringToTCHAR(x)     (wchar_t*) x.utf16()
#define PQStringToTCHAR(x)    (wchar_t*) x->utf16()
#define TCHARToQString(x)     QString::fromUtf16((x))
#define TCHARToQStringN(x,y)  QString::fromUtf16((x),(y))
#else
#define QStringToTCHAR(x)     x.local8Bit().constData()
#define PQStringToTCHAR(x)    x->local8Bit().constData()
#define TCHARToQString(x)     QString::fromLocal8Bit((x))
#define TCHARToQStringN(x,y)  QString::fromLocal8Bit((x),(y))
#endif
--------------------- 
作者:小卒曹阿瞒 
来源:CSDN 
原文:https://blog.csdn.net/qq_28119741/article/details/79484112 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值