PyQt的一些问题

csdnbuku 2015-06-22 10:29:01
将一些Qt上的代码移植到PyQt上使用。
遇到了一些问题:
问题一:

//Qt代码
QList<QPushButton *> btn = this->findChildren<QPushButton *>();
foreach (QPushButton * b, btn) {
connect(b, SIGNAL(clicked()), this, SLOT(btn_clicked()));
}

这段代码目的是将程序中的所有按钮都连接到btn_clicked(),很方便。
pyqt上的我改改了,大概是:

btn = []
btn = self.findChildren(QPushButton)
b = QPushButton()
for b in btn:

b.connect(self,SIGNAL("clicked()"),self.btn_clicked)

这样格式,但不起作用。PyQt中好像没有QList这个类,其用法我不是很清楚 ,目前的解决方法是:
直接
self.ui.btna.clicked.connect(self.btn_clicked)
self.ui.btnb.clicked.connect(self.btn_clicked)
self.ui.btnc.clicked.connect(self.btn_clicked)
self.ui.btnd.clicked.connect(self.btn_clicked)
self.ui.btne.clicked.connect(self.btn_clicked)
self.ui.btnf.clicked.connect(self.btn_clicked)
self.ui.btng.clicked.connect(self.btn_clicked)
self.ui.btnh.clicked.connect(self.btn_clicked)

………………
手动连接。比较麻烦。
问题二:
事件过滤器中的这段代码怎么转换到PyQt中使用,Qt上的这个代码实在太抽象。不会转了。
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);

if (keyEvent->key() == Qt::Key_Space) {
}

我寻思了直接
keyEvent=QKeyEvent()
但是 没效果。
网上根本找不到结果!都是最简单的事件过滤器的应用。
问题三:
connect(qApp, SIGNAL(focusChanged(QWidget *, QWidget *)),this, SLOT(focusChanged(QWidget *, QWidget *)));
怎么转换成PyQt的,我是直接:
qApp.connect(self,QtCore.SIGNAL("focusChanged()"),self.focusChanged)
但是没效果。一遇到带*这些玩意。我就不懂怎么玩了!或者改成focusChanged(QWidget,QWidget)之类的?
求大神解决。


随便问问。这么冷门的东西,估计没多少人回我……
...全文
294 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
csdnbuku 2015-06-24
  • 打赏
  • 举报
回复
引用 4 楼 panghuhu250 的回复:
2. 假设你说的是这段代码:

bool FilterObject::eventFilter(QObject *object, QEvent *event)
{
    if (object == target && event->type() == QEvent::KeyPress) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
        if (keyEvent->key() == Qt::Key_Tab) {
            // Special tab handling
            return true;
        } else
            return false;
    }
    return false;
}
上面第三行的"if (object == target && event->type() == QEvent::KeyPress)"就保证了event是一个QKeyEvent, event.key()应该没问题. 3. isAncestorOf是QWidget的一个方法, 每个widget的子类都继承了这个方法. inherits是QObject中定义的方法, 更是每个QT中的对象都有的.

In [84]: win1 = QMainWindow()

In [85]: win1.isAncestorOf?
Docstring: QWidget.isAncestorOf(QWidget) -> bool
Type:      builtin_function_or_method

In [86]: pb = QPushButton(win1)

In [87]: pb.isAncestorOf?
Docstring: QWidget.isAncestorOf(QWidget) -> bool
Type:      builtin_function_or_method

In [88]: pb.inherits(QWidget)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-88-17f2b78798b1> in <module>()
----> 1 pb.inherits(QWidget)

TypeError: QObject.inherits(str): argument 1 has unexpected type 'PyQt4.QtCore.pyqtWrapperType'

In [89]: pb.inherits("QWidget")
Out[89]: True

In [90]: pb.inherits("QList")
Out[90]: False

In [91]: win1.isAncestorOf(pb)
Out[91]: True

