2012-11-16 29 views
8

मैं अभी क्यूटी में शुरू कर रहा हूं, और मॉडल-व्यू-कंट्रोलर डिज़ाइन पैटर्न का सरलीकृत, कामकाजी उदाहरण प्राप्त करने का प्रयास कर रहा हूं।क्यूटी मॉडल/व्यू/कंट्रोलर उदाहरण

अब तक, मैं QLabel पर पुश बटन जैसे मूल विजेट कनेक्ट करने के लिए सिग्नल और स्लॉट का उपयोग करने में सक्षम हूं, और दृश्य को संशोधित किया गया है क्योंकि पुश बटन क्लिक/रिलीज़ किया गया है। उस के एक उदाहरण के लिए नीचे कोड देखें (MainWindow कक्षा में लागू)।

मैं इस श्रेणी में Game, जो कि मेरा मॉडल होने जा रहा है, को परिभाषित करने की कोशिश कर रहा हूं। मैं अपने पूरे आवेदन के सभी डेटा और व्यवसाय नियमों के लिए Game चाहता हूं। मुझे Game की आवश्यकता नहीं है क्यूटी विशिष्ट - यह बहुत अच्छी तरह से सामान्य C++ हो सकता है। हालांकि, नीचे दिए गए कोड में, इसमें QTimer लागू करने के लिए कुछ क्यूटी-विशिष्ट कोड हैं जो इस उदाहरण के प्रयोजनों के लिए उपयोगी हैं।

मैं इस उदाहरण में दो बातें प्राप्त करने के लिए कोशिश कर रहा हूँ:

  1. मैं एक मॉडल है जो समय बीतने के ऊपर एक चर मूल्य बढ़ाने की तरह, के भीतर ही घटना के कुछ प्रकार उत्पन्न करने में सक्षम है करना चाहते हैं, और फिर आखिरकार देखते हैं कि दृश्य में किसी भी तरह से बदलाव दिखाई देता है। या बेहतर अभी तक QTimer के timeout() बस कुछ स्लॉट से जुड़े सिग्नल हो सकते हैं, यह स्लॉट मॉडल के भीतर होने वाली कुछ घटना है। नीचे दिखाए गए कोड का उपयोग करके, imageOn या imageOff (MainWindow कक्षा का हिस्सा भी) में संग्रहीत छवियों में से एक को प्रदर्शित करने के लिए दृश्य में प्रतिबिंब label_1 (MainWindow वर्ग का हिस्सा) की सेटिंग होगी।
  2. मैं on_pushButton_clicked() और on_pushButton_pressed() स्लॉट से जुड़े पुश बटन को मॉडल के भीतर संग्रहीत कुछ मान संशोधित करने में सक्षम होना चाहता हूं। फिर, आइटम 1 के साथ पूर्ण सर्कल आ रहा है, मॉडल के उस अद्यतन को दृश्य में प्रतिबिंबित किया जाना चाहिए।

यदि मेरी शब्दावली अब तक गलत है या एमवीसी डिजाइन पैटर्न की क्यूटी शब्दावली के साथ असंगत है, तो मुझे क्षमा करें। मैं उस पर किसी भी स्पष्टीकरण का स्वागत करेंगे। साथ ही, यदि मैंने प्रदान किया गया उदाहरण कोड क्यूटी में एमवीसी डिजाइन पैटर्न का उदाहरण देने के लिए बहुत ही मजबूत है, तो मैं स्लेट साफ करने और अधिक उचित उदाहरण के साथ शुरू करने के इच्छुक हूं। मैं बस इतना करना चाहता हूं कि क्यूटी और एमवीसी के साथ शुरुआत हो, लेकिन इस तरह से अधिक जटिल डेटा प्रकारों से संबंधित है।

