草庐IT

python - PyQt5 中的 connect() 方法在哪里?

coder 2023-08-17 原文

我正在关注 Mark Summerfield 的 Rapid GUI Programming with Python and Qt,它使用的是 PyQt4。我更喜欢使用 PyQt5,但我的机器上都有。我在书上的第二个习题,如下:

from __future__ import division
import sys
from math import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *


class Form(QDialog):

    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.browser = QTextBrowser()
        self.lineedit = QLineEdit("Type an expression and press Enter")
        self.lineedit.selectAll()
        layout = QVBoxLayout()
        layout.addWidget(self.browser)
        layout.addWidget(self.lineedit)
        self.setLayout(layout)
        self.lineedit.setFocus()
        # This line fails:
        self.connect(self.lineedit, SIGNAL("returnPressed()"), self.updateUi)
        self.setWindowTitle("Calculate")


    def updateUi(self):
        try:
            text = unicode(self.lineedit.text())
            self.browser.append("%s = <b>%s</b>" % (text, eval(text)))
        except:
            self.browser.append(
                    "<font color=red>%s is invalid!</font>" % text)


app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()

当我使用 PyQt4 运行脚本(并将 PyQt5.QtWidgetsPyQt4.QtGui 交换)时,它运行良好,但使用 PyQt5 时失败:

Traceback (most recent call last):
  File "calculate.pyw", line 32, in <module>
    form = Form()
  File "calculate.pyw", line 19, in __init__
    self.connect(self.lineedit, SIGNAL("returnProcessed()"), self.updateUi)
AttributeError: 'Form' object has no attribute 'connect'

我做了一些挖掘,但显然 there are no changes to connect所以我认为这可能是一个继承问题,但是当我在 PyQt4 和 PyQt5 中运行 dir(QDialog)connect 只出现在 PyQt4 中(输出修剪,完整输出进一步向下):

Python 3.4.1 (default, Aug 24 2014, 21:32:40)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from PyQt5.QtWidgets import *
>>> dir(QDialog)
[..., 'colorCount', 'connectNotify', 'contentsMargins', ...]

Python 2.7.8 (default, Aug 24 2014, 21:26:19)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from PyQt4.QtGui import *
>>> dir(QDialog)
[..., 'colorCount', 'connect', 'connectNotify', 'contentsMargins', ...]

connect 方法存在于 PyQt4 中:

