Archive for the ‘QT’ Category

QT拖拽文件、文件夹及遍历文件夹简单案例

星期五, 九月 19th, 2014 137 views

首先是实现QT的窗体拖拽功能将文件拖拽进入Mainwindow,需要实现代码如下:

1
2
3
4
5
6
7
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setAcceptDrops(true);//将Mainwindow设置成可相应拖拽事件
}

这里的 setAcceptDrops(true); 将Mainwindow设置成可相应拖拽事件,接下来,重载dragEnterEvent和dropEvent方法,实现对拖拽内容的判断和操作,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//拖入Mainwindow时触发
void MainWindow::dragEnterEvent(QDragEnterEvent  *event){
    if(event->mimeData()->hasUrls())
    {
        foreach(QUrl url, event->mimeData()->urls())
        {
            if(!url.isEmpty())
                event->accept();//界面反馈表示可拖拽
        }
        return;
    }
    else
    {
        event->ignore();//界面反馈表示不可拖拽
    }
}

//松开鼠标后触发
void MainWindow::dropEvent(QDropEvent *event)
{
    if(event->mimeData()->hasUrls())
    {
        foreach(QUrl url, event->mimeData()->urls())
        {
            QFileInfo fileInfo(url.toString());
            QString filePath = fileInfo.filePath().remove(0, QDir::currentPath().size() + 9);

            if(fileInfo.fileName().contains(".")){//根据是否带"."判断是否是文件夹
                //属于文件
            }else{
                //属于文件夹
                FindFile(filePath);//遍历文件夹递归函数
            }
        }
        return;
    }
    return;

}

(更多…)

QT实现启动画面

星期三, 九月 10th, 2014 35 views

代码如下,详解见注释,效果请自行编译运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include "mainwindow.h"
#include <QApplication>
#include <QSplashScreen>
#include <QPixmap>
#include <QTextCodec>
#include <QElapsedTimer>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);


    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForLocale(codec);


    QSplashScreen splash(QPixmap("./images/logo.png"));
    splash.setDisabled(true); //禁用用户的输入事件响应 否则点击会消失
    splash.show();

    splash.showMessage(QString::fromUtf8("检测版本信息中..."),
                       Qt::AlignCenter|Qt::AlignBottom,Qt::black);


    //实现延时2s
    int delayTime = 2;
    QElapsedTimer timer;
    timer.start();
    while(timer.elapsed() < (delayTime * 1000))
    {
        a.processEvents();
    }

    MainWindow w;
    splash.finish(&w);//关闭启动画面
    w.show();

    return a.exec();
}

BeiTown
2014.09.10

QWebView保存帐号密码功能实现

星期三, 八月 13th, 2014 241 views

以下用QT模拟一下常规浏览器对帐号密码的保存

首先是获取QWebview中的表单内容,需要保存的表单中的两个input如下:

1
2
帐号:<input name="username" type="text"/>
密码:<input name="password" type="password"/>

在QT中获取这两个input的值的需要使用带JS的方法,首先通过findFirstElement()方法找到目标标签,然后调用js方法获取其值,如下:

1
2
3
//获取帐号密码
qDebug()< <ui->webView->page()->mainFrame()->findFirstElement("#username").evaluateJavaScript("this.value").toString();
qDebug()< <ui->webView->page()->mainFrame()->findFirstElement("#password").evaluateJavaScript("this.value").toString();

具体在何处调用以上方法视应用设计的情况而定,这里我使用了QWebview::loadStarted()信号来触发,因为提交表单时必会触发这个信号。
(更多…)

QT使用单例模式获取主窗体Mainwindow指针

星期二, 七月 22nd, 2014 275 views

最近一直在用QT做项目,信号和槽机制甚是好用,但是前提需求是在connect时必须同时传入Object1和Object2的指针(见《QT 多线程(UI线程)间的signal/slot(信号与槽)通信》),这样一来,我们如果需要在其他类中绑定Mainwindow的槽函数,则必须在该类初始化时传入Mainwindow的指针,甚是麻烦。甚至有时是间隔了好几个类。
查询了网络上的一些方法,稍微可行一些的是使用parentWidget()方法,但是还是没有从根本上解决全局获取Mainwindow指针的问题。
既然是全局,我们的基本解决思路就是static化,实现起来其实也非常简单,使Mainwindow变成单例即可,代码如下:

首先是Mainwindow.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <qmainwindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    static MainWindow *GetInstance();//获取单例方法

private:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    Ui::MainWindow *ui;
    static MainWindow *m_pInstance;//单例指针

};

#endif // MAINWINDOW_H
</qmainwindow>

(更多…)

QT5读取及修改cookie简单样例

星期四, 七月 3rd, 2014 337 views

介于网上(中文网页)没有一篇完整的关于QT5读写cookie的简单案例,特有此篇。

①准备工作,定义cookie控制器
在开始获取cookie之前我们需要做一些准备工作,先在mainwindow下拖出一个webview,这里不上图了,以后会比较少上图,有些图华而不实,文字看得懂的自然都看得懂。
之后给这个webview定义一个networkAccessManager,#include什么的这些常识问题大家自己F1。

1
2
3
4
5
6
7
8
9
10
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    _cookieJar = new MyCookieJar();
    //这里设置networkAccessManager
    ui->webView->page()->networkAccessManager()->setCookieJar( _cookieJar );

}

上文中的_cookieJar是我们自己定义的一个MyCookieJar类,继承了QT自带的QNetworkCookieJar。
这里我自己封装了一些方法也放出来吧:

MyCookieJar.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef MYCOOKIEJAR_H
#define MYCOOKIEJAR_H
#include <qnetworkcookiejar>
#include <qnetworkcookie>
#include <qnetworkrequest>
class MyCookieJar : public QNetworkCookieJar
{
    Q_OBJECT
public:
    explicit MyCookieJar(QObject *parent = 0);

    QList<qnetworkcookie> getCookies();
    void setCookies(const QList</qnetworkcookie><qnetworkcookie>& cookieList);
    void addCookies(QString name,QString value);
    void changeCookie(QString name,QString value);
};
#endif // MYCOOKIEJAR_H
</qnetworkcookie></qnetworkrequest></qnetworkcookie></qnetworkcookiejar>

MyCookieJar.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "mycookiejar.h"

MyCookieJar::MyCookieJar(QObject *parent) :
    QNetworkCookieJar(parent)
{
}


QList<qnetworkcookie> MyCookieJar::getCookies()

{
    return  this->allCookies();
}

void MyCookieJar::setCookies(const QList</qnetworkcookie><qnetworkcookie>& cookieList)
{
    if(this == NULL)
        return;
    this->setAllCookies(cookieList);
}

void MyCookieJar::addCookies(QString name,QString value)
{
    QNetworkCookie cookie(name.toUtf8(),value.toUtf8());
    this->insertCookie(cookie);
}

void MyCookieJar::changeCookie(QString name,QString value)
{
    QNetworkCookie cookie(name.toUtf8(),value.toUtf8());
    this->updateCookie(cookie);

}
</qnetworkcookie>

(更多…)

关于QT中域名解析IP的方法(阻塞式)

星期四, 五月 2nd, 2013 103 views

最近在用QT制作一套网络安全工作,正巧需要实现域名解析出IP的一个功能,用winsock也可以实现,需要用到gethostbyname(url)方法,调用后返回的是一个HOSTENT结构体。但相对在QT中来处理这个结构体,各种位操作及字符指针的移动比较麻烦,同时也考虑到将来工具的跨平台性,趁早拜托对winsock的依赖为好,因此,还是用QT中实现域名解析的QHostInfo类来实现这项功能。

相对于winsock中的几十行代码,在QT中仅仅需要两行即可实现:

1
2
QHostInfo info=QHostInfo::fromName("www.beitown.com");
qDebug()<<info.addresses().first().toString()<<endl;

注意如果提示 QHostInfo : No such File or directory (找不到QHostInfo文件)请在.pro 文件添加 QT += network 即可.

本例为QHostInfo解析域名方法的其中之一,即可阻塞式方法。另外一种是使用信号与槽机制的非阻塞方法,实现原理类似,后续用到时另外开篇。

本篇到此,谢谢关注。

BeiTown
2013.05.02

QT 多线程(UI线程)间的signal/slot(信号与槽)通信

星期三, 五月 1st, 2013 956 views

写这篇的时候感觉有点像写之前Android主线程与子线程间的通信消息队列,其实需要这么做的原因基本相同,即QT在主线程(UI线程)中某些阻塞行为会造成UI的更新的阻塞,举例来说,在UI线程中创建一个while循环,并在这个while循环中对UI进行更新,运行结果是UI完全无响应,因为UI线程一直卡在while中无法跳出来去完成更新,虽然它不断的得到了更新UI的通知。

因此在本篇中我们将通过多线程的方式来解决此类问题。

QT中已经替我们实现了一个线程类QThread,我们只需要继承它就好。使用时只需->start()即可。

1
2
3
4
5
6
7
8
9
10
class MyThread : public QThread
{
Q_OBJECT
public:
    MyThread();
signals://定义一个信号
    void sendString(QString);
protected:
    void run();
};

上面的代码简单实现了一个线程类的头文件,这里注意一下定义的signals(信号)。
信号与槽是QT特有的一个通信机制,简单阐述一下其运用在线程间的工作流程。
(更多…)

QT paintEvent重绘事件及窗体圆角代码

星期日, 一月 27th, 2013 191 views

利用重回paintEvent重绘事件来进行窗体重绘,本例中使用一个圆角代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void MainWindow::paintEvent(QPaintEvent *){

    QBitmap objBitmap(size());
    //QPainter用于在位图上绘画
    QPainter painter(&objBitmap);
    //填充位图矩形框(用白色填充)
    painter.fillRect(rect(),Qt::white);
    painter.setBrush(QColor(0,0,0));
    //在位图上画圆角矩形(用黑色填充)
    painter.drawRoundedRect(this->rect(),10,10);
    //使用setmask遮罩
    setMask(objBitmap);

}

在mainwindow.cpp中直接添加 MainWindow::paintEvent 方法,主窗体运行时会自动调用该处的重绘代码。
本段代码使用了遮罩原理进行圆角绘制。举一反三后,其原理可以用到更多的地方。
最后效果如下:

注意,当使用了遮罩后,程序自带的标题框会消失,或者说是被覆盖了。
本文到此,感谢关注。

BeiTown
2013.01.27

QT外部调用qss样式表方法

星期日, 一月 27th, 2013 239 views

以利用qss样式在主窗口添加背景图片为例:

①新建qss文件
建立文本文件,内容先空着一会添加。更改文件后缀名为qss。本例中qss为style.qss

②创建qrc资源文件
右键点项目 “Add New(添加新文件)”->”QT Resource file(QT资源文件)” 生成一个qrc文件。本例中qrc为src.qrc

③将qss文件添加进qrc中
(更多…)

QT调用多个UI窗口的方法及error LNK2019修复

星期六, 一月 26th, 2013 3,241 views

首先是创建一个QT项目,选择QT Gui应用。然后一直下一步。

创建完成后项目结构如下

这个时候点运行,出现一个空的mainwindow界面,这里就不截图了。
(更多…)