मैं एक उदाहरण विकसित करने की कोशिश कर रहा हूं जिसमें मैं Game जैसे मॉडल और कक्षा को संभालने की कोशिश कर रहा हूं जो संभावित रूप से जटिल है - QStrings की एक साधारण सूची या कुछ अधिक सीधे आगे होने की गारंटी नहीं है। जब मैंने एमवीसी से संबंधित क्यूटी दस्तावेज के माध्यम से ब्राउज किया, तो मुझे कई उदाहरण सामने आए जो setModel() फ़ंक्शन का उपयोग करने के लिए कनेक्शन की कोशिश करने और बनाने के लिए आवश्यक रूप से सूची आइटम 1 और 2 में उल्लिखित हैं। समस्या यह थी कि मैं एक रास्ता नहीं देख सका Game जैसे अधिक जटिल डेटा-प्रकार के साथ उस सटीक दृष्टिकोण का उपयोग करने के लिए जो पूर्ण एप्लिकेशन के लिए संपूर्ण डेटा मॉडल हो सकता है (मुझे पता है कि Game इस उदाहरण में जटिल नहीं है, लेकिन यह अंत में हो सकता है)। मुझे ऐसा कुछ चाहिए जो स्केलेबल और एक्स्टेंसिबल है, जो कुछ पूरे एप्लिकेशन के लिए काम करेगा। यदि उन setModel()-प्रकार के फ़ंक्शन इस के लिए उपयुक्त हैं - जो कि वे शायद ही हो सकते हैं, मैं इसे अपने आप नहीं समझ पाया - मैं जानना चाहता हूं कि QLabel और छवियों से निपटने वाले इस उदाहरण में उन लोगों को कैसे कार्यान्वित किया जाए।

कोड:

खेल।ज

#ifndef GAME_H 
#define GAME_H 

#include <QtCore> 

class Game : public QObject { 

    Q_OBJECT 

public: 
    Game(); 
    void timed_job(); 

private: 
    QTimer *timer; 
}; 

#endif // GAME_H 

game.cpp

#include "game.h" 
#include <QtCore> 

Game::Game() { 
} 

void Game::timed_job() { 
    timer = new QTimer(this); 
    timer->start(1000); 
    //connect(timer, SIGNAL(timeout()), this, SLOT(flip())); 
} 

mainwindow.h

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 

#include <QMainWindow> 

namespace Ui { 
    class MainWindow; 
} 

class MainWindow : public QMainWindow { 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(); 

private slots: 
    void on_pushButton_clicked(); 
    void on_pushButton_pressed(); 

private: 
    Ui::MainWindow *ui; 
    QImage imageOn, imageOff; 
}; 

#endif // MAINWINDOW_H 

mainwindow.cpp

#include <QImage> 
#include "mainwindow.h" 
#include "ui_mainwindow.h" 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) { 
    imageOn.load(":/Files/On.jpg"); 
    imageOff.load(":/Files/Off.jpg"); 

    ui->setupUi(this); 
} 

MainWindow::~MainWindow() { 
    delete ui; 
} 

void MainWindow::on_pushButton_clicked() { 
    ui->label_1->setPixmap(QPixmap::fromImage(imageOff)); 
} 

void MainWindow::on_pushButton_pressed() { 
    ui->label_1->setPixmap(QPixmap::fromImage(imageOn)); 
} 

main.cpp

#include <QtGui/QApplication> 
#include <QLabel> 
#include "mainwindow.h" 
#include "game.h" 

int main(int argc, char *argv[]) { 
    QApplication a(argc, argv); 

    MainWindow w; 

    w.show(); 

    return a.exec(); 
} 
+0

क्यूटी मॉडल-व्यू दृष्टिकोण का उपयोग करता है, कोई अलग नियंत्रक नहीं है। क्या आप क्यूटी मॉडल-व्यू सामान का उपयोग करने की कोशिश कर रहे हैं, या अपनी खुद की एमवीसी चीज रोल कर रहे हैं? फिर, वास्तविक सवाल क्या है? – hyde

+0

मुझे क्यूटी मॉडल-व्यू सामान बनाम लागत और लाभों की जानकारी नहीं है, मेरी खुद की एमवीसी चीज रोल करें, लेकिन मुझे इसके लिए अनाज के खिलाफ काम करने का कोई कारण नहीं दिख रहा है। मुझे लगता है कि इसका मतलब होगा कि मैं क्यूटी मॉडल-व्यू सामान का उपयोग करना चाहता हूं।मैं नियंत्रक को मिश्रण में मजबूर करने की कोशिश नहीं कर रहा हूं। मुझे नहीं पता था कि क्यूटी ने मूल रूप से अलग नियंत्रक नहीं थे। – nairware

+0

सामान्य दृश्य (जो मैंने पढ़ा है) यह है कि सुविधा विजेट छोटे सामान के लिए अच्छे हैं। दृश्य/मानक मॉडल एकदम सही होते हैं जब आपको एक डेटा मॉडल और उसी डेटा के कई दृश्य होने की आवश्यकता होती है ... और आखिरकार ... यदि आपको अपने डेटा संरचनाओं का प्रतिनिधित्व करने वाले विशाल डेटासेट करने की आवश्यकता है, तो कस्टम मॉडल वहां हैं उस तरह के प्रदर्शन के लिए। – jdi