In [92]: pb.isAncestorOf(win1)
Out[92]: False
谢谢,第二个问题也解决了。 第三个问题,我之前说的代码有什么不妥的地方吗? 看你提供的代码也没有发觉。 附上此处的原代码和我修改的pyqt代码:

void frmInput::focusChanged(QWidget *oldWidget, QWidget *nowWidget)
{
    //qDebug() << "oldWidget:" << oldWidget << " nowWidget:" << nowWidget;
    if (nowWidget != 0 && !this->isAncestorOf(nowWidget)) {
        //在Qt5和linux系统中(嵌入式linux除外),当输入法面板关闭时,焦点会变成无,然后焦点会再次移到焦点控件处
        //这样导致输入法面板的关闭按钮不起作用,关闭后马上有控件获取焦点又显示.
        //为此,增加判断,当焦点是从有对象转为无对象再转为有对象时不要显示.
        //这里又要多一个判断,万一首个窗体的第一个焦点就是落在可输入的对象中,则要过滤掉
#ifndef __arm__
        if (oldWidget == 0x0 && !isFirst) {
            return;
        }
#endif

        isFirst = false;
        if (nowWidget->inherits("QLineEdit")) {
            currentLineEdit = (QLineEdit *)nowWidget;
            currentEditType = "QLineEdit";
            this->setVisible(true);
        } else if (nowWidget->inherits("QTextEdit")) {
            currentTextEdit = (QTextEdit *)nowWidget;
            currentEditType = "QTextEdit";
            this->setVisible(true);
        } else if (nowWidget->inherits("QPlainTextEdit")) {
            currentPlain = (QPlainTextEdit *)nowWidget;
            currentEditType = "QPlainTextEdit";
            this->setVisible(true);
        } else if (nowWidget->inherits("QTextBrowser")) {
            currentBrowser = (QTextBrowser *)nowWidget;
            currentEditType = "QTextBrowser";
            this->setVisible(true);
        } else if (nowWidget->inherits("QComboBox")) {
            QComboBox *cbox = (QComboBox *)nowWidget;
            //只有当下拉选择框处于编辑模式才可以输入
            if (cbox->isEditable()) {
                currentLineEdit = cbox->lineEdit() ;
                currentEditType = "QLineEdit";
                this->setVisible(true);
            }
        } else if (nowWidget->inherits("QSpinBox") ||
                   nowWidget->inherits("QDoubleSpinBox") ||
                   nowWidget->inherits("QDateEdit") ||
                   nowWidget->inherits("QTimeEdit") ||
                   nowWidget->inherits("QDateTimeEdit")) {
            currentWidget = nowWidget;
            currentEditType = "QWidget";
            this->setVisible(true);
        } else {
            //需要将输入法切换到最初的原始状态--小写,同时将之前的对象指针置为零
            currentWidget = 0;
            currentLineEdit = 0;
            currentTextEdit = 0;
            currentPlain = 0;
            currentBrowser = 0;
            currentEditType = "";
            currentType = "min";
            changeType(currentType);
            this->setVisible(false);
        }

        //根据用户选择的输入法位置设置-居中显示-底部填充-显示在输入框正下方
        if (currentPosition == "center") {
            QPoint pos = QPoint(deskWidth / 2 - frmWidth / 2, deskHeight / 2 - frmHeight / 2);
            this->setGeometry(pos.x(), pos.y(), frmWidth, frmHeight);
        } else if (currentPosition == "bottom") {
            this->setGeometry(0, deskHeight - frmHeight, deskWidth, frmHeight);
        } else if (currentPosition == "control") {
            QRect rect = nowWidget->rect();
            QPoint pos = QPoint(rect.left(), rect.bottom() + 2);
            pos = nowWidget->mapToGlobal(pos);
            this->setGeometry(pos.x(), pos.y(), frmWidth, frmHeight);
        }
    }
}


