如何修复我 on_foo_bar 槽存在错误的问题

huangapple go评论92阅读模式
英文:

How may I fix my error prone on_foo_bar slots

问题

我有八个列表小部件在一个选项卡小部件中。它们有类似的名称,而设计师的“转到槽”机制已经创建了链接到它们名称的槽函数(在“mainwindow.h”的“私有槽”部分)如下:

void on_SR0listWidget_itemClicked(QListWidgetItem *item);

我看到了警告:“命名为on_foo_bar的槽函数容易出错”,现在我需要更改它们的名称以查明是否这是导致我遇到奇怪行为的原因。我尝试简单地重构这些名称,但这使得槽函数不起作用。我使用了设计师的图形“编辑信号/槽”机制,并成功将新添加的列表小部件的“itemClicked(QListWidgetItem *item)”信号连接到新添加的槽函数,图形表示看起来没问题,但当点击项目时,槽函数中设置的调试消息没有输出。

我还使用了这些小部件的“entered”信号,因此至少有16个需要修复。如果可以通过解析相关文件来完成此任务,我将编写一个脚本。

关于如何重命名一个替代槽函数并将“项目点击”或“进入”信号连接到它的确切示例(以及它应该放在哪里)将会非常有帮助。

英文:

I have eight list widgets in a tab widget. They have similar names, and Designer's "Go to slot" mechanism has made links to slots it names (in the "private slots" section of "mainwindow.h") like:

void on_SR0listWidget_itemClicked(QListWidgetItem *item);

I saw warnings that "Slots named on_foo_bar are error-prone," and now I need to change their names in order to discover if that's the cause of the weird behaviour I'm getting.
I tried simply refactoring the names, but that stopped the slot code from working. I used Designer's graphical "Edit Signal/Slot" mechanism and was able to connect a newly added list widget's "itemClicked(QListWidgetItem *item)" signal to a newly added slot, and it looks OK in the graphical representation, but there's no debug message (that I set up in the Slot function) when an item is clicked.
I also use those widgets' "entered" signals, so there will be at least 16 to fix. I would write a script if it could be done by parsing the relevant files.

One example of exactly how to rename one of my replacement slots and connect an "item clicked" or "entered" signal to it (and where it should go) would be a great help.

答案1

得分: 2

通过设计师设置的信号/槽依赖于涉及的小部件的名称。如果更改小部件的名称,这可能会导致问题。有时使用设计师方法会导致编译通过但实际上不会创建您期望的连接。这就是为什么会出现该警告。

通过在代码中以编程方式连接信号和槽,您可以获得更可靠的行为。例如,假设您有一个类头文件如下:

#include <QMainWindow>;

namespace Ui {
class MyWindow;
};

class QListWidgetItem;

class MyWindow : public QMainWindow {
   Q_OBJECT
public:
   explicit MyWindow(QWidget* parent = nullptr);
   ~MyWindow() override;

private:
   void handleItemClicked(QListWidgetItem* item); // 这是您的槽

   Ui::MyWindow* ui;
};

您可以在 cpp 文件中像这样连接信号/槽:

#include "MyWindow.h"
#include "ui_MyWindow.h"

#include <QDebug>

MyWindow::MyWindow(QWidget* parent)
   : QWidget(parent),
     ui(new Ui::MyWindow()) {
   ui->setupUi(this);

   // connect() 有多种重载,但在这种情况下,我们传递了:
   // 1. 发出信号的对象
   // 2. 正在发出的信号
   // 3. 要调用的槽的对象
   // 4. 要连接到的槽
   connect(
      ui->listWidget, &QListWidget::itemClicked,
      this, &MyWindow::handleItemClicked);
}

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

void MyWindow::handleItemClicked(QListWidgetItem* item) {
   qDebug() << "item clicked";
}

您仍然可以使用设计师来布局您的用户界面,但最好在代码中直接管理连接,而不是通过设计师。

英文:

Signals/slots setup through the designer rely on the names of the widgets involved. This can lead to problems if the widget names are changed. There are times when using the designer method will lead to code that compiles but doesn't actually make the connections you expect. This is why you are getting that warning.

You can get more reliable behavior by connecting the signals and slots programmatically. For example, let's say you have a class header such as:

#include &lt;QMainWindow&gt;

namespace Ui {
class MyWindow;
};

class QListWidgetItem;

class MyWindow : public QMainWindow {
   Q_OBJECT
public:
   explicit MyWindow(QWidget* parent = nullptr);
   ~MyWindow() override;

private:
   void handleItemClicked(QListWidgetItem* item); // this is your slot

   Ui::MyWindow* ui;
};

You can connect the signal/slot together in the cpp file like this:

#include &quot;MyWindow.h&quot;
#include &quot;ui_MyWindow.h&quot;

#include &lt;QDebug&gt;

MyWindow::MyWindow(QWidget* parent)
   : QWidget(parent),
     ui(new Ui::MyWindow()) {
   ui-&gt;setupUi(this);

   // connect() has many overloads, but in this case we are passing:
   // 1. the object emitting the signal
   // 2. the signal being emitted
   // 3. the object whose slot we want to call
   // 4. the slot to connect to
   connect(
      ui-&gt;listWidget, &amp;QListWidget::itemClicked,
      this, &amp;MyWindow::handleItemClicked);
}

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

void MyWindow::handleItemClicked(QListWidgetItem* item) {
   qDebug() &lt;&lt; &quot;item clicked&quot;;
}

You can still use the designer to layout your UI - but prefer to manage connections directly in code rather than through the designer.

huangapple
  • 本文由 发表于 2023年2月8日 18:59:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/75384792.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定