उत्तर

7

एक क्यूटी में "नियंत्रक" तकनीकी रूप से बस स्लॉट हैं एक अलग QObject उपवर्ग द्वारा प्रस्तुत किया जा सकता है। और आप इसे अपने मॉडल और दृश्य के बीच तार करेंगे।
लेकिन आम तौर पर मैं जो करता हूं (और देखता हूं) सिर्फ आपके मॉडल को व्यावसायिक तर्क शामिल करना है, और आपके व्यू उप-वर्ग में इसके उपयोगकर्ता इंटरैक्शन को संभालने के तरीकों को शामिल किया गया है। मैं नियंत्रक अवधारणा के निकटतम हूं, जब मेरे पास मेरा QMainWindow (या संवाद) वर्ग है जो एप्लिकेशन का प्रतिनिधित्व करता है, और इसमें SLOTS का एक गुच्छा है। इन स्लॉट्स को एक साथ जोड़ने के लिए निजी यूआई सदस्यों के सिग्नल में वायर्ड हो जाते हैं।

उदाहरण: आपकी मुख्य विंडो में एक मॉडल, दृश्य और पुश बटन है। मुख्य विंडो के लिए init में, मैं मॉडल को दृश्य में सेट कर दूंगा, और अपनी विंडो refreshData() पर एक स्लॉट पर "क्लिक" पुश बटन को कनेक्ट कर दूंगा। यह स्लॉट मॉडल पर "अपडेट" विधि को कॉल करेगा, जो स्वचालित रूप से दृश्य के लिए प्रचारित होगा। इस प्रकार मुख्य खिड़की एक नियंत्रक की तरह कार्य करता है।

आप कुछ करना चाहते हैं QAbstractItemModel या QStandardItemModel जो आपके डेटा का प्रतिनिधित्व करता है और जो आप डेटा को अपडेट करना चाहते हैं (आपके द्वारा सुझाए गए टाइमर) को करना है। मॉडल से जुड़े किसी भी दृश्य को मानक इंटरफ़ेस की वजह से इसे देखने में सक्षम हो जाएगा। आप, साथ ही एक अलग टाइमर कस्टम QAbstractItemModel कक्षाएं

रूप @hyde द्वारा बताया के बारे में एक मौजूदा QStandardItemModel

एक नोट में डेटा देता है कि, अगर आप कोशिश एक चुनौती हो सकती कस्टम मॉडल में कूद कर सकते हैं और मौजूदा कंक्रीट मॉडल कक्षाओं की अच्छी समझ प्राप्त करने से पहले इसे पहले करें।

  1. तो फिर QTreeView साथ
  2. अंत में काम एक QListView/QTableView
  3. के साथ एक QStandardItemModel का उपयोग करके देखें सुविधा विगेट्स (QListWidget, QTableWidget, QTreeWidget)
  4. से परिचित हों: यहाँ मैं क्या करने की सलाह देते है , जब आपको वास्तव में अपने मौजूदा डेटा संरचनाओं के लिए बहुत ही कस्टम मॉडलिंग की आवश्यकता होती है, तो आप इसे अपनी आंतरिक संरचना का उपयोग करने के लिए QAbstractItemModel को उपclassing पर काम कर सकते हैं।
+2

QAbstractItemModel के बारे में एक टिप्पणी: यह तर्कसंगत रूप से सबसे जटिल भागों में से एक है क्यूटी, स्क्रैच से पहला मॉडल करते समय, कुछ बालों को खींचने के लिए तैयार रहें, और सावधानीपूर्वक डॉक्टर पढ़ने ... – hyde

+0

यह केवल एक व्यक्तिपरक अनुभव हो सकता है। यह केवल जटिल है यदि आप मौजूदा ठोस मॉडल को समझने के बिना तुरंत इसे शुरू करते हैं। एक बार जब आप जानते हैं कि वे कैसे काम करते हैं, तो एक साधारण पठन-केवल कस्टम मॉडल प्राप्त करना बहुत आसान है। हालांकि मैं कुछ जानकारी के साथ अपडेट करूँगा। धन्यवाद! – jdi

+0

टू-डू सूची के लिए धन्यवाद। मैं उस पर शुरू करने जा रहा हूं और एक बेहतर नींव के साथ वापस आऊंगा। – nairware