2012-05-16 9 views
6

मेरा प्रश्न वास्तव में एक एसक्यूएलकेमी-घोषणात्मक मॉडल को कैसे सेट अप करना है जिसे पीईसाइड के क्यूटेबल व्यू क्लास से एक्सेस किया जा सकता है।PySide + SQLAlchemy में QTableView के लिए 'मॉडल' का डिज़ाइन।

मैं सिर्फ अनिवार्य रूप से Object Relational tutorial

के लिए एक सामने अंत को लागू करने की कोशिश कर रहा हूँ दुर्भाग्य से मैं भ्रम की कुछ बिंदुओं की है। मैं यह बताने की कोशिश करूंगा कि मैं कहां हूं।

मैंने उस बिंदु पर SQLAlchemy ट्यूटोरियल का पालन किया है जहां मेरे पास दो संबंधित तालिकाओं हैं और बिना किसी समस्या के उन लोगों को कुशल/क्वेरी कर सकते हैं। QTableView class को स्थापित करने का प्रयास करने के लिए मेरे खुद के मॉडल के साथ setData() method की आवश्यकता है, या डिफ़ॉल्ट मॉडल का उपयोग करने के लिए setItem() method की आवश्यकता है।

तो प्रश्न यह है कि मॉडल को कैसे डिजाइन किया जाए। मुझे लगता है कि डेटाबेस को क्वेरी/संशोधित करने के लिए उन दो विधियों में से एक को परिभाषित करना है। मुझे ऐसा करने का सही तरीका नहीं पता है।

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

मुझे यह भी नहीं पता कि डेटाबेस कब बढ़ता है, क्या पूरी तालिका तत्काल हो जाती है और मेमोरी में होती है या क्यूटी लोड पंक्तियों और कॉलम करता है क्योंकि उपयोगकर्ता स्क्रॉल करते समय देखने के लिए आते हैं?

यहां बहुत सारे टेक्स्ट खेद है, लेकिन स्पष्ट होने की कोशिश कर रहे हैं। यदि कोई अतिरिक्त चीजें हैं जो मैं जोड़ सकता हूं तो कृपया मुझे बताएं। या अगर मैं गलत ट्रैक पर पूरी तरह से कर रहा हूँ ....

from PySide import QtCore, QtGui 
from sqlalchemy import Column, Integer, String, Text, Sequence, ForeignKey, Date, Boolean, create_engine 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.orm import sessionmaker, relationship, backref, aliased 
import datetime 


engine = create_engine('sqlite:///reminder.db') 

Base = declarative_base() 

class User(Base): 
    __tablename__ = 'users_db' 
    id = Column(Integer, Sequence('user_id_seq'), primary_key=True) 
    lastname = Column(String) 
    firstname = Column(String) 
    contact = Column(String) 
    history = Column(Text) 
    notes = Column(Text) 

    addresses = relationship('Address', order_by='Address.id', 
           backref='user', cascade='all, delete, delete-orphan') 


    def __init__(self, firstname, lastname, contact): 
     self.firstname = firstname 
     self.lastname = lastname 
     self.contact = contact 

    def __repr__(self): 
     return "<User('{0}', '{1}', '{2}')>".format(self.firstname, self.lastname, self.contact) 


class Address(Base): 
    __tablename__ = 'addresses_db' 
    id = Column(Integer, primary_key=True) 
    address = Column(String(150)) 
    date = Column(Date) 
    check1 = Column(Boolean) 
    check2 = Column(Boolean) 

    user_id = Column(Integer, ForeignKey('users_db.id')) 

    def __init__(self, address, date): 
     self.address = address 
     self.date = date 
     self.check1 = False 
     self.check2 = False 

    def __repr__(self): 
     return "<Address('{0}', '{1}')>".format(self.address, self.date) 

if __name__ == '__main__': 
    Base.metadata.create_all(engine) 
    Session = sessionmaker(bind=engine) 
    session = Session() 
    header = [User.firstname, User.lastname, nextaddressfromUser] 

>>> for user in session.query(User).all(): 
...  for addr in user.addresses: 
...   print user.firstname, user.lastname, addr.address 

उत्तर

6

पहले, हमें क्वेरी के बारे में भूल जाते हैं, और पाश प्रयोग कर रहे हैं का उपयोग करते हैं। यूआई में जो खोज रहे हैं वह एक मूल बात है। मुझे दस्तावेज़ों की कमी से पता चला है, कि QTableWidget (या कुछ भी QWhateverWidget) का उपयोग करना सर्वोत्तम है, जो मूलभूत चीज़ों के लिए QWhateverView से बेहतर है। आपको सरल चीजों के लिए अपना खुद का मॉडल परिभाषित करने की आवश्यकता नहीं है। तो, मैं आपको एक QTableWidget के साथ यह कैसे दिखाऊंगा। आपको प्रत्येक सेल (पंक्ति, कॉलम) पर एक QTableWidgetItem बनाने की आवश्यकता है। मुझे एक समस्या का सामना करना पड़ा, उन्हें जोड़ने से पहले पंक्तियों की संख्या निर्धारित करना था। यहां वैसे भी,:

import sys 
from PySide import QtGui, QtCore 