Python 2.7.8 (default, Aug 24 2014, 21:26:19)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from PyQt4.QtGui import *
>>> dir(QDialog)
['Accepted', 'DialogCode', 'DrawChildren', 'DrawWindowBackground',
 'IgnoreMask', 'PaintDeviceMetric', 'PdmDepth', 'PdmDpiX', 'PdmDpiY',
 'PdmHeight', 'PdmHeightMM', 'PdmNumColors', 'PdmPhysicalDpiX',
 'PdmPhysicalDpiY', 'PdmWidth', 'PdmWidthMM', 'Rejected', 'RenderFlag',
 'RenderFlags', '__class__', '__delattr__', '__dict__', '__doc__',
 '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__',
 '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
 '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
 '__weakref__', 'accept', 'acceptDrops', 'accepted',
 'accessibleDescription', 'accessibleName', 'actionEvent', 'actions',
 'activateWindow', 'addAction', 'addActions', 'adjustSize',
 'autoFillBackground', 'backgroundRole', 'baseSize', 'blockSignals',
 'changeEvent', 'childAt', 'childEvent', 'children', 'childrenRect',
 'childrenRegion', 'clearFocus', 'clearMask', 'close', 'closeEvent',
 'colorCount', 'connect', 'connectNotify', 'contentsMargins',
 'contentsRect', 'contextMenuEvent', 'contextMenuPolicy', 'create',
 'cursor', 'customContextMenuRequested', 'customEvent', 'deleteLater',
 'depth', 'destroy', 'destroyed', 'devType', 'disconnect',
 'disconnectNotify', 'done', 'dragEnterEvent', 'dragLeaveEvent',
 'dragMoveEvent', 'dropEvent', 'dumpObjectInfo', 'dumpObjectTree',
 'dynamicPropertyNames', 'effectiveWinId', 'emit', 'enabledChange',
 'ensurePolished', 'enterEvent', 'event', 'eventFilter', 'exec_',
 'extension', 'find', 'findChild', 'findChildren', 'finished',
 'focusInEvent', 'focusNextChild', 'focusNextPrevChild', 'focusOutEvent',
 'focusPolicy', 'focusPreviousChild', 'focusProxy', 'focusWidget',
 'font', 'fontChange', 'fontInfo', 'fontMetrics', 'foregroundRole',
 'frameGeometry', 'frameSize', 'geometry', 'getContentsMargins',
 'grabGesture', 'grabKeyboard', 'grabMouse', 'grabShortcut',
 'graphicsEffect', 'graphicsProxyWidget', 'handle', 'hasFocus',
 'hasMouseTracking', 'height', 'heightForWidth', 'heightMM', 'hide',
 'hideEvent', 'inherits', 'inputContext', 'inputMethodEvent',
 'inputMethodHints', 'inputMethodQuery', 'insertAction', 'insertActions',
 'installEventFilter', 'isActiveWindow', 'isAncestorOf', 'isEnabled',
 'isEnabledTo', 'isEnabledToTLW', 'isFullScreen', 'isHidden',
 'isLeftToRight', 'isMaximized', 'isMinimized', 'isModal', 
 'isRightToLeft', 'isSizeGripEnabled', 'isTopLevel', 'isVisible',
 'isVisibleTo', 'isWidgetType', 'isWindow', 'isWindowModified',
 'keyPressEvent', 'keyReleaseEvent', 'keyboardGrabber', 'killTimer',
 'languageChange', 'layout', 'layoutDirection', 'leaveEvent', 'locale',
 'logicalDpiX', 'logicalDpiY', 'lower', 'mapFrom', 'mapFromGlobal',
 'mapFromParent', 'mapTo', 'mapToGlobal', 'mapToParent', 'mask',
 'maximumHeight', 'maximumSize', 'maximumWidth', 'metaObject', 'metric',
 'minimumHeight', 'minimumSize', 'minimumSizeHint', 'minimumWidth',
 'mouseDoubleClickEvent', 'mouseGrabber', 'mouseMoveEvent',
 'mousePressEvent', 'mouseReleaseEvent', 'move', 'moveEvent',
 'moveToThread', 'nativeParentWidget', 'nextInFocusChain',
 'normalGeometry', 'numColors', 'objectName', 'open', 'orientation',
 'overrideWindowFlags', 'overrideWindowState', 'paintEngine',
 'paintEvent', 'paintingActive', 'palette', 'paletteChange', 'parent',
 'parentWidget', 'physicalDpiX', 'physicalDpiY', 'pos',
 'previousInFocusChain', 'property', 'pyqtConfigure', 'raise_',
 'receivers', 'rect', 'reject', 'rejected', 'releaseKeyboard',
 'releaseMouse', 'releaseShortcut', 'removeAction', 'removeEventFilter',
 'render', 'repaint', 'resetInputContext', 'resize', 'resizeEvent',
 'restoreGeometry', 'result', 'saveGeometry', 'scroll', 'sender',
 'senderSignalIndex', 'setAcceptDrops', 'setAccessibleDescription',
 'setAccessibleName', 'setAttribute', 'setAutoFillBackground',
 'setBackgroundRole', 'setBaseSize', 'setContentsMargins',
 'setContextMenuPolicy', 'setCursor', 'setDisabled', 'setEnabled',
 'setExtension', 'setFixedHeight', 'setFixedSize', 'setFixedWidth',
 'setFocus', 'setFocusPolicy', 'setFocusProxy', 'setFont',
 'setForegroundRole', 'setGeometry', 'setGraphicsEffect', 'setHidden',
 'setInputContext', 'setInputMethodHints', 'setLayout',
 'setLayoutDirection', 'setLocale', 'setMask', 'setMaximumHeight',
 'setMaximumSize', 'setMaximumWidth', 'setMinimumHeight',
 'setMinimumSize', 'setMinimumWidth', 'setModal', 'setMouseTracking',
 'setObjectName', 'setOrientation', 'setPalette', 'setParent',
 'setProperty', 'setResult', 'setShortcutAutoRepeat',
 'setShortcutEnabled', 'setShown', 'setSizeGripEnabled', 
 'setSizeIncrement', 'setSizePolicy', 'setStatusTip', 'setStyle',
 'setStyleSheet', 'setTabOrder', 'setToolTip', 'setUpdatesEnabled',
 'setVisible', 'setWhatsThis', 'setWindowFilePath', 'setWindowFlags',
 'setWindowIcon', 'setWindowIconText', 'setWindowModality',
 'setWindowModified', 'setWindowOpacity', 'setWindowRole',
 'setWindowState', 'setWindowTitle', 'show', 'showEvent',
 'showExtension', 'showFullScreen', 'showMaximized', 'showMinimized',
 'showNormal', 'signalsBlocked', 'size', 'sizeHint', 'sizeIncrement',
 'sizePolicy', 'stackUnder', 'startTimer', 'staticMetaObject',
 'statusTip', 'style', 'styleSheet', 'tabletEvent', 'testAttribute',
 'thread', 'timerEvent', 'toolTip', 'topLevelWidget', 'tr', 'trUtf8',
 'underMouse', 'ungrabGesture', 'unsetCursor', 'unsetLayoutDirection',
 'unsetLocale', 'update', 'updateGeometry', 'updateMicroFocus',
 'updatesEnabled', 'visibleRegion', 'whatsThis', 'wheelEvent', 'width',
 'widthMM', 'winId', 'window', 'windowActivationChange',
 'windowFilePath', 'windowFlags', 'windowIcon', 'windowIconText',
 'windowModality', 'windowOpacity', 'windowRole', 'windowState',
 'windowTitle', 'windowType', 'x', 'y']