#修改的
   def focusChanged(self,oldWidget,nowWidget):
      
   
      
      if (nowWidget != 0 & self.isAncestorOf(nowWidget)==False):
      

         
        #在Qt5和linux系统中(嵌入式linux除外),当输入法面板关闭时,焦点会变成无,然后焦点会再次移到焦点控件处
        #这样导致输入法面板的关闭按钮不起作用,关闭后马上有控件获取焦点又显示.
        #为此,增加判断,当焦点是从有对象转为无对象再转为有对象时不要显示.
        #这里又要多一个判断,万一首个窗体的第一个焦点就是落在可输入的对象中,则要过滤掉
#ifndef __arm__
         if (oldWidget == 0x0 & self.isFirst==False):
            return
        
#endif

         self.isFirst = False
         if (nowWidget.inherits("QLineEdit")):
            self.currentLineEdit = QLineEdit(nowWidget)
            self.currentEditType = "QLineEdit"
            self.setVisible(True);
         elif (nowWidget.inherits("QTextEdit")):
            self.currentTextEdit = QTextEdit(nowWidget)
            self.currentEditType = "QTextEdit"
            self.setVisible(True)
         elif (nowWidget.inherits("QPlainTextEdit")):
            self.currentPlain = QPlainTextEdit(nowWidget)
            self.currentEditType = "QPlainTextEdit"
            self.setVisible(True)
         elif (nowWidget.inherits("QTextBrowser")):
            self.currentBrowser = QTextBrowser(nowWidget)
            self.currentEditType = "QTextBrowser"
            self.setVisible(True)
         elif (nowWidget.inherits("QComboBox")):
            cbox = QComboBox(nowWidget)
            #只有当下拉选择框处于编辑模式才可以输入
            if (cbox.isEditable()):
               self.currentLineEdit = cbox.lineEdit()
               self.currentEditType = "QLineEdit"
               self.setVisible(True)
            
         elif (nowWidget.inherits("QSpinBox") |
                   nowWidget.inherits("QDoubleSpinBox") |
                   nowWidget.inherits("QDateEdit") |
                   nowWidget.inherits("QTimeEdit") |
                   nowWidget.inherits("QDateTimeEdit")):
            self.currentWidget = nowWidget
            self.currentEditType = "QWidget"
            self.setVisible(True)
         else:
            #需要将输入法切换到最初的原始状态--小写,同时将之前的对象指针置为零
            self.currentWidget = 0
            self.currentLineEdit = 0
            self.currentTextEdit = 0
            self.currentPlain = 0
            self.currentBrowser = 0
            self.currentEditType = ""
            self.currentType = "min"
            self.changeType(self.currentType)
            self.setVisible(False)
        

        #根据用户选择的输入法位置设置-居中显示-底部填充-显示在输入框正下方
         if (self.currentPosition == "center"):
            pos = QPoint(deskWidth / 2 - frmWidth / 2, deskHeight / 2 - frmHeight / 2)
            self.setGeometry(pos.x(), pos.y(), frmWidth, frmHeight)
         elif (self.currentPosition == "bottom"):
            self.setGeometry(0, deskHeight - frmHeight, deskWidth, frmHeight)
         elif (self.currentPosition == "control"):
            rect = nowWidget.rect()
            pos = QPoint(rect.left(), rect.bottom() + 2)
            pos = nowWidget.mapToGlobal(pos)
            self.setGeometry(pos.x(), pos.y(), frmWidth, frmHeight)


panghuhu250 2015-06-24
  • 打赏
  • 举报
回复
2. 假设你说的是这段代码:

bool FilterObject::eventFilter(QObject *object, QEvent *event)
{
    if (object == target && event->type() == QEvent::KeyPress) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
        if (keyEvent->key() == Qt::Key_Tab) {
            // Special tab handling
            return true;
        } else
            return false;
    }
    return false;
}
上面第三行的"if (object == target && event->type() == QEvent::KeyPress)"就保证了event是一个QKeyEvent, event.key()应该没问题. 3. isAncestorOf是QWidget的一个方法, 每个widget的子类都继承了这个方法. inherits是QObject中定义的方法, 更是每个QT中的对象都有的.

In [84]: win1 = QMainWindow()

