I am trying to pass a string (which holds the file name to an image) to a class constructor.
// pushbutton function call to open new window
void SelectTest::on_upperSideStart_clicked()
{
QString imageFile = ui->upperSideEdit->text();
uppersidewindow = new upperSideWindow(imageFile, this);
uppersidewindow->show();
}
// new class constructor
upperSideWindow::upperSideWindow(const QString &_imageFile, QWidget *parent) :
QMainWindow(parent),
ui(new Ui::upperSideWindow)
{
ui->setupUi(this);
*image = QImage(_imageFile);
qDebug() << image->size();
}
From the debugger:
(before constructor call) imageFile =
"C:/Users/User/Documents/SpineAnalysis/Patient Name/UpperSide.JPG"
(after constructor call) imageFile =
"\001І뒴\001І뒯\001儇楌"
Why does this happen?
This appears to be a debugger issue. Using:
qDebug() << "image file: " << _imageFile
I can see that the string is still in tact.
Related
class Label : public QLabel
{
Q_OBJECT
public:
QString str;
Label(QWidget* parent, QString text) : QLabel(parent)
{
this->str = text;
}
void paintEvent(QPaintEvent* p)
{
QLabel::paintEvent(p);
QPainter paint(this);
QPixmap pixmap;
pixmap.load(":/pic.png");
paint.drawPixmap(QRect(0, 0, 32, 32), pixmap);
qDebug() << "str: " << str;
paint.drawText(QPoint(10, 10), "Hello World");
}
};
Main::Main(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
QLabel* label = new Label(ui.pushButton, "test");
label.str = "hello world"; // <-- error: expression must have a class type
}
How to update the value of str from QLabel* label?
I tried: label.str = "hello world"; but I got the error: expression must have a class type.
Does subclassing controls increases the app CPU usage?
Each time the paintEvent(QPaintEvent* p) function is called it creates a new pixmap and repaint the control? or the pixmap is created only once and kept on memory and then 'reused'?
There's is any 'best practices' when subclassing buttons? or is it desirable to avoid subclassing?
I want to display my image in a new window . So i am trying to pass the path of the image as value through constructor
void DicomWidget::mouseDoubleClickEvent(QMouseEvent *event){
qDebug() << ui->diWidget->whatsThis();
QString path = ui->diWidget->whatsThis();
EditWindow * editWindow = new EditWindow(this);
editWindow->setWindowTitle(path);
editWindow->setWhatsThis(path);
editWindow->show();
}
I want to pass the path in constructor but if I do the UI of the editwindow is not rendering
my editwindow.cpp
#include "editwindow.h"
#include "ui_editwindow.h"
EditWindow::EditWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::EditWindow)
{
ui->setupUi(this);
}
EditWindow::~EditWindow()
{
delete ui;
}
//Here i need to have refernce to this how shoul i give it
EditWindow::EditWindow(QString& filepath){
QFile file (filepath);
QFileInfo fileInfo(file.fileName());
QString filename(fileInfo.fileName());
QString name = filename;
currentDicomPath = filepath;
}
void EditWindow::on_pushButton_clicked()
{
currentDicomPath = EditWindow::windowTitle();
qDebug() <<"Hello9" << currentDicomPath;
}
By rewriting the constructor with EditWindow::EditWindow(QString& filepath) the Qt constructor with EditWindow::EditWindow(QWidget *parent) won't run, and thus you can't see any rendering.
Consider amending the existing constructor with something like EditWindow::EditWindow(QWidget *parent, QString& filepath) and add your custom code below ui->setup(this);
After that, you are able to initiate your class with EditWindow* editWindow = new EditWindow(this, filepath);
Otherwise, you just created an overload of the existing constructor.
In my MainWindow i have a combobox and a select button. When the select button is clicked a new window is opened.
I want to be able to create a QString variable on the MainWindow that contains the text from the combobox, and pass that QString to the new window. The new window is going to perform different tasks, based on the contents of the QString (based on the selection of the combobox).
The following is my code so far...
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "testwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->cmboTestSelect->addItem("{Please Select a Test}");
ui->cmboTestSelect->addItem("Test 1");
ui->cmboTestSelect->addItem("Test 2");
ui->cmboTestSelect->addItem("Test 3");
ui->cmboTestSelect->addItem("Test 4");
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btnTestSelect_clicked()
{
QString str_TestSelect = ui->cmboTestSelect->currentText(); //stores "Test Name" in string
hide();
Testwindow = new testwindow(this);
Testwindow->show();
}
The simplest way to do this is, as suggested in the comments, to pass the variable as parameter in the constructor of the class Testwindow. Then you can save the value of the string in a private variable in your Testwindow class and do whatever you want with it.
testwindow.h
class Testwindow : public QMainWindow
{
Q_OBJECT
public:
explicit Testwindow(QString text, QWidget *parent = nullptr);
signals:
private:
QString comboBoxText;
};
testwindow.cpp
Testwindow::Testwindow(QString text, QWidget *parent) : QMainWindow(parent)
{
comboBoxText = text; //now you can use comboBoxText in the rest of Testwindow class
}
mainwindow.cpp
void MainWindow::on_btnTestSelect_clicked()
{
QString str_TestSelect = ui->cmboTestSelect->currentText(); //stores "Test Name" in string
hide();
Testwindow *w = new Testwindow(str_TestSelect, this);
w->show();
}
I tried maybe everything but I just don't see a mistake in this code. I made two windows inherited from QMainWindow: one with qt designer and another just in constructor. I'm trying to switch these windows in the MainWindow class depending on what buttons you press.
LoginWindow.cpp
LoginWindow::LoginWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::LoginWindow) {
ui->setupUi(this);
}
LoginWindow::~LoginWindow() {
delete ui;
}
void LoginWindow::on_confirmButton_clicked() {
emit confirmButton_clicked();
}
RegistrationWindow.hpp
RegistrationWindow::RegistrationWindow(QWidget* parent): QMainWindow(parent) {
label = new QLabel("Fast Typing"); //variable in .hpp
label->setAlignment(Qt::AlignCenter);
label->setFont(QFont("Lucida Console", 12, 2));
QVBoxLayout * l = new QVBoxLayout();
l->addWidget(label);
l->addWidget(new QLabel("Login", this));
l->addWidget(new QLineEdit(this));
l->addWidget(new QLabel("Password", this));
l->addWidget(new QLineEdit(this));
p = new QPushButton("Confirm", this); //variable in .hpp
l->addWidget(p);
w = new QWidget(); //variable in .hpp
w->setLayout(l);
setCentralWidget(w);
connect(p, &QPushButton::clicked, this, &RegistrationWindow::on_confirmButton_clicked);
}
void RegistrationWindow::on_confirmButton_clicked() {
emit confirmButton_clicked();
}
RegistrationWindow::~RegistrationWindow() { }
MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
//variables in .hpp
logWindow = new LoginWindow();
regWindow = new RegistrationWindow();
goToReg();
connect(logWindow, SIGNAL(confirmButton_clicked()), this, SLOT(goToReg()));
connect(regWindow, SIGNAL(confirmButton_clicked()), this, SLOT(goToLog()));
}
void MainWindow::goToReg() {
qDebug() << "goToReg";
resize(regWindow->size());
qDebug() << "goToReg";
setCentralWidget(regWindow);
setWindowTitle("Registration");
qDebug() << "registration: " << regWindow;
qDebug() << "login: " << logWindow;
}
void MainWindow::goToLog() {
qDebug() << "goToLog";
resize(logWindow->size());
qDebug() << "goToLog";
setCentralWidget(logWindow);
setWindowTitle("Login");
qDebug() << "registration: " << regWindow;
qDebug() << "login: " << logWindow;
}
All I could say is it switches windows no matter what I make a starting window and for second time it's crashes on the line setCentralWidget() in slot with SEGV runtime error.
From the documentation of QMainWindow::setCentralWidget:
Note: QMainWindow takes ownership of the widget pointer and deletes it at the appropriate time.
The widgets that logWindow and regWindow point to start life unowned. Then you call goToReg(), which calls setCentralWidget(regWindow) - now the main window owns *regWindow. Then you call goToLog(), which calls setCentralWidget(logWindow) - now the main window takes ownership of *logWindow and destroys *regWindow, so regWindow becomes a dangling pointer. Next time you attempt to use it, the program exhibits undefined behavior.
I am writing a gui in QT for controlling usb relays. I wrote a relay class which has turn on/off member functions. also wrote a custom widget which has radio buttons for controlling, a relay pointer, as well as a switchStatus() slot in which the relay turn on/off functions were called. The mainwindow has relay members. When I call the the ui->widget->switchStatus() from the mainwindow constructor, everything works fine, the relay can be turn on and off well. However, if I connect the radio button signal to switchStatus(), the program crashes whenever I click the radio button. It crashes at the line serialPort->write. But it's not about write, whatever code related to serialPort pointer it first come to will cause crash. even I want to get the port name or port address.
myWidget::myWidget(QWidget *parent) : QWidget(parent), m_ui(new Ui::Form)
{ status = 0;
m_ui->setupUi(this);
m_ui->statusIndicator->status = &status; // status in ui pointing to null before this
m_ui->turnOffButton->setChecked(true);
connect(m_ui->turnOnButton, SIGNAL(clicked(bool)), this, SLOT(switchStatus()));
//crashes when click ratioButton,
//compare to last line in the mainwindow construtor
connect(m_ui->turnOffButton, SIGNAL(clicked(bool)), this, SLOT(switchStatus()));
}
void myWidget::switchStatus()
{
qDebug() << "swithcing";
if(status)
{
setStatus(false);
}
else
{
setStatus(true);
}
m_relay->switchStatus();
}
void relay::switchStatus()
{ if(status) turnOff();
else turnOn();
}
bool relay::turnOn(){
qDebug() << writeDataOn; // test if string is correct
qDebug() << serialPort; // crashes whenever serialPort address is called
const qint64 bytesWritten = serialPort->write(writeDataOn);
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
QList<QSerialPortInfo> infos = QSerialPortInfo::availablePorts();
qDebug() << infos[0].description();
QSerialPort serialPort;
serialPort.setPortName(infos[0].portName());
serialPort.setBaudRate(QSerialPort::Baud9600);
if (!serialPort.open(QIODevice::ReadWrite)) {
qDebug() << QObject::tr("Failed to open port %1, error: %2").arg(serialPort.portName()).arg(serialPort.error()) ;
}
ui->setupUi(this);
for(int i=0;i<4;i++)
{
relays[i].setRelayNumber(i);
relays[i].setPort(&serialPort);
relays[i].setStatus(relays[i].getRealStatus());
}
ui->widget->m_relay = relays;
qDebug() << ui->widget->m_relay;
qDebug() << ui->widget->m_relay->getPort();
ui->widget->switchStatus(); // this line runs well
}
Make your serial port a member of the MainWindow class. At the moment it is local to your constructor, so it is deallocated when the constructor finishes, hence the crashing. If you have declared a 'serialPort' member, you are hiding it by redeclaring it as a local scope variable inside the constructor.