??QPainter.drawRect(QRectF)繪制圖形傳入的是世界坐標,而后經過變換矩形變為窗口坐標,最后經過窗口-視口變換變為設備坐標。其中世界坐標系和窗口坐標系都屬于邏輯坐標系,設備坐標系屬于物理坐標。
??綜上,三個坐標系中,世界坐標系和窗口坐標系是邏輯坐標系,與具體的設備大小沒有關系,兩者之間相差的是坐標變換,而設備坐標系也就是物理坐標系,第二象限是繪圖的有效果區域,沒有負坐標軸。
關于繪圖設備
??繪圖設備常常有QWidget、QPixmap、QImage等。(另外感覺QGraphicsItem也可以作為繪圖設備,使用paint函數繪圖。)關于QGraphicsView和QGraphicsScene
??使用QWidget::paintEvent只能繪制簡單的圖形,Qt提供了可與用戶交互的QGraphics繪圖體系,圖形項可移動、選中。view類似于繪圖設備,但是view不能設置視口,scene的坐標系類似于邏輯坐標系,可以通過view.setSceneRect(QRectF)來選定scene中的部分區域顯示在view中。
`X'=aX + b``Y'=cY + d`其中,XY為窗口坐標,X'Y'為視口坐標。
??在QWidget::paintEvet()中繪圖,QWidget是繪圖設備,左上角為物理坐標系的坐標原點。通過設置窗口setWindow()和設置視口setViewPort()來分別設置邏輯坐標系的繪制區域和物理坐標系的顯示區域,超出物理坐標系的內容不予顯示。在邏輯坐標系中通過坐標系變換實現繪制。
??在QGraphicsItem::paint()中可以繪制,Item的左上角默認是邏輯坐標系的原點,可通過painter的坐標系變換(如translate、scale、shear、rotate)實現與QWidget體系中相同的繪制。與QWidget不同的是,超出Item仍然能夠顯示。
??QGraphicsView間接繼承于QWidget,因此可作為控件擺放在QWidget中,直接繼承于QAbstractScrollArea,因此作為顯示的窗口時,可以出現滾動條。View與QGraphicsScene搭配使用,Scene用于存放QGraphicsItem,默認邏輯坐標系的原點位于其中心,Item通過item::setPos()設置其在(場景)邏輯坐標系中的位置,通過item::setRect()設置其在自身局部坐標系中的位置,因此Scene場景的不同位置皆可放置Item。而View類似于視口,用于顯示場景中的內容,通過view::setSceneRect()可設置顯示哪部分場景區域,類似于設置窗口。但是View并不能設置顯示在哪部分區域。
painter.save();
painter.setPen(Qt::red);
painter.drawRect(0,0, 200, 200);//可視化視口(紅色)
painter.setViewport(0,0, 200, 200);
QPen pen=painter.pen();
pen.setStyle(Qt::DashLine);
pen.setWidth(3);
pen.setColor(Qt::blue);
painter.setPen(pen);
painter.setWindow(-100, -100, 200, 200);
painter.drawRect(-100, -100, 200, 200);//可視化窗口(藍色)
painter.translate(50, 50);//平移(50,50)
painter.setPen(Qt::black);//繪制兩個圖形
painter.drawRect(-100, -100, 100, 100);
painter.drawRect(50, 50, 100, 100);
painter.restore();
總結:
文章轉自博客園(YueLiGo):https://www.cnblogs.com/wsw2022/p/16983853.html
一篇文章用VBA下載一部完整小說,VBA除了可以輕松下載一部《水滸傳》小說,還有什么用途?VBA獲取網頁信息(即爬蟲技術)其用處可多了。今天介紹各位小伙用來監控的自選股票的主力資金變動的情況,愿大伙在2022年股票市場長紅!也是把上期一個網友評論的內容(有些數據藏得很深,怎么找真正的地址……)回應一下。
東富的主力資金流入圖
有一個理論我們會經常聽到,A股的票漲漲跌跌主要是因為有大資金在活動、在操作,一些股票不斷上漲是因為有主力資金不斷買入,反而不斷下跌是因為主力資金不斷流出。喜歡做短線的,我們實時觀察這些主力資金就變得很有意義,很多網站都有主力資金的數據,但是要對多支股票進行觀察,則需要一個個打開網頁、APP或者電腦程序查看數據,這樣耗時也不能多支股票同框對比。還有一些小伙正上班,打開股票軟件給老板或同事看到,總覺得怪怪的,當然這不是鼓勵一些小伙上班玩股票,純屬用項目和大家一起交流學習。
用VBA就可以很輕松解決上述兩個問題。大伙先看看效果吧!
點擊按鈕更新數據:2022年12月21日數據
完整代碼如下:
Sub maincapital()
Application.DisplayAlerts=False
'循環A列數據,解析出相應股票代碼
For Each cl In Range("a2:a" & Range("a2").End(xlDown).Row)
stock_code=Right(cl, 6) '取右邊6位字符
Dim strText, stcok_code As String
'拼接構造網址
URL="https://push2.eastmoney.com/api/qt/ulist.np/get?cb=fltt=2&secids=1." + stock_code + "&fields=f62%2Cf184%2Cf66%2Cf69%2Cf72%2Cf75%2Cf78%2Cf81%2Cf84%2Cf87%2Cf64%2Cf65%2Cf70%2Cf71%2Cf76%2Cf77%2Cf82%2Cf83%2Cf164%2Cf166%2Cf168%2Cf170%2Cf172%2Cf252%2Cf253%2Cf254%2Cf255%2Cf256%2Cf124%2Cf6%2Cf278%2Cf279%2Cf280%2Cf281%2Cf282&ut=b2884a393a59ad64002292a3e90d46a5&_=1641268581776"
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", URL, False
.send
strText=.responseText
End With
'判斷是有null,解決深A股和上A股網址不同拼接問題,secids=0.是深A;secids=1.是上A。
Dim regStrTest As Object
With CreateObject("VBScript.Regexp")
.Pattern="null"
Set regStrTest=.Execute(strText)
End With
If regStrTest.Count > 0 Then
'如果出現null則拼接構造一個新網址
URL="https://push2.eastmoney.com/api/qt/ulist.np/get?cb=fltt=2&secids=0." + stock_code + "&fields=f62%2Cf184%2Cf66%2Cf69%2Cf72%2Cf75%2Cf78%2Cf81%2Cf84%2Cf87%2Cf64%2Cf65%2Cf70%2Cf71%2Cf76%2Cf77%2Cf82%2Cf83%2Cf164%2Cf166%2Cf168%2Cf170%2Cf172%2Cf252%2Cf253%2Cf254%2Cf255%2Cf256%2Cf124%2Cf6%2Cf278%2Cf279%2Cf280%2Cf281%2Cf282&ut=b2884a393a59ad64002292a3e90d46a5&_=1641268581776"
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", URL, False
.send
strText=.responseText
End With
End If
Rnum=cl.Row '股票名稱所在行號
'利用正則表達式得到我們想要的內容,并寫相應的表格
With CreateObject("VBScript.Regexp")
.Pattern="""f62"":(.*?),"
Cells(Rnum, 2)=Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '主力凈流進
.Pattern="""f184"":(.*?),"
Cells(Rnum, 3)=Round(.Execute(strText)(0).submatches.Item(0) / 100, 2) '主力凈比
.Pattern="""f66"":(.*?),"
Cells(Rnum, 4)=Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '超大單凈流進
.Pattern="""f69"":(.*?),"
Cells(Rnum, 5)=Round(.Execute(strText)(0).submatches.Item(0) / 100, 2) '超大單凈比
.Pattern="""f72"":(.*?),"
Cells(Rnum, 6)=Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '大單凈流進
.Pattern="""f75"":(.*?),"
Cells(Rnum, 7)=Round(.Execute(strText)(0).submatches.Item(0) / 100, 2) '大單凈比
.Pattern="""f78"":(.*?),"
Cells(Rnum, 8)=Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '中單凈流進
.Pattern="""f81"":(.*?),"
Cells(Rnum, 9)=Round(.Execute(strText)(0).submatches.Item(0) / 100, 2) '中單凈比
.Pattern="""f84"":(.*?),"
Cells(Rnum, 10)=Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '小單凈流進
.Pattern="""f87"":(.*?),"
Cells(Rnum, 11)=Round(.Execute(strText)(0).submatches.Item(0) / 100, 2) '小單凈比
.Pattern="""f64"":(.*?),"
Cells(Rnum, 12)=Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '超大單流入
.Pattern="""f65"":(.*?),"
Cells(Rnum, 13)=Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '超大流出
.Pattern="""f70"":(.*?),"
Cells(Rnum, 14)=Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '大單流入
.Pattern="""f71"":(.*?),"
Cells(Rnum, 14)=Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '大單流出
End With
Next
Application.DisplayAlerts=True
End Sub
這個項目用到的幾個重要知識:
獲取動態網頁加載數據的真正網址
我們在目標網頁點擊右鍵,并點擊“查看網頁源代碼”后,當使用cttl+f鍵查看我們想要獲取的信息進行查看(這里我輸入主力凈比數據-42.76),發現并沒有相關的數據。
在源代碼網頁同時按cttl+f鍵查看
通過這個方法基本可以判斷目標網頁的部分數據是使用動態加載的方式。簡單的動態加載數據,可以通過以下兩步獲取真正的網址:
第一步:打開瀏覽器控制臺。演示使用的瀏覽器是chrome,按下F12鍵打開瀏覽器控制臺,再次刷新網頁,在控制臺找到并點擊擴大鏡小按鈕,打開search對話框,這里輸入想找的數據(這里我輸入主力凈比數據42.76)后,按下回車鍵或輸入框旁邊的刷新按鍵,就會彈出一個“get”字符及一些類似網址的內容,點擊彈出的內容,右下面對話框會彈出相應的內容(對話框的菜單有Headers,Preview,Response……)
圖中主力凈比數據為-42.73和在輸入框的數據不一致,是因為資金數據動態變化了
第二步:找到加載數據的網址。點擊Headers可以看到Resquest URl字符,后面網址就是加載數據真正的網址,復制網址在瀏覽器打開,我們可以看到相應的數據內容。獲得這網址后,就可以通過VBA訪問這個網址獲取相應的數據,按下來的工作就好辦了。
目標數據的網址
使用CreateObject("MSXML2.XMLHTTP")對象獲取網頁信息
stock_code=Right(cl, 6) '取右邊6位字符
Dim strText, stcok_code As String '
'拼接構造網址
URL="https://push2.eastmoney.com/api/qt/ulist.np/get?cb=fltt=2&secids=1." + stock_code + "&fields=f62%2Cf184%2Cf66%2Cf69%2Cf72%2Cf75%2Cf78%2Cf81%2Cf84%2Cf87%2Cf64%2Cf65%2Cf70%2Cf71%2Cf76%2Cf77%2Cf82%2Cf83%2Cf164%2Cf166%2Cf168%2Cf170%2Cf172%2Cf252%2Cf253%2Cf254%2Cf255%2Cf256%2Cf124%2Cf6%2Cf278%2Cf279%2Cf280%2Cf281%2Cf282&ut=b2884a393a59ad64002292a3e90d46a5&_=1641268581776"
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", URL, False
.send
strText=.responseText
End With
'判斷是有null,解決深A股和上A股網址不同拼接問題,secids=0.是深A;secids=1.是上A。
Dim regStrTest As Object
With CreateObject("VBScript.Regexp")
.Pattern="null"
Set regStrTest=.Execute(strText)
End With
If regStrTest.Count > 0 Then
'如果出現null則拼接構造一個新網址
URL="https://push2.eastmoney.com/api/qt/ulist.np/get?cb=fltt=2&secids=0." + stock_code + "&fields=f62%2Cf184%2Cf66%2Cf69%2Cf72%2Cf75%2Cf78%2Cf81%2Cf84%2Cf87%2Cf64%2Cf65%2Cf70%2Cf71%2Cf76%2Cf77%2Cf82%2Cf83%2Cf164%2Cf166%2Cf168%2Cf170%2Cf172%2Cf252%2Cf253%2Cf254%2Cf255%2Cf256%2Cf124%2Cf6%2Cf278%2Cf279%2Cf280%2Cf281%2Cf282&ut=b2884a393a59ad64002292a3e90d46a5&_=1641268581776"
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", URL, False
.send
strText=.responseText
End With
End If
上面代碼的說明:
1、使用right(目標字符串,字符個數)函數獲取目標字符串從右邊數起第幾個字符。
2、做兩次網址請求是因為深A股和上A股的數據網址是有區別,網址的參數“secids=0.+ 股票代碼”是深A;“secids=1.+股票代碼”是上A。如果人為對每支股票判斷是上A還深A會很復雜,所以使用正則表達式,對請求數據內容出現“null”字樣的網址,則更換網址參數。如下圖:
上A網址請求結果
深A網址請求結果
使用CreateObject("VBScript.Regexp")正則表達式對象獲取數據
For Each cl In Range("a2:a" & Range("a2").End(xlDown).Row)
……
Rnum=cl.Row '股票名稱所在行號
'利用正則表達式得到我們想要的內容,并寫相應的表格
With CreateObject("VBScript.Regexp")
.Pattern="""f62"":(.*?)," 'VBA的英文的雙引號
Cells(Rnum, 2)=Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '主力凈流入
.Pattern="""f184"":(.*?),"
Cells(Rnum, 3)=Round(.Execute(strText)(0).submatches.Item(0) / 100, 2) '主力凈比
.Pattern="""f66"":(.*?),"
……
上面代碼的說明:
1、Range("a2").End(xlDown)是表示定位從A2單元往下最后一個不空值的單元格。
2、cl.Row是表示單元格的行數,Range("A1").Row,Cells(1, 1).Row都可以獲取單元格行數,列值則是Range("A1").Column和Cells(1, 1).Column。
3、.Pattern="""f62"":(.*?)," 是正則表達式(網頁的內容是:"f62":-15043563520.0),VBA的英文的雙引號用正則表式表示則是兩個雙引號,即是""。"f62":后面數據就是主力凈流入的數據,用(.*?)表示。再用.submatches.Item(0)得到目標數據,這個數據是以元為單位,網頁顯示的是億,所以要/100000000。
4、Round(目標數據,小數點位數)是取多少位小數的方法。
點擊按鈕調用函數
Private Sub CommandButton1_Click()
Call maincapital '調用函數
End Sub
在這總結一下VBA抓取數據主要步驟:
分析網站->>分析網頁數據->>處理網頁數據->>儲存網頁數據
歡迎大家評論及提意見,相互學習,提高效率,創造價值。
Chart的顯示需要用到QChartView,創建QChartView的步驟如下:
(1)在.pro文件中添加:QT +=charts。
(2)用到QChart的文件中添加:QT_CHARTS_USE_NAMESPACE,或者:using namespace QtCharts;
(3)在ui界面中拖入一個graphicsView(或)控件,然后右擊提升為QChartView類,如下圖,點擊添加,點擊提升;QChart的顯示容器創建完成。
Qt資料領取→「鏈接」
QChart的兩種顯示方法:(本質上就是同一種方法)
(1)QChart必須顯示在widget上,更確切地說,是必須把它顯示在QGraphicView控件中,眾所周知,QT的ui控件都可以作為獨立窗口直接顯示,所以這就是方法1。
(2)把QChart顯示在ui界面的QGraphicView控件中。
PS:把QChart顯示在QGraphicView控件中,程序略顯繁瑣,QT早就為我們封裝好了一個ui控件類QtCharts::QChartView,它繼承了QGraphicView。這就是上文提到的把QGraphicView提升成了QChartView。用QChartView來顯示QChart還是很方便的。
用QGraphicView來顯示QChart較為繁瑣,下面來對比一下,分別用QGraphicView和QChartView來顯示QChart,代碼量的區別:
(1)用QGraphicView來顯示,需要借助QGraphicsScene類。具體地說就是,QGraphicView在最底層,QGraphicsScene在中間,QChart在最外層。
QGraphicsScene scene;//場景(中間層)
QGraphicsView view(&scene);//視圖(最底層)
view.setRenderHint(QPainter::Antialiasing);//設置視圖抗鋸齒
view.setSceneRect(0, 0, 630, 280);//設置視圖大小
QLineSeries *lineseries=new QLineSeries();//圖表的數據集
lineseries->append(0, 5);//append和<<功能差不多
*lineseries << QPointF(13, 5) << QPointF(17, 6) << QPointF(20, 2);
QChart *lineChart=new QChart();//圖表(最頂層)
lineChart->addSeries(lineseries); // 將 數據集 添加至圖表中
scene.addItem(lineChart);//把圖標添加到場景中(一個場景中允許添加多個圖表)
view.show();//視圖顯示
(2)用QChartView來顯示QChart較為方便
QLineSeries *lineseries=new QLineSeries();//圖表的數據集
lineseries->append(0, 5);//append和<<功能差不多
*lineseries << QPointF(13, 5) << QPointF(17, 6) << QPointF(20, 2);
QChart *lineChart=new QChart();//圖表(最頂層)
lineChart->addSeries(lineseries); // 將 數據集 添加至圖表中
QChartView *chartView=new QChartView(chart);//QChartView 可以一步到位直接顯示QChart
chartView->setRenderHint(QPainter::Antialiasing);//繼承來的抗鋸齒方法
chartView->resize(400, 300);
chartView->show();//本示例代碼,把該控件作為窗口直接顯示出來。
//其實,也可以把QChartView的父控件設置為主UI,這樣就能把QChartView顯示在主窗體中了
如果ui中已添加了QChartView,則可以直接在ui中顯示:
......
ui->histogramView->setChart(chart); //histogramView--ui中已添加的QChartView
ui->histogramView->setRenderHint(QPainter::Antialiasing);
ui->histogramView->setVisible(true);
最后再來捋一下各個類之間的層次關系。下圖中,大括號“{”代表左邊實體包含右邊實體,下箭頭↓↓↓↓代表繼承關系
文章轉自博客園(手磨咖啡):https://www.cnblogs.com/zzzsj/p/14760234.html
Qt資料領取(視頻教程+文檔+代碼+項目實戰)
*請認真填寫需求信息,我們會在24小時內與您取得聯系。