• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            zhonghua

            C++博客 首頁 新隨筆 聯系 聚合 管理
              72 Posts :: 1 Stories :: 4 Comments :: 0 Trackbacks

            1、QGridLayout
            QGridLayout包含多個grid,它并沒有要求其中的每個grid的size相同,通常情況下,每個grid的size是不同的。
            對于成員函數addWidget(widget, fromRow, fromColumn, rowSpan, columnSpan, alignment):rowSpan表示新添加進來的widget在垂直方向上跨越或者占據多少個grid。
            columnSpan表示新添加進來的widget在水平方向上跨越或者占據多少個grid。

            2、line edit的input mask
            對一個line edit設置了input mask屬性后,也就限定了輸入字符。一般情況下,需要填寫的字符位置是空白的,但是,你可以讓該空白以某個字符占位,你只需在指定input mask的字符末尾添加“*?”即可,把‘?’換為你想用來占位的一個字符。

            3、利用designer設計ui
            總體上來說,先創建各個控件,然后設置layout相對來說好些。另外,grid layout對設置布局前的窗口布局依賴比較大,即如果設置grid layout前的布局不同,則生效后的差別可能較大。

            4、QLabel的buddy屬性
            在qt中,只有QLabel實現了buddy機制。
            只有你為QLabel設置了buddy后,文本中的字符‘&’才能以下劃線顯示(這點與其他widget不同),并創建了對應的快捷鍵(當然,需要+Alt),然后可以利用快捷鍵迅速的把光標定位到該QLabel的buddy中,例如:
            QLabel *what = new QLabel("Find &What:");
            該實例對應快捷鍵Alt+w。

            5、QMouseEvent中的坐標
            QMouseEvent中保存了兩個坐標,一個是全局坐標,當然另外一個是局部坐標。
            全局坐標(globalPos())即是桌面屏幕坐標(screen coordinates),這個跟windows下的調用getCursorPos函數得到的結果一致。
            局部坐標(pos())即是相對當前active widget的坐標,左上角坐標為(0, 0)。

            補充一個公式:
            this->mapFromGlobal(this->cursor().pos()) = event.pos()

            6、鼠標跟蹤
            在qt中,鼠標跟蹤對應函數mouseMoveEvent。但是,默認情況下他并不能如期象你想象的那樣響應鼠標的移動。此時,你只需在合適的位置調用一下函數setMouseTracking(true)即可。

            默認情況下,mouseMoveEvent響應你按下鼠標的某個鍵(拖動,但不局限于左鍵拖動)的鼠標移動。

            7、鼠標左鍵拖動和左鍵點擊的判斷
            鼠標左鍵點擊很容易判斷,一般就是在重寫mousePressEvent函數,示例如下:
            void XXXWidget::mousePressEvent(QMouseEvent *event)
            {
                if(event->button() == Qt:leftButton)
                {
                    // todo ...
                }
            }
            左鍵拖動的判斷一般放在mouseMoveEvent函數中,但是你不能向上例一樣來判斷,因為該函數的event參數總是返回Qt::NoButton。你可以這樣做:
            void XXXWidget::mouseMoveEvent(QMouseEvent *event)
            {
                if(event->buttons() & Qt:leftButton)
                {
                    // todo ...
                }
            }

            8、窗口有一個子窗口,子窗口隨著父窗口最小化而最小化的實現:

            child = new QWidget(parent);
            child->setWindowFlags(Qt::Window);

            但是,如果父子窗口都顯示的話,此時銷毀父窗口,子窗口依然顯示;然后關閉子窗口,才算完全關閉了整個窗口。理想的做法是這樣的:

            child = new QWidget(parent);
            child->setWindowFlags(Qt::Window | Qt::SubWindow);
            9、解決中文亂碼問題
                //解決中文亂碼問題
                QTextCodec::setCodecForTr(QTextCodec::codecForName("GB2312"));
                QTextCodec::setCodecForLocale(QTextCodec::codecForName("GB2312"));
                QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB2312"));
            10、實現多窗體切換。
                信號通訊方法(參數1事件響應對象,參數2響應事件,參數3本實例對象指針,參數4響應方法)
                connect(this->ui->butSumbie, SIGNAL(clicked()), this, SIGNAL(send1()));
                信號通訊方法(參數1事件響應對象,參數2響應事件,參數3本實例對象指針,本實例對象執行方法)
                connect(this->ui->butSumbie, SIGNAL(clicked()), this, SLOT(close()));
            事件中調用說明:
                信號通訊方法(參數1事件響應對象,參數2響應事件,參數3本實例對象指針,參數4響應方法)
                    MyWidget w;
                    執行權限交給主窗體
                    app.setMainWidget(&w);
            11、獲取當前執行程序路徑:QCoreApplication::applicationDirPath()
            12、獲取當前執行程序文件夾下全部文件內容并且保存到comboBox中。
                QDir dir(QCoreApplication::applicationDirPath());
                通過QDir獲取目錄下全部文件與文件夾
                QFileInfoList qFilelist = dir.entryInfoList();
                for(int i=0;i<qFilelist.count();i++)
                {   //判斷獲取到的名稱是文件
                    if(qFilelist.value(i).isFile())
                        ui->comboBox->addItem(qFilelist.value(i).fileName(),i);
                }
            13、文件讀取實現內容實現代碼。
                QFile file(ui->comboBox->itemText(index));
                if(file.open(QIODevice::ReadOnly))//以只讀方式打開文件
                {
                    FileName = ui->comboBox->itemText(index);
                    QTextStream ts(&file);
                    QTextCodec *codec=QTextCodec::codecForName("GBK");
                    ts.setCodec(codec);
                    ui->textEdit->setText(QString::null);
                    QString line;
                    do{
                         line = ts.readLine();
                         if(!line.isNull())
                             line+="\n";
                         ui->textEdit->insertPlainText(line);
                    } while (!line.isNull());
                    file.close();
                }
            14、文件寫入實現代碼段
                QFile file(this->FileName);
                if(file.open(QIODevice::ReadWrite))//以讀寫方式打開文件
                {
                    QTextStream qts(&file);
                    QTextCodec *codec=QTextCodec::codecForName("GBK");
                    qts.setCodec(codec);
                    QString text = ui->textEdit->document()->toPlainText();
                    qts<<text;//寫入到文件中。
                    qts.flush();//執行寫入
                    file.close();
                }
            15、數據庫QSqlQueryModel類使用意見SqlServer數據庫連接。
                ui->setupUi(this);
                db = QSqlDatabase::addDatabase("QODBC");//定義數據庫連接類型。db對象在執行QSqlQueryModel綁定中一直必須是開啟狀態并且要可見否則無數據內容顯示。
                db.setDatabaseName(QString("DRIVER={SQL Server};"
                                "SERVER=%1;DATABASE=%2;UID=%3;PWD=%4")
                            .arg("127.0.0.1")
                            .arg("Northwind")
                            .arg("sa")
                            .arg("sa"));
                db.open();
                QSqlQuery query(db);//可以執行查詢與刪除修改添加操作對象。
                query.exec("select top 10 * from dbo.Orders");
                if(query.numRowsAffected() == -1)
                {
                    QMessageBox::about(this,"234","234");
                }

                QSqlQueryModel *model = new QSqlQueryModel;
                ui->tableView->setWindowTitle("model");
                model->setQuery("select top 10 * from dbo.Orders");
                ui->tableView->setModel(model);
                ui->tableView->show();
            16、例用QTableWidget實現表格樣式自定義顯示結構。
                QSqlDatabase db;
                db =QSqlDatabase::addDatabase("QODBC");
                db.setDatabaseName(QString("DRIVER={SQL Server};"
                                "SERVER=%1;DATABASE=%2;UID=%3;PWD=%4")
                            .arg("192.168.0.16")
                            .arg("Northwind")
                            .arg("sa")
                            .arg("sa"));
                db.open();
                QSqlQueryModel *model=new QSqlQueryModel(this);
                model->setQuery("select * from EmployeeTerritories where EmployeeID<4");
                QStringList List;
                List.push_back("aa");List.push_back("bb");setColumnCount(2);//設置字段名
                setHorizontalHeaderLabels(List);//命名字段
                for(int i=0;i<model->rowCount();i++)
                {
                    QString s;
                    s=model->record(i).value("EmployeeID").toString();
                    QPushButton *LineEdit1=new QPushButton(s);//綁定在表格中的控件類型
                    insertRow(i);
                    setCellWidget(i,0,LineEdit1);
                }
                db.close();
            17、實現不規則窗體顯示。
                //自定義不規則窗體
                QPalette p = palette();
                QPixmap img("a.jpg");
                //窗體掩碼圖定義
                //QBitmap mask("mask.png");
                p.setBrush(QPalette::Window, QBrush(img));
                setPalette(p);
                //設置掩模圖
                //setMask(mask);
                setWindowFlags(Qt::FramelessWindowHint);
                resize(800, 600);
                //ui->setupUi(this);
            18、重寫鼠標控制窗體移動事件
                //聲明的對象
                QPoint last,pos0;//鼠標移動控制對象
                //重寫的鼠標移動事件
                void MainWindow::mouseMoveEvent(QMouseEvent *e)
                {
                    if(e->buttons() & Qt::LeftButton)
                    {
                        //QMessageBox::about(this,"進入移動","成功進入移動事件");
                        QPoint newpos = e->globalPos();
                        QPoint upleft = pos0 + newpos - last;
                        move(upleft);
                    }
                }
                //重寫的鼠標按下事件
                void MainWindow::mousePressEvent(QMouseEvent *e)
                {
                    if(e->button()==Qt::LeftButton)
                    {
                        //QMessageBox::about(this,"進入按下","成功進入按下事件");
                        last = e->globalPos();
                        pos0 = e->globalPos() - e->pos();
                    }
                }
            19、QT中調用DLL實現代碼段
                這個推薦一款小工具 viewdll.exe 。實例代碼和工具下面提供下載。將DLL文件直接拖過去,就直接顯示DLL里的函數名。當然也不是所有DLL都能顯示。  
                用QT生成DLL,直接導出函數的方法。   
                用QTcreator  dll向導建立工程。把所有.H文件刪除,在唯一的.CPP文件中編寫你所要導出的函數,函數模版   
                extern "C" __declspec(dllexport) int ShowMessageBox()   
                {   
                    char *str = "this is Dll";   
                    cout<<str;   
                    return 0;   
                }   
                直接編譯后,生成DLL文件。   
                將dll文件拷貝到你要使用的exe工程中。這里我的EXE使用的是core類型,沒有使用GUI。   
                在新工程的cpp文件中加入   
                QLibrary myLib("ClassDll.dll");//加載dll文件   
                typedef void (*MyPrototype)();   
                MyPrototype myFunction = (MyPrototype) myLib.resolve("ClassDll");//CLASSDLL是函數名   
                if (myFunction)   
                    myFunction();//調用的classdll,也就是你的函數生成dll的文件:
                //mydll.h
              extern "C" __declspec(dllexport) int maxfun(int,int);    //函數
            struct __declspec(dllexport) nNode  //結構體
            {
                int x;   
            };
            //mydll.cpp
            #include "mydll.h"
            extern "C" __declspec(dllexport)int maxfun(int x,int y)
            {
                return x+y;
            }
            extern "C" __declspec(dllexport)nNode  temp={10};  //這里一個結構體對象
            ///下面是程序調用dll.
            #include <qapplication.h>
            #include <qlibrary.h>
            #include <qmessagebox.h>
            int main(int argc,char* argv[])
            {
                QApplication app(argc,argv); 
                struct mynode
                {
                     int i;
                };
                QLibrary lib("mydll");
                mynode* no = (mynode*)lib.resolve("temp");
                if(no)
                {
                    QMessageBox::information(0,"name",QString::number(no->i));
                }
                else
                    QMessageBox::information(0,"name","no==0");
                return app.exec();
            }
            20、QT中的網絡編程與實現。QT中共提供四個與套按字相關的類,分別是:
              QServerSocket:TCP-based server
              QSocket: Buffered TCP connection
              QSocketDevice: Platform-independent low-level socket API
              QSocketNotifier: Support for socket callbacks
              下面介紹使用QT進行網絡編程,我們使用一個簡單的C/S模式網絡程序說明如何使用QT中的套接字。同時我們用TCP和UDP兩種協議實現這個程序(該程序客戶端與服務端各向對方發送一個字符口串“abc”)
              1、UDP實現
               UDP是不連接協議,沒有客戶端與服務端的概念。
               1)建立套接字相關對象
               QSocketDevice *MUReceiveSocket; //套接字對象
               QSocketNotifier *MSocketNotifier; //套接字監聽對象
               2)初始化套接字相關對象
               MUReceiveSocket=new QSocketDevice(QSocketDevice::Datagram);
               //UDP初始化
               QHostAddress MyAddress;
               QString FakeAddress;
               FakeAddress = get_eth1_ip(); //取得接口IP
               MyAddress.setAddress(FakeAddress);
               MUReceiveSocket->bind(MyAddress,Port);
               //綁定到指定網絡接口地址(IP),指定邏輯端口
               MSocketNotifier = new QSocketNotifier(MUReceiveSocket->socket(),QSocketNotifier::Read,0,"MSocketNotifier");
               //監聽MUReceiveSocket套接字
               3)定義用實現響應slot
               virtual void OnMReceive();
               void Client::OnMReceive()
               {
               int ByteCount,ReadCount;
               char *IncommingChar;
               fprintf(stderr,"Load a piece of Message!\n");
               ByteCount=MUReceiveSocket->bytesAvailable();
               IncommingChar=(char *)malloc(ByteCount+1);
               ReadCount=MUReceiveSocket->readBlock(IncommingChar,ByteCount);
               IncommingChar[ByteCount]='';
               fprintf(stderr,“%s“,IncommingChar); //打印接收的字符串
               }
               4)關聯套接字的signal和接收slot
               connect(MSocketNotifier,SIGNAL(activated(int)),this,SLOT(OnMReceive()));
               //當MSocketNotifier檢測到MUReceiveSocket活躍時調用OnMReceive
               5)發送字符串
               char information[20];
               strcpy(information,“abc“);
               MUReceiveSocket->writeBlock(information,length,MyAddress,2201);
              2、TCP實現
               TCP的實現與UDP的實現大同小異,它是面象連接的協議。這里只介紹與UDP不同的地方。
               服務端:
               1)套接字對象的定義
               比UDP多定義一個套接字,一個用來監聽端口,一個用來通信。
               QSocketDevice *ServerSocket;
               QSocketDevice *ClientSocket;
               QSocketNotifier *ClientNotifier;
               QSocketNotifier *ServerNotifier;
               2)套接字的初始化
               QHostAddress MyAddress;
               QString FakeAddress;
               FakeAddress = "127.0.0.1";
               MyAddress.setAddress(FakeAddress);
               UINT Port=1234;
               ServerSocket=new QSocketDevice(QSocketDevice::Stream);
               ClientSocket=new QSocketDevice(QSocketDevice::Stream);
               ServerSocket->bind(MyAddress,Port);
               ServerSocket->listen(20); //20代表所允許的最大連接數
               ClienttNotifier = new QSocketNotifier(ClientSocket->socket(),QSocketNotifier::Read,0,"ClientSocket");
               ServerNotifier = new QSocketNotifier(ServerSocket->socket(),QSocketNotifier::Read,0,"ServerSocket");
               3)響應連接(在定義slot中響應)
               當收到客戶端的連接后,響應它,并以ClientSocket接收:
               ServerSocket->SetSocket(ClientSocket->socket());
               4)接收信息slot與UDP一致,這里不在敘述。
               客戶端實現:
               客戶端的實現與UDP實現大同小異,不同的地方只是客戶端套接字不需要bind端口,因為連接上服 務端后TCP會保持這個連接,直到通信的結束。
            操作系統:ARM-LINUX QT版本:QT-2.3.2-FOR-LINUX GUI:Qtopia 在LINUX下進行網絡編程,我們可以使用LINUX提供的統一的套接字接口。但是這種方法牽涉到太多的結構體,比如IP地址,端口轉換等,不熟練的人往 往容易犯這樣那樣的錯誤。QT中提供的SOCKET完全使用了類的封裝機制,使用戶不需要接觸底層的各種結構體操作。而且它采用QT本身的signal- slot機制,使編寫的程序更容易理解。 QT中共提供四個與套按字相關的類,分別是: QServerSocket:TCP-based server QSocket: Buffered TCP connection QSocketDevice: Platform-independent low-level socket API QSocketNotifier: Support for socket callbacks 下面介紹使用QT進行網絡編程,我們使用一個簡單的C/S模式網絡程序說明如何使用QT中的套接字。同時我們用TCP和UDP兩種協議實現這個程序(該程 序客戶端與服務端各向對方發送一個字符口串“abc”) 1、UDP實現 UDP是不連接協議,沒有客戶端與服務端的概念。 1)建立套接字相關對象 QSocketDevice *MUReceiveSocket; //套接字對象 QSocketNotifier *MSocketNotifier; //套接字監聽對象 2)初始化套接字相關對象 MUReceiveSocket=new QSocketDevice(QSocketDevice::Datagram); //UDP初始化 QHostAddress MyAddress; QString FakeAddress; FakeAddress = get_eth1_ip(); //取得接口IP MyAddress.setAddress(FakeAddress); MUReceiveSocket->bind(MyAddress,Port); //綁定到指定網絡接口地址(IP),指定邏輯端口 MSocketNotifier = new QSocketNotifier(MUReceiveSocket->socket(),QSocketNotifier::Read,0,"MSocketNotifier"); //監聽MUReceiveSocket套接字 3)定義用實現響應slot virtual void OnMReceive(); void Client::OnMReceive() { int ByteCount,ReadCount; char *IncommingChar; fprintf(stderr,"Load a piece of Message!\n"); ByteCount=MUReceiveSocket->bytesAvailable(); IncommingChar=(char *)malloc(ByteCount+1); ReadCount=MUReceiveSocket->readBlock(IncommingChar,ByteCount); IncommingChar[ByteCount]=''; fprintf(stderr,“%s“,IncommingChar); //打印接收的字符串 } 4)關聯套接字的signal和接收slot connect(MSocketNotifier,SIGNAL(activated(int)),this,SLOT(OnMReceive())); //當MSocketNotifier檢測到MUReceiveSocket活躍時調用OnMReceive 5)發送字符串 char information[20]; strcpy(information,“abc“); MUReceiveSocket->writeBlock(information,length,MyAddress,2201); 2、TCP實現 TCP的實現與UDP的實現大同小異,它是面象連接的協議。這里只介紹與UDP不同的地方。 服務端: 1)套接字對象的定義 比UDP多定義一個套接字,一個用來監聽端口,一個用來通信。 QSocketDevice *ServerSocket; QSocketDevice *ClientSocket; QSocketNotifier *ClientNotifier; QSocketNotifier *ServerNotifier; 2)套接字的初始化 QHostAddress MyAddress; QString FakeAddress; FakeAddress = "127.0.0.1"; MyAddress.setAddress(FakeAddress); UINT Port=1234; ServerSocket=new QSocketDevice(QSocketDevice::Stream); ClientSocket=new QSocketDevice(QSocketDevice::Stream); ServerSocket->bind(MyAddress,Port); ServerSocket->listen(20); //20代表所允許的最大連接數 ClienttNotifier = new QSocketNotifier(ClientSocket->socket(),QSocketNotifier::Read,0,"ClientSocket"); ServerNotifier = new QSocketNotifier(ServerSocket->socket(),QSocketNotifier::Read,0,"ServerSocket"); 3)響應連接(在定義slot中響應) 當收到客戶端的連接后,響應它,并以ClientSocket接收: ServerSocket->SetSocket(ClientSocket->socket()); 4)接收信息slot與UDP一致,這里不在敘述。 客戶端實現: 客戶端的實現與UDP實現大同小異,不同的地方只是客戶端套接字不需要bind端口,因為連接上服 務端后TCP會保持這個連接,直到通信的結束。
            21、Qt窗體布局操作
                布局中主要的操作有
                水平布局, 垂直布局, 打破布局。
                當只有一個控件時,不能進行布局操作。布局操作是多個控件,或者對話框的操縱。
                選擇多個窗體控件,按住shift鍵,鼠標點擊選取,右鍵進行布局操縱。
                當選中對話框主窗體時,可以進行窗體上控件的布局操作。
                該操縱將對窗體上的控件或者布局進行,水平布局或者垂直布局操縱
            22、Qt繪圖模式
                Qt助手,放大縮小,很方便。
                繪圖系統
                主要基于三個類,QPainter, QPaintDevice, QPaintEngine.
                QPainter用于執行繪圖操作。QPaintDevice使用QPaint進行繪圖所使用的二維空間。QPaintEngine提供了在不同設備上的 繪圖接口,被QPainter, QPaintDevice內部使用,對于程序員來說是隱藏的,只有在創建自己的設備類型時,才能用到。
                QPainter能用畫筆作圖,畫文字或者圖形。
                畫 填充 創建設備 讀寫圖形文件 樣式
                QPaintDevice是用于畫圖的設備的基類。
                QPaintDevice的子類有 QWidget, QImage, QPixmap, QGLWidget, QGLPixelBuffer, QPicture and QPrinter。
            23、CListWidget與CTableWidget編程注意事項
                在執行CListWidget與CTableWidget等類似的列表控件的Clear操作時,系統經常崩潰,原因分析。這個clear操作因為改變了列表的內容,會觸發其它的信號。特別是下面的兩個函數。
                CListWidget的函數
                void currentItemChanged ( QListWidgetItem * current, QListWidgetItem * previous )
                void currentRowChanged ( int currentRow )
                CTableWidget的函數。
                void currentCellChanged ( int currentRow, int currentColumn, int previousRow, int previousColumn )
                void currentItemChanged ( QTableWidgetItem * current, QTableWidgetItem * previous )
                如果,在下面的函數中,沒有加入信號參數檢測,就很容易出錯。主要檢查currentRow 是否大于或者等于0。current,previous 是否有效。如果不檢查,并根據該參數,調用了其它的方法。當currentRow =-1; 時,就會發生錯誤。
                ui.tableWidget->item(row, 0);  row=-1時,調用就會產生錯誤。
                ui.listWidget->item(row);  row=-1時,調用就會產生錯誤。
                錯誤解決方法:加入錯誤檢查,
                if (row>=0){//其它相關處理}
            24、一個工程中出現多個QMainWindow并同時顯示的方案。
                問題描述:
            在一個CMainWindow CMyWin1的繼承類中,如果再使用一個CMainWindow類CMyWin2;
            在CMyWin1中使用以下代碼、
            CMyWin2 mw;
            mw.show ()
            mw 一閃就沒有了。具體原因不明。
            定義窗體局部變量: CDataManager *m_pDataMager;
            調用過程如下,并建立信號連接,監控信號 destryed,接收道該信號時,做一個槽處理。
            if (m_pDataMager)
            {
               m_pDataMager->setVisible (true);
               m_pDataMager->showNormal ();
               //m_pDataMager->
            }
            else
            {
               m_pDataMager = new CDataManager();
               connect(m_pDataMager, SIGNAL(destroyed(QObject*)),
                 this, SLOT(after_DataManage_Destoryed(QObject*)));
               m_pDataMager->setVisible (true);
            }
            在函數after_DataManage_Destoryed中,進行窗體的delete,并設置變量為NULL。
            void SeismicRecogn::after_DataManage_Destoryed(QObject *obj)
            {
                //QMessageBox::information(this,"Test Box","DataManage_Destoryed!");
                if (m_pDataMager)
                {
                 disconnect(m_pDataMager, SIGNAL(destroyed(QObject*)),
                    this, SLOT(after_DataManage_Destoryed(QObject*)));
                 obj->deleteLater();
                 m_pDataMager =NULL;
                }
            }
            25、資源文件的動態加載
            在構造函數中添加如下:
            QIcon icon;
            icon.addPixmap(QPixmap(QString::fromUtf8("../resource/well.png")), QIcon::Normal,QIcon::Off);
            ui.actionLoad->setIcon(icon);
            tableWidget設置高度寬帶
            ui.tableWidget->setColumnWidth(0,280);
            ui.tableWidget->setColumnWidth(1,280);
            for (int i=0;i<10;i++)
               ui.tableWidget->setRowHeight(i,20);
            26、如何對LineEdit輸入數據進行格式限制。
            QLineEdit 中對輸入字符輸入格式的控制通過inputMask與validators實現。
            使用時,詳細閱讀2個的說明。
            QIntValidator *vv=new QIntValidator(this);
            ui.lineEdit->setValidator (vv);
            27、二維圖形框架Graphics View
            Graphics View框架實現了模型-視圖結構的圖形管理,能對大量的圖元進行管理,支持碰撞檢測、坐標變換和圖元組等多種方便的操作。Graphics View支持事件傳播體系結構,可以使圖元在場景(scene)中得到提高了一倍的精確交互能力。圖元能夠處理鍵盤事件,鼠標按下、移動、釋放和雙擊事 件,也能跟蹤鼠標的移動。在Graphics View框架中,通過BSP(二元空間劃分樹,Binary Space Partionng)來提供快速的圖元查找,這樣就能實時地顯示大場景,甚至上百萬個圖元。
            Graphics View框架提供基于圖元的模型-視圖編程,類似于Qt InterView的模型-視圖結構,只是這里的數據是圖形。Graphics View框架中包括三個主要的類:QGraphicsItem, QGraphicsScene 和 QGraphicsView。
            Graphics View為大量定制的2維圖元的管理與交互提供了一個框架,可以實現這些圖元的可視化,并支持縮放和旋轉。
            28、Graphics View框架繼續學習
            主要內容:場景 QGraphicsScene 視圖 QGraphicsView 圖元 QGraphicsItem
            示例:Examples and Demos >> Graphics View
            QGraphicsScene是QGraphicsItems的容器。它與QGraphicsView一起實現了圖元的可視化,例如線,矩形,文本,以及定制的圖元。QGraphicsScene也提供了以下功能,讓你高效的確定圖元的位置以及圖元的可視性。
            QGraphicsScene scene;
            scene.addText("Hello, world!");
            QGraphicsView view(&scene);
            view.show();
            重點示例程序:
            Diagram Scene
            //圖元的外接矩形區域(虛函數的實現)
            QRectF CGeoObjCnoline::boundingRect() const
            //圖元的繪制路徑(虛函數的實現)
            QPainterPath CGeoObjCnoline::shape() const
            //圖元的繪制(虛函數的實現)
            void CGeoObjCnoline::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
            29、要想界面一直存在用new創建
            用new指針生成,起作用
            private:
            Ui::cdtestClass ui;
            QGraphicsScene *scene;
            QGraphicsView *view;
            cdtest::cdtest(QWidget *parent, Qt::WFlags flags): QMainWindow(parent, flags)
            {   
                ui.setupUi(this);
                scene = new QGraphicsScene();
                scene->setSceneRect (-400,-300,800,600);
                scene->setItemIndexMethod (QGraphicsScene::NoIndex );
                scene->addText ("Good");
                view = new QGraphicsView(scene);
                ui.layTest->addWidget(view);
                view->update();
            }
            用局部變量不起作用
            void cdtest::on_actionTest_triggered()
            {
                QGraphicsScene scene;
                scene.setSceneRect (-400,-300,800,600);
                scene.setItemIndexMethod (QGraphicsScene::NoIndex );
                scene.addText ("Good");
                QGraphicsView view(&scene);
                ui.layTest->addWidget(&view);
                view.update();
            }
            指針用局部變量,使用的時候new,起作用。
            void cdtest::on_actionTest_triggered()
            {
                QGraphicsScene *scene;
                scene = new QGraphicsScene;
                scene->setSceneRect (-400,-300,800,600);
                scene->setItemIndexMethod (QGraphicsScene::NoIndex );
                scene->addText ("Good");
                QGraphicsView *view;
                view =new QGraphicsView(scene);
                ui.layTest->addWidget(view);
                view->update();
            }
            30、QTableView根據內容自動調整列寬行高
            1: 使用QTableView自己帶的函數,函數原型如下:
            ui.tableWidget->resizeColumnToContents (0);
            將第一列根據內容自動調整列寬。
            根據內容自動調整某列的列寬
            void QTableView::resizeColumnToContents ( int column ) [slot]
            Resizes the given column based on the size hints of the delegate used to render each item in the column.
            根據內容自動調整所有列的列寬
            void QTableView::resizeColumnsToContents () [slot]
            Resizes all columns based on the size hints of the delegate used to render each item in the columns.
            根據內容自動調整某一行的行高
            void QTableView::resizeRowToContents ( int row ) [slot]
            Resizes the given row based on the size hints of the delegate used to render each item in the row.
            根據內容自動調整所有行的行高。
            void QTableView::resizeRowsToContents () [slot]
            Resizes all rows based on the size hints of the delegate used to render each item in the rows.
            31、QGraphicsItem中的碰撞檢測描述
            QGraphicsItem是圖元基類。QGraphics View框架提供了幾種標準的圖元,如矩形(QGraphicsRectItem、橢圓(QGraphicsEllipseItem)和文本圖元 (QGraphicsTextItem)等。用戶可以繼承QgraphicItem實現符合自己需要的圖元。
            QGraphicsItem具有以下功能:
            處理鼠標按下、移動、釋放、雙擊、懸停、滾輪和右鍵菜單事件
            處理鍵盤輸入事件
            處理拖放事件
            分組
            碰撞檢測
              圖元有自己的坐標系統,也提供場景和圖元、圖元與圖元之間的坐標轉換函數。圖元可以包含子圖元。
                要創建自己的圖元,必須首先創建QGrahicsItem的一個子類,然后開始實現他的2個純虛函數。一個是boundingRect(),用于返回圖元繪制所需要的估測區域。另一個是paint,它實現實際的繪圖操縱。舉例:
            class SimpleItem : public QGraphicsItem
            {
               public:
               QRectF boundingRect() const
               {
                   qreal penWidth = 1;
                   return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
                          20 + penWidth / 2, 20 + penWidth / 2);
                }
                void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget)
                {
                   painter->drawRoundedRect(-10, -10, 20, 20, 5, 5);
                }
            };
                boundingRect函數有幾個目的。QGraphicsScene的圖元索引就是建立在boundingRect的基礎上。 QGraphicsView也使用這個函數來從視圖上將不可見的圖元移去,以及在繪制重疊的圖元時決定需要重新組織的區域。另 外,QGraphicsItem的碰撞檢測機制(collision detection)使用boundingRest來提高高效的處理。更好的碰撞檢測算法是基于shape函數的調用,shape函數將圖元的形狀的準確 外觀以QPainterPath返回。
                QGraphicsScene認為所有圖元的boundingRect函數與shape函數都是不發生改變的,除非用戶進行通知。如果你想改變一個圖元的范圍,必需先調用prepareGeometryChange以允許QGraphicsScene進行更新。
            碰撞檢測可以通過以下兩種方式實現:
            重新實現shape函數返回一個準確的圖元外觀形狀,依賴collidesWithItem函數進行缺省的碰撞檢測,如果形狀非常的復雜,該檢測將是非常耗時的。
            重新實現collidesWithItem函數,為自己的定制圖元編寫碰撞檢測算法。
            對于多點成線的圖元可以使用下面的方式返回shape。
            QPainterPath path;
            //直線的繪制路徑
            if (m_pointList.count()>0)
            {
               int iSize;
               iSize = m_pointList.size();
               path.moveTo (m_pointList[0]);
               for(int i=1;i<iSize/2;i++)
               {
                   path.lineTo (m_pointList[i*2]);
               }
               for(int i=iSize/2;i>=1;i--)
               {
                   path.lineTo (m_pointList[i*2-1]);
               }
               path.closeSubpath();
                 }
             return path;
            32、sql中二進制文件通過QByteArray讀寫
            從數據庫到文件
            QSqlQuery myquery( *pDatabase);
            QByteArray myba;
            if(myquery.exec(sql))
            {
                QSqlRecord myrecord = myquery.record();
                if (myquery.next()) {
                    myba = myquery.value(myrecord.indexOf("Settings")).toByteArray();//讀取二進制對象
                }
            }
            else
            {
                initBoundary();
                return false;
            }
            QFile mybfile(MapDataFilename);
            if (!mybfile.open(QIODevice::WriteOnly))
            {
               initBoundary();
               return false;
            }
            mybfile.write (myba);
            mybfile.close();
            從文件到數據庫
            //將文件存入數據庫
            QByteArray mapData;
            QFile file(MapDataFilename);
            if (!file.open(QIODevice::ReadOnly))
               return false;
            mapData = file.readAll();
            file.close();
            QSqlDatabase* pDatabase = CAccessController::getInstance()->getAccesser(g_dbXMLFilePath);
            if (pDatabase ==0 )
            {
               // QMessageBox::information(this, "Error", CAccessController::getInstance()->lastError());
               return false;
            }
            QSqlQuery query( *pDatabase);
            query.prepare("update p_project SET Settings = :set where ID_P = :idp");
            query.bindValue (":set",mapData);
            query.bindValue (":idp",CMainConfig::CurProjectID);
            bool bRtn = query.exec();
            if (!bRtn)
            {
               QSqlError er =query.lastError ();
               QString ss= er.text();
               return false;
            }
            33、QGraphicsView放大縮小中心屬性分析
               將下面的函數注釋掉,是resize,不發生縮放。
               void CBaseMapForm::resizeEvent ( QResizeEvent * event )
               {
                  //m_view->doZoomAll();
               }
               QMatrix可以直接進行文件存儲。 << >>。
            34、幫助文件的調用執行問題
              幫助文件安裝制作:
              取得當前可執行程序的路徑
              QString strUrl=QApplication::applicationDirPath () ;
              strUrl=QString("file:///%1/help.htm").arg (strUrl)
              用客戶機的瀏覽器,打開網頁
              desktopServices.openUrl(qqq);
            35、最簡單的圖形顯示控件QLabel
              imageLabel = new QLabel;
              imageLabel->setWordWrap(true);
              imageLabel->setAlignment(Qt::AlignCenter);
              imageLabel->setPixmap(QPixmap(":/images/image.png"));
              QPixmap的伸縮
              ui.lblImage->setPixmap(pixmap.scaled(ui.lblImage->size()-QSize(40,40),Qt::KeepAspectRatio, Qt::FastTransformation));
            36、取得QTableView的特定行,特定列的數據
              QModelIndex index = ui.tableView->currentIndex();
              if (!index.isValid())
              {
                 QMessageBox::information (NULL,"提示","請先選擇一行數據。");
                 return;
              }
              int iRow;
              iRow = index.row();
              QAbstractItemModel* model = ui.tableView->model();
              //取得層數據庫的數據表名
              index = model->index(iRow,1,QModelIndex());
              QString strHorizonName;
              strHorizonName = index.data().toString();
            37、qt下獲得屏幕的分辨率
            在Qt中提供了QDesktopWidget類,提供屏幕的有關信息.
            可以這么作:
            QDesktopWidget *d=QApplication::desktop();
            int width=d->widht(); //屏幕的寬度
            int height=d->height(); //屏幕的高度
            或者簡寫如下:
            int width=QApplication::desktop()->width();
            int height=QApplication::desktop()->height();
            38、干掉QT窗體的標題欄。。
            setWindowFlags(Qt::FramelessWindowHint);
            39、設置QT按鈕為透明。
            //就是這句能夠實現透明,真是意外的發現,希望對一些學習的朋友有點幫助
            ui->pushButton->setFlat(true);
            40、設置QT窗體置頂。
            this->setWindowFlags(Qt::WindowStaysOnTopHint);
            41、判斷sqlite數據表是否存在。

                QStringList existTables;
                existTables=dataBase->tables();
                if(!existTables.contains(userId))

                QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
                //創建不帶名稱的數據庫連接,可以理解成ADO中的Connection
            Driver   Class name      Constructor arguments                                                File to include
            QPSQL    QPSQLDriver     PGconn *connection                                                   qsql_psql.cpp
            QMYSQL   QMYSQLDriver    MYSQL *connection                                                    qsql_mysql.cpp
            QOCI     QOCIDriver      OCIEnv *environment, OCISvcCtx *serviceContext                       qsql_oci.cpp
            QODBC    QODBCDriver     SQLHANDLE environment, SQLHANDLE connection                          qsql_odbc.cpp
            QDB2     QDB2 SQLHANDLE  environment, SQLHANDLE connection                                    qsql_db2.cpp
            QTDS     QTDSDriver      LOGINREC *loginRecord, DBPROCESS *dbProcess, const QString &hostName qsql_tds.cpp
            QSQLITE  QSQLiteDriver   sqlite *connection                                                   qsql_sqlite.cpp
            QIBASE   QIBaseDriver    isc_db_handle connection                                             qsql_ibase.cpp

            ODBC連接適合數據庫類型 連接方式access  "Driver={microsoft access driver(*.mdb)};dbq=*.mdb;uid=admin;pwd=pass;"dBase  "Driver={microsoft dbase driver(*.dbf)};driverid=277;dbq=------------;"oracle  "Driver={microsoft odbc for oracle};server=oraclesever.world;uid=admin;pwd=pass;"MSSQL server  "Driver={sql server};server=servername;database=dbname;uid=sa;pwd=pass;"MS text  "Driver={microsoft text driver(*.txt; *.csv)};dbq=-----;extensions=asc,csv,tab,txt;Persist SecurityInfo=false;"Visual Foxpro  "Driver={microsoft Visual Foxpro driver};sourcetype=DBC;sourceDB=*.dbc;Exclusive=No;"MySQL  "Driver={mysql};database=yourdatabase;uid=username;pwd=yourpassword;option=16386;"SQLite  "Driver={SQLite3 ODBC Driver};Database=D:\SQLite\*.db"PostgreSQL  "Driver={PostgreSQL ANSI};server=127.0.0.1;uid=admin;pwd=pass;database=databaseName"OLEDB連接適 合的數據庫類型 連接方式access  "Provider=microsoft.jet.oledb.4.0;data source=your_database_path;user id=admin;password=pass;"oracle  "Provider=OraOLEDB.Oracle;data source=dbname;user id=admin;password=pass;"MS SQL Server  "Provider=SQLOLEDB;data source=machinename;initial catalog=dbname;userid=sa;password=pass;"MS text  "Provider=microsof.jet.oledb.4.0;data source=your_path;Extended Properties'text;FMT=Delimited'
                //參見QSqlDatabase的文檔http://doc.trolltech.com/4.0/qsqldatabase.html#addDatabase
                db.setDatabaseName("UserDB");
                if ( !db.open())
                {
                    QMessageBox::critical(NULL, QObject::tr("Collection"), QObject::tr("數據庫連接失敗!"));
                    return ;
                }
                if(db.tables().isEmpty())
                {
                    QMessageBox::critical(NULL, QObject::tr("Collection"), QObject::tr("數據庫連接失敗!"));
                }
            42、QString 轉換 unsigned char* 。
                 QString str = "ABCD";
                 int length = str.length();
                 unsigned char *sequence = NULL;
                 sequence = (unsigned char*)qstrdup(str.toAscii().constData());
            43、怎樣獲取手機串號?
                 TPlpVariantMachineId machineId;
                 PlpVariant::GetMachineIdL(machineId);
            44、自定義按鍵事件與控件大小變化事件
                //按鍵事件
                virtual void keyPressEvent(QKeyEvent *k);
                //控件改變重繪事件
                virtual void paintEvent(QPaintEvent *);
            45、獲取QTableView行信息內容
                QSqlQueryModel model;//以綁定數據內容的QSqlQueryModel
                query.prepare("delete from glossary where [work]=:work and [explain]=:explain");
                QModelIndex index = ui->tableView->currentIndex();
                query.bindValue(":work", model->record(index.row()).value(0).toString());
                query.bindValue(":explain", model->record(index.row()).value(1).toString());

            posted on 2012-05-28 14:47 米米 閱讀(3655) 評論(0)  編輯 收藏 引用 所屬分類: qt
            久久精品国产免费观看| 久久久精品久久久久特色影视| 无码8090精品久久一区| 午夜精品久久影院蜜桃| 欧美日韩精品久久久免费观看 | 综合久久国产九一剧情麻豆| 性欧美大战久久久久久久久| 国产精品久久久久9999高清| 欧美久久久久久午夜精品| 国产欧美久久久精品影院| 久久免费小视频| 久久人人爽人人爽人人AV东京热| 国产精品久久久天天影视香蕉 | 久久99精品久久久久久不卡| 无码国内精品久久综合88 | 国产产无码乱码精品久久鸭| 久久精品国产亚洲5555| 韩国免费A级毛片久久| 久久久国产精华液| 国产精品久久久久久久久| 亚洲日本va中文字幕久久| 热综合一本伊人久久精品| 日本精品久久久久中文字幕8| 国产色综合久久无码有码| 日韩va亚洲va欧美va久久| 国产高潮久久免费观看| …久久精品99久久香蕉国产| 色偷偷偷久久伊人大杳蕉| 欧美日韩精品久久久久| 久久夜色精品国产噜噜亚洲a| 精品视频久久久久| 久久久久国产精品麻豆AR影院 | 久久成人国产精品二三区| 久久婷婷人人澡人人爽人人爱| 久久人人超碰精品CAOPOREN | 狠色狠色狠狠色综合久久| 久久无码人妻一区二区三区午夜| 一本一道久久综合狠狠老| 伊人久久大香线蕉av不卡| 午夜精品久久久久久中宇| 无码人妻久久一区二区三区免费|