class Test(QtGui.QWidget): 

    def __init__(self, rows): 
     super(Test, self).__init__() 

     self.table = QtGui.QTableWidget() 
     self.table.setColumnCount(3) 
     # Optional, set the labels that show on top 
     self.table.setHorizontalHeaderLabels(("First Name", "Last Name", "Address")) 

     self.table.setRowCount(len(rows)) 
     for row, cols in enumerate(rows): 
      for col, text in enumerate(cols): 
       table_item = QtGui.QTableWidgetItem(text) 
       # Optional, but very useful. 
       table_item.setData(QtCore.Qt.UserRole+1, user) 
       self.table.setItem(row, col, table_item) 

     # Also optional. Will fit the cells to its contents. 
     self.table.resizeColumnsToContents() 

     # Just display the table here. 
     layout = QtGui.QHBoxLayout() 
     layout.addWidget(self.table) 
     self.setLayout(layout) 

if __name__ == "__main__": 
    # ... 
    rows = [] 
    # Here I have to fill it in an array, because you need to know the number of rows before adding... There might be a better solution though. 
    for user in session.query(User).all(): 
     for addr in user.addresses: 
      # These are the columns on each row (firstname, lastname, address) 
      rows.append((user.firstname, user.lastname, addr.address)) 

    app = QtGui.QApplication(sys.argv) 
    test = Test(rows) 
    test.show() 
    app.exec_() 

एक और बात आप विचार कर सकते हैं एक QTreeWidget, जो एकाधिक स्तंभों का समर्थन करता है, और आप इसे एक मेज की तरह लग रहे बना सकते हैं, लेकिन डिफ़ॉल्ट रूप से संपादन योग्य कोशिकाओं के बिना, और यह आपके डेटा के अनुरूप हो सकता है यहाँ बेहतर

अब क्वेरी के लिए, आप परिणामों के माध्यम से लूपिंग से बचने और प्रत्येक उपयोगकर्ता के लिए एक अतिरिक्त क्वेरी करने से बचने के लिए इसे एक ही प्रश्न बनाना चाहेंगे। की तरह कुछ: बहुत सी पंक्तियाँ लिए

query = session.query(User.firstname, User.lastname, Address.address).filter(Address.user_id == User.id) 
    for row in query.all(): 
     # firstname, lastname, address = row 
     rows.append(row) 

, मुझे लगता है कि वहाँ एक समाधान है, लेकिन फिर आप अपने खुद के मॉडल को परिभाषित करने और आपके प्रश्नों में LIMIT s का उपयोग करने की आवश्यकता होगी। दस्तावेज़ों और ट्यूटोरियल की कमी के साथ, यह इतना आसान नहीं है ...

और एक साइड नोट के रूप में, आपको अपने पते और उपयोगकर्ता कक्षाओं पर __init__ विधि को परिभाषित करने की आवश्यकता नहीं है, क्योंकि आप कुछ भी विशेष नहीं कर रहे हैं , SQLAlchemy यह आपके लिए स्वचालित रूप से कर सकता है। और आप डिफ़ॉल्ट मान सीधे कॉलम परिभाषा में परिभाषित कर सकते हैं।

अद्यतन: QTableWidgetItem.setData का उपयोग करने के उदाहरण के लिए, मान लें कि हम डबल-क्लिक करते समय उपयोगकर्ता को हटाना चाहते हैं। हम itemDoubleClicked सिग्नल का उपयोग करेंगे।

# in the __init__ function 
self.table.itemDoubleClicked.connect(self.onItemDoubleClick) 

# in onItemDoubleClicked function 
def onItemDoubleClicked(self, item): 
    # Every data has a role, you can specify your own (it's an integer) as long as it's greater than UserRole. Others are used internally, like DisplayRole and some others you can find in the QtCore package. 
    # You can use data with other widgets also, not just TableWidgets. 
    user = item.data(QtCore.Qt.UserRole+1) 
    # you get a session however you want, then delete the user. This object is the same as the one you passed earlier when creating the item, it can be whatever you like. 
    session.delete(user) 
    session.commit() 
+0

अच्छा लगता है। देर हो चुकी है तो अभी इसे आजमा नहीं सकता है। क्या आप table_item.setData (QtCore.Qt.UserRole + 1, उपयोगकर्ता) – jbbiomed

+0

की व्याख्या कर सकते हैं इसका उपयोग यह है कि आप वास्तव में उपयोगकर्ता ऑब्जेक्ट में हेरफेर कर सकते हैं, न केवल अपना नाम प्रदर्शित कर सकते हैं ... (उदाहरण के लिए)। मैं एक उदाहरण दिखाने के लिए अपना जवाब अपडेट करूंगा। – jadkik94

+0

व्याख्या करने के लिए अच्छा धन्यवाद। मुझे लगता है कि आप केवल आपके द्वारा पोस्ट किए गए पहले कोड में संक्षेप में हैं और मैं सही जगह पर सही उपयोगकर्ता का संदर्भ आसानी से जोड़ सकता हूं और कोई जादू नहीं है जिसका आप उपयोग कर रहे हैं। – jbbiomed

संबंधित मुद्दे