但不是 PyQt5:

Python 3.4.1 (default, Aug 24 2014, 21:32:40)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from PyQt5.QtWidgets import *
>>> dir(QDialog)
['Accepted', 'DialogCode', 'DrawChildren', 'DrawWindowBackground',
 'IgnoreMask', 'PaintDeviceMetric', 'PdmDepth', 'PdmDevicePixelRatio',
 'PdmDpiX', 'PdmDpiY', 'PdmHeight', 'PdmHeightMM', 'PdmNumColors',
 'PdmPhysicalDpiX', 'PdmPhysicalDpiY', 'PdmWidth', 'PdmWidthMM',
 'Rejected', 'RenderFlag', 'RenderFlags', '__class__', '__delattr__',
 '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
 '__getattr__', '__getattribute__', '__gt__', '__hash__', '__init__',
 '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
 '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
 '__subclasshook__', '__weakref__', 'accept', 'acceptDrops', 'accepted',
 'accessibleDescription', 'accessibleName', 'actionEvent', 'actions',
 'activateWindow', 'addAction', 'addActions', 'adjustSize',
 'autoFillBackground', 'backgroundRole', 'baseSize', 'blockSignals',
 'changeEvent', 'childAt', 'childEvent', 'children', 'childrenRect',
 'childrenRegion', 'clearFocus', 'clearMask', 'close', 'closeEvent',
 'colorCount', 'connectNotify', 'contentsMargins', 'contentsRect',
 'contextMenuEvent', 'contextMenuPolicy', 'create',
 'createWindowContainer', 'cursor', 'customContextMenuRequested',
 'customEvent', 'deleteLater', 'depth', 'destroy', 'destroyed',
 'devType', 'devicePixelRatio', 'disconnect', 'disconnectNotify', 'done',
 'dragEnterEvent', 'dragLeaveEvent', 'dragMoveEvent', 'dropEvent',
 'dumpObjectInfo', 'dumpObjectTree', 'dynamicPropertyNames',
 'effectiveWinId', 'ensurePolished', 'enterEvent', 'event',
 'eventFilter', 'exec', 'exec_', 'find', 'findChild', 'findChildren',
 'finished', 'focusInEvent', 'focusNextChild', 'focusNextPrevChild',
 'focusOutEvent', 'focusPolicy', 'focusPreviousChild', 'focusProxy',
 'focusWidget', 'font', 'fontInfo', 'fontMetrics', 'foregroundRole',
 'frameGeometry', 'frameSize', 'geometry', 'getContentsMargins', 'grab',
 'grabGesture', 'grabKeyboard', 'grabMouse', 'grabShortcut',
 'graphicsEffect', 'graphicsProxyWidget', 'hasFocus',
 'hasHeightForWidth', 'hasMouseTracking', 'height', 'heightForWidth',
 'heightMM', 'hide', 'hideEvent', 'inherits', 'initPainter',
 'inputMethodEvent', 'inputMethodHints', 'inputMethodQuery',
 'insertAction', 'insertActions', 'installEventFilter', 'isActiveWindow',
 'isAncestorOf', 'isEnabled', 'isEnabledTo', 'isFullScreen', 'isHidden',
 'isLeftToRight', 'isMaximized', 'isMinimized', 'isModal',
 'isRightToLeft', 'isSignalConnected', 'isSizeGripEnabled', 'isVisible',
 'isVisibleTo', 'isWidgetType', 'isWindow', 'isWindowModified',
 'isWindowType', 'keyPressEvent', 'keyReleaseEvent', 'keyboardGrabber',
 'killTimer', 'layout', 'layoutDirection', 'leaveEvent', 'locale',
 'logicalDpiX', 'logicalDpiY', 'lower', 'mapFrom', 'mapFromGlobal',
 'mapFromParent', 'mapTo', 'mapToGlobal', 'mapToParent', 'mask',
 'maximumHeight', 'maximumSize', 'maximumWidth', 'metaObject', 'metric',
 'minimumHeight', 'minimumSize', 'minimumSizeHint', 'minimumWidth',
 'mouseDoubleClickEvent', 'mouseGrabber', 'mouseMoveEvent',
 'mousePressEvent', 'mouseReleaseEvent', 'move', 'moveEvent',
 'moveToThread', 'nativeEvent', 'nativeParentWidget', 'nextInFocusChain',
 'normalGeometry', 'objectName', 'objectNameChanged', 'open',
 'overrideWindowFlags', 'overrideWindowState', 'paintEngine',
 'paintEvent', 'paintingActive', 'palette', 'parent', 'parentWidget',
 'physicalDpiX', 'physicalDpiY', 'pos', 'previousInFocusChain',
 'property', 'pyqtConfigure', 'raise_', 'receivers', 'rect',
 'redirected', 'reject', 'rejected', 'releaseKeyboard', 'releaseMouse',
 'releaseShortcut', 'removeAction', 'removeEventFilter', 'render',
 'repaint', 'resize', 'resizeEvent', 'restoreGeometry', 'result',
 'saveGeometry', 'scroll', 'sender', 'senderSignalIndex',
 'setAcceptDrops', 'setAccessibleDescription', 'setAccessibleName',
 'setAttribute', 'setAutoFillBackground', 'setBackgroundRole',
 'setBaseSize', 'setContentsMargins', 'setContextMenuPolicy',
 'setCursor', 'setDisabled', 'setEnabled', 'setFixedHeight',
 'setFixedSize', 'setFixedWidth', 'setFocus', 'setFocusPolicy',
 'setFocusProxy', 'setFont', 'setForegroundRole', 'setGeometry',
 'setGraphicsEffect', 'setHidden', 'setInputMethodHints', 'setLayout',
 'setLayoutDirection', 'setLocale', 'setMask', 'setMaximumHeight',
 'setMaximumSize', 'setMaximumWidth', 'setMinimumHeight',
 'setMinimumSize', 'setMinimumWidth', 'setModal', 'setMouseTracking',
 'setObjectName', 'setPalette', 'setParent', 'setProperty', 'setResult',
 'setShortcutAutoRepeat', 'setShortcutEnabled', 'setSizeGripEnabled',
 'setSizeIncrement', 'setSizePolicy', 'setStatusTip', 'setStyle',
 'setStyleSheet', 'setTabOrder', 'setToolTip', 'setToolTipDuration',
 'setUpdatesEnabled', 'setVisible', 'setWhatsThis', 'setWindowFilePath',
 'setWindowFlags', 'setWindowIcon', 'setWindowIconText',
 'setWindowModality', 'setWindowModified', 'setWindowOpacity',
 'setWindowRole', 'setWindowState', 'setWindowTitle', 'sharedPainter',
 'show', 'showEvent', 'showFullScreen', 'showMaximized', 'showMinimized',
 'showNormal', 'signalsBlocked', 'size', 'sizeHint', 'sizeIncrement',
 'sizePolicy', 'stackUnder', 'startTimer', 'staticMetaObject',
 'statusTip', 'style', 'styleSheet', 'tabletEvent', 'testAttribute',
 'thread', 'timerEvent', 'toolTip', 'toolTipDuration', 'tr',
 'underMouse', 'ungrabGesture', 'unsetCursor', 'unsetLayoutDirection',
 'unsetLocale', 'update', 'updateGeometry', 'updateMicroFocus',
 'updatesEnabled', 'visibleRegion', 'whatsThis', 'wheelEvent', 'width',
 'widthMM', 'winId', 'window', 'windowFilePath', 'windowFlags',
 'windowHandle', 'windowIcon', 'windowIconChanged', 'windowIconText',
 'windowIconTextChanged', 'windowModality', 'windowOpacity',
 'windowRole', 'windowState', 'windowTitle', 'windowTitleChanged',
 'windowType', 'x', 'y']

我错过了什么?

最佳答案

您正在使用具有 not been implemented in PyQt5 的旧式信号和插槽.尝试使用 new-style signals and slots .

self.lineedit.returnPressed.connect(self.updateUi)

关于python - PyQt5 中的 connect() 方法在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27382053/

有关python - PyQt5 中的 connect() 方法在哪里?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  5. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  6. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  7. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  8. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  9. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

  10. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

随机推荐