In [85]: win1.isAncestorOf?
Docstring: QWidget.isAncestorOf(QWidget) -> bool
Type:      builtin_function_or_method

In [86]: pb = QPushButton(win1)

In [87]: pb.isAncestorOf?
Docstring: QWidget.isAncestorOf(QWidget) -> bool
Type:      builtin_function_or_method

In [88]: pb.inherits(QWidget)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-88-17f2b78798b1> in <module>()
----> 1 pb.inherits(QWidget)

TypeError: QObject.inherits(str): argument 1 has unexpected type 'PyQt4.QtCore.pyqtWrapperType'

In [89]: pb.inherits("QWidget")
Out[89]: True

In [90]: pb.inherits("QList")
Out[90]: False

In [91]: win1.isAncestorOf(pb)
Out[91]: True

In [92]: pb.isAncestorOf(win1)
Out[92]: False
csdnbuku 2015-06-24
  • 打赏
  • 举报
回复
引用 6 楼 panghuhu250 的回复:
[quote=引用 5 楼 csdnbuku 的回复:] 第三个问题,我之前说的代码有什么不妥的地方吗? 看你提供的代码也没有发觉。
我的回答是针对3楼最后的"pyqt中没有isAncestorOf 和inherits这两种用法,不知道该怎么改". 如果不是这个问题, 那么你的问题是什么?[/quote] 这个。pyqt报错了。要想让它不报错怎么搞。
panghuhu250 2015-06-24
  • 打赏
  • 举报
回复
引用 5 楼 csdnbuku 的回复:
第三个问题,我之前说的代码有什么不妥的地方吗? 看你提供的代码也没有发觉。
我的回答是针对3楼最后的"pyqt中没有isAncestorOf 和inherits这两种用法,不知道该怎么改". 如果不是这个问题, 那么你的问题是什么?
csdnbuku 2015-06-23
  • 打赏
  • 举报
回复
引用 1 楼 csdnbuku 的回复:
CSDN实在不好用。发个问题 界面居然这么卡顿,打了半天。 还有,python那个代码格式都给我弄乱了。
谢谢。根据你的代码。1、3已成功。 2还是不行。报错:AttributeError: 'QEvent' object has no attribute 'key' 这是个很常用的功能。不知道为什么pyqt资料这么少,不知道该怎么改。 对于3中的代码。还有点问题:

QObject.connect(qApp, SIGNAL("focusChanged(QWidget *, QWidget *)"), self.focusChanged)


   def focusChanged(self,oldWidget,nowWidget):
      
   
      
      if (nowWidget != 0 & self.isAncestorOf(nowWidget)==False):
         self.isFirst = False
         if (nowWidget.inherits("QLineEdit")):
            self.currentLineEdit = QLineEdit(nowWidget)
            self.currentEditType = "QLineEdit"
            self.setVisible(True);
…………

pyqt中没有isAncestorOf 和inherits这两种用法,不知道该怎么改。
panghuhu250 2015-06-23
  • 打赏
  • 举报
回复
1. 既然

self.ui.btna.clicked.connect(self.btn_clicked)
可以, 在循环中为什么不用相同的结构:

        for b in btn:           
           b.clicked.connect(self.btn_clicked)
2. python没有type, 只有"duck typing".
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
的作用是声明"event实际上是QKeyEvent, 把它当QKeyEvent用". 在python中不用这个, 如果event是QKeyEvent, 你直接把它当QKeyEvent用就是了.

if (event.key() == Qt::Key_Space) {
        }
3. http://stackoverflow.com/questions/7377397/pyqt-window-focus-events-not-called:

QObject.connect(app, SIGNAL("focusChanged(QWidget *, QWidget *)"), changedFocusSlot)
1, 2没有完整代码,纯属猜测. 3的代码试过了.
csdnbuku 2015-06-22
  • 打赏
  • 举报
回复
CSDN实在不好用。发个问题 界面居然这么卡顿,打了半天。 还有,python那个代码格式都给我弄乱了。

37